use of org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityResponse in project entity-service by hypertrace.
the class EntityDataServiceImpl method mergeAndUpsertEntity.
@Override
public void mergeAndUpsertEntity(MergeAndUpsertEntityRequest request, StreamObserver<MergeAndUpsertEntityResponse> responseObserver) {
RequestContext requestContext = RequestContext.CURRENT.get();
String tenantId = requestContext.getTenantId().orElse(null);
if (tenantId == null) {
responseObserver.onError(new ServiceException("Tenant id is missing in the request."));
return;
}
Entity receivedEntity = this.entityNormalizer.normalize(tenantId, request.getEntity());
Optional<Entity> existingEntity = getExistingEntity(tenantId, receivedEntity.getEntityType(), receivedEntity.getEntityId());
boolean rejectUpsertForConditionMismatch = existingEntity.map(entity -> !this.upsertConditionMatcher.matches(entity, request.getUpsertCondition())).orElse(false);
if (rejectUpsertForConditionMismatch) {
// There's an existing entity and the update doesn't meet the condition, return existing
responseObserver.onNext(MergeAndUpsertEntityResponse.newBuilder().setEntity(existingEntity.get()).build());
responseObserver.onCompleted();
} else {
// There's either a new entity or a valid update to upsert
Entity entityToUpsert = existingEntity.map(Entity::toBuilder).map(Entity.Builder::clearCreatedTime).map(builder -> builder.mergeFrom(receivedEntity)).map(Builder::build).orElse(receivedEntity);
try {
Entity upsertedEntity = this.upsertEntity(tenantId, entityToUpsert);
responseObserver.onNext(MergeAndUpsertEntityResponse.newBuilder().setEntity(upsertedEntity).build());
responseObserver.onCompleted();
entityChangeEventGenerator.sendChangeNotification(requestContext, existingEntity.map(List::of).orElse(Collections.emptyList()), List.of(upsertedEntity));
} catch (IOException e) {
responseObserver.onError(e);
}
}
}
use of org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityResponse in project entity-service by hypertrace.
the class EntityDataCachingClientTest method beforeEach.
@BeforeEach
void beforeEach() throws IOException {
String uniqueName = InProcessServerBuilder.generateName();
this.grpcServer = InProcessServerBuilder.forName(uniqueName).directExecutor().addService(this.mockDataService).build().start();
this.grpcChannel = InProcessChannelBuilder.forName(uniqueName).directExecutor().build();
this.dataClient = EntityDataClient.builder(this.grpcChannel).build();
this.possibleResponseEntities = List.of(this.defaultResponseEntity);
this.responseError = Optional.empty();
doAnswer(invocation -> {
StreamObserver<MergeAndUpsertEntityResponse> observer = invocation.getArgument(1, StreamObserver.class);
Entity inputEntity = invocation.getArgument(0, MergeAndUpsertEntityRequest.class).getEntity();
responseError.ifPresentOrElse(observer::onError, () -> {
observer.onNext(MergeAndUpsertEntityResponse.newBuilder().setEntity(this.possibleResponseEntities.stream().filter(entity -> entity.getEntityId().equals(inputEntity.getEntityId())).findFirst().orElse(inputEntity)).build());
observer.onCompleted();
});
return null;
}).when(this.mockDataService).mergeAndUpsertEntity(any(), any());
this.testScheduler = new TestScheduler();
RxJavaPlugins.setComputationSchedulerHandler(ignored -> testScheduler);
}
Aggregations