Search in sources :

Example 1 with UpsertCondition

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));
}
Also used : UpsertCondition(org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition) Test(org.junit.jupiter.api.Test)

Example 2 with UpsertCondition

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"));
}
Also used : EnrichedEntity(org.hypertrace.entity.data.service.v1.EnrichedEntity) Entity(org.hypertrace.entity.data.service.v1.Entity) AttributeValue(org.hypertrace.entity.data.service.v1.AttributeValue) UpsertCondition(org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition) EntityDataServiceBlockingStub(org.hypertrace.entity.data.service.v1.EntityDataServiceGrpc.EntityDataServiceBlockingStub) Test(org.junit.jupiter.api.Test)

Example 3 with UpsertCondition

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);
    });
}
Also used : UpsertCondition(org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition)

Example 4 with UpsertCondition

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();
    }
}
Also used : CallCredentials(io.grpc.CallCredentials) RequestContext(org.hypertrace.core.grpcutils.context.RequestContext) Single(io.reactivex.rxjava3.core.Single) LoadingCache(com.google.common.cache.LoadingCache) Channel(io.grpc.Channel) ConcurrentMap(java.util.concurrent.ConcurrentMap) Functions(io.reactivex.rxjava3.internal.functions.Functions) Duration(java.time.Duration) Entity(org.hypertrace.entity.data.service.v1.Entity) Objects.isNull(java.util.Objects.isNull) Nonnull(javax.annotation.Nonnull) Striped(com.google.common.util.concurrent.Striped) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Completable(io.reactivex.rxjava3.core.Completable) UpsertCondition(org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition) Instant(java.time.Instant) CacheLoader(com.google.common.cache.CacheLoader) TimeUnit(java.util.concurrent.TimeUnit) EntityDataServiceStub(org.hypertrace.entity.data.service.v1.EntityDataServiceGrpc.EntityDataServiceStub) Lock(java.util.concurrent.locks.Lock) Slf4j(lombok.extern.slf4j.Slf4j) EntityDataServiceGrpc(org.hypertrace.entity.data.service.v1.EntityDataServiceGrpc) Disposable(io.reactivex.rxjava3.disposables.Disposable) MergeAndUpsertEntityRequest(org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest) Clock(java.time.Clock) Optional(java.util.Optional) MergeAndUpsertEntityResponse(org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityResponse) CacheBuilder(com.google.common.cache.CacheBuilder) Objects.nonNull(java.util.Objects.nonNull) Lock(java.util.concurrent.locks.Lock)

Aggregations

UpsertCondition (org.hypertrace.entity.data.service.v1.MergeAndUpsertEntityRequest.UpsertCondition)4 Entity (org.hypertrace.entity.data.service.v1.Entity)2 Test (org.junit.jupiter.api.Test)2 CacheBuilder (com.google.common.cache.CacheBuilder)1 CacheLoader (com.google.common.cache.CacheLoader)1 LoadingCache (com.google.common.cache.LoadingCache)1 Striped (com.google.common.util.concurrent.Striped)1 CallCredentials (io.grpc.CallCredentials)1 Channel (io.grpc.Channel)1 Completable (io.reactivex.rxjava3.core.Completable)1 Single (io.reactivex.rxjava3.core.Single)1 Disposable (io.reactivex.rxjava3.disposables.Disposable)1 Functions (io.reactivex.rxjava3.internal.functions.Functions)1 Clock (java.time.Clock)1 Duration (java.time.Duration)1 Instant (java.time.Instant)1 Objects.isNull (java.util.Objects.isNull)1 Objects.nonNull (java.util.Objects.nonNull)1 Optional (java.util.Optional)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1