use of org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition in project hypertrace-ingester by hypertrace.
the class DefaultTraceEntityAccessorTest method includesUpsertConditionIfTimestampAttributeDefined.
@Test
void includesUpsertConditionIfTimestampAttributeDefined() {
mockAllEntityTypes(TEST_ENTITY_TYPE.toBuilder().setTimestampAttributeKey(TEST_ENTITY_TIMESTAMP_ATTRIBUTE_KEY).build());
mockGetAllAttributes(TEST_ENTITY_ID_ATTRIBUTE, TEST_ENTITY_NAME_ATTRIBUTE, TEST_ENTITY_TIMESTAMP_ATTRIBUTE);
mockGetSingleAttribute(TEST_ENTITY_TIMESTAMP_ATTRIBUTE);
mockTenantId();
mockAttributeRead(TEST_ENTITY_ID_ATTRIBUTE, stringLiteral(TEST_ENTITY_ID_ATTRIBUTE_VALUE));
mockAttributeRead(TEST_ENTITY_NAME_ATTRIBUTE, stringLiteral(TEST_ENTITY_NAME_ATTRIBUTE_VALUE));
mockAttributeRead(TEST_ENTITY_TIMESTAMP_ATTRIBUTE, longLiteral(30));
this.entityAccessor.writeAssociatedEntitiesForSpanEventually(TEST_TRACE, TEST_SPAN);
UpsertCondition expectedCondition = UpsertCondition.newBuilder().setPropertyPredicate(Predicate.newBuilder().setAttributeKey(TEST_ENTITY_TIMESTAMP_ATTRIBUTE_KEY).setOperator(PredicateOperator.PREDICATE_OPERATOR_LESS_THAN).setValue(longAttributeValue(30)).build()).build();
verify(mockDataClient, times(1)).createOrUpdateEntityEventually(argThat(MATCHING_TENANT_REQUEST_CONTEXT), eq(EXPECTED_ENTITY.toBuilder().putAttributes(TEST_ENTITY_TIMESTAMP_ATTRIBUTE_KEY, longAttributeValue(30)).build()), eq(expectedCondition), eq(DEFAULT_DURATION));
}
use of org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition in project entity-service by hypertrace.
the class EntityDataServiceTest method testUpdateEntityWithPredicateViaUpsertAndMerge.
@Test
public void testUpdateEntityWithPredicateViaUpsertAndMerge() {
// Scope this test to its own tenant for isolation
String TENANT_ID = EntityDataServiceTest.TENANT_ID + "testUpdateEntityWithPredicateViaUpsertAndMerge";
EntityDataServiceBlockingStub entityDataServiceStub = buildStubForTenant(TENANT_ID);
setupEntityTypes(channel, TENANT_ID);
Map<String, AttributeValue> createAttributes = Map.of("some-attr", stringValue("v1"));
Map<String, AttributeValue> updateAttributes = Map.of("some-attr", stringValue("v2"));
// Expect create and the first update to succeed, the second to fail
UpsertCondition condition = UpsertCondition.newBuilder().setPropertyPredicate(Predicate.newBuilder().setAttributeKey("some-attr").setOperator(PredicateOperator.PREDICATE_OPERATOR_EQUALS).setValue(stringValue("v1"))).build();
// V1 entity
Entity entityToCreate = Entity.newBuilder().setTenantId(TENANT_ID).setEntityType(EntityType.K8S_POD.name()).setEntityName("V1 UPDATE PREDICATE POD").putIdentifyingAttributes(EntityConstants.getValue(CommonAttribute.COMMON_ATTRIBUTE_EXTERNAL_ID), generateRandomUUIDAttrValue()).putAllAttributes(createAttributes).build();
// Successful create
Entity createdEntity = entityDataServiceStub.mergeAndUpsertEntity(MergeAndUpsertEntityRequest.newBuilder().setEntity(entityToCreate).setUpsertCondition(condition).build()).getEntity();
assertEquals(stringValue("v1"), createdEntity.getAttributesMap().get("some-attr"));
Entity entityUpdate = entityToCreate.toBuilder().putAllAttributes(updateAttributes).build();
Entity updatedEntity = entityDataServiceStub.mergeAndUpsertEntity(MergeAndUpsertEntityRequest.newBuilder().setEntity(entityUpdate).setUpsertCondition(condition).build()).getEntity();
// Successful update
assertEquals(stringValue("v2"), updatedEntity.getAttributesMap().get("some-attr"));
Entity secondEntityUpdate = entityToCreate.toBuilder().putAttributes("some-new-attr", stringValue("foo")).build();
Entity secondUpdatedEntity = entityDataServiceStub.mergeAndUpsertEntity(MergeAndUpsertEntityRequest.newBuilder().setEntity(secondEntityUpdate).setUpsertCondition(condition).build()).getEntity();
// No change, update rejected
assertFalse(secondUpdatedEntity.getAttributesMap().containsKey("some-new-attr"));
assertEquals(stringValue("v2"), secondUpdatedEntity.getAttributesMap().get("some-attr"));
// V2 Entity
entityToCreate = Entity.newBuilder().setTenantId(TENANT_ID).setEntityId(UUID.randomUUID().toString()).setEntityType(TEST_ENTITY_TYPE_V2).setEntityName("V2 entity predicate update").putAllAttributes(createAttributes).build();
// Successful create
createdEntity = entityDataServiceStub.mergeAndUpsertEntity(MergeAndUpsertEntityRequest.newBuilder().setEntity(entityToCreate).setUpsertCondition(condition).build()).getEntity();
assertEquals(stringValue("v1"), createdEntity.getAttributesMap().get("some-attr"));
entityUpdate = entityToCreate.toBuilder().putAllAttributes(updateAttributes).build();
updatedEntity = entityDataServiceStub.mergeAndUpsertEntity(MergeAndUpsertEntityRequest.newBuilder().setEntity(entityUpdate).setUpsertCondition(condition).build()).getEntity();
// Successful update
assertEquals(stringValue("v2"), updatedEntity.getAttributesMap().get("some-attr"));
secondEntityUpdate = entityToCreate.toBuilder().putAttributes("some-new-attr", stringValue("foo")).build();
secondUpdatedEntity = entityDataServiceStub.mergeAndUpsertEntity(MergeAndUpsertEntityRequest.newBuilder().setEntity(secondEntityUpdate).setUpsertCondition(condition).build()).getEntity();
// No change, update rejected
assertFalse(secondUpdatedEntity.getAttributesMap().containsKey("some-new-attr"));
assertEquals(stringValue("v2"), secondUpdatedEntity.getAttributesMap().get("some-attr"));
}
use of org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition in project hypertrace-ingester by hypertrace.
the class DefaultTraceEntityAccessor method writeEntityIfExists.
private void writeEntityIfExists(EntityType entityType, StructuredTrace trace, Event span) {
this.buildEntity(entityType, trace, span).subscribeOn(Schedulers.io()).subscribe(entity -> {
UpsertCondition upsertCondition = this.buildUpsertCondition(entityType, trace, span).defaultIfEmpty(UpsertCondition.getDefaultInstance()).blockingGet();
this.entityDataClient.createOrUpdateEntityEventually(RequestContext.forTenantId(this.traceAttributeReader.getTenantId(span)), entity, upsertCondition, this.writeThrottleDuration);
});
}
use of org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition in project entity-service by hypertrace.
the class EntityDataCachingClient method createOrUpdateEntityEventually.
@Override
public void createOrUpdateEntityEventually(RequestContext requestContext, Entity entity, UpsertCondition condition, Duration maximumUpsertDelay) {
EntityKey entityKey = new EntityKey(requestContext, entity);
// Don't allow other update processing until finished
Lock lock = this.pendingUpdateStripedLock.get(entityKey);
try {
lock.lock();
this.pendingEntityUpdates.computeIfAbsent(entityKey, unused -> new PendingEntityUpdate()).addNewUpdate(entityKey, condition, maximumUpsertDelay);
} finally {
lock.unlock();
}
}
Aggregations