diff --git a/hypertrace-trace-enricher/trace-reader/src/main/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReader.java b/hypertrace-trace-enricher/trace-reader/src/main/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReader.java index d79aae0f7..6ff3b704a 100644 --- a/hypertrace-trace-enricher/trace-reader/src/main/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReader.java +++ b/hypertrace-trace-enricher/trace-reader/src/main/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReader.java @@ -1,6 +1,7 @@ package org.hypertrace.trace.reader.entities; import static io.reactivex.rxjava3.core.Maybe.zip; +import static java.util.function.Predicate.not; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.Single; @@ -132,10 +133,12 @@ private Maybe buildEntity(EntityType entityType, T trace, S span) { this.resolveAllAttributes(entityType.getAttributeScope(), trace, span).cache(); Maybe id = - attributes.mapOptional(map -> this.extractString(map, entityType.getIdAttributeKey())); + attributes.mapOptional( + map -> this.extractNonEmptyString(map, entityType.getIdAttributeKey())); Maybe name = - attributes.mapOptional(map -> this.extractString(map, entityType.getNameAttributeKey())); + attributes.mapOptional( + map -> this.extractNonEmptyString(map, entityType.getNameAttributeKey())); return zip( id, @@ -187,13 +190,14 @@ private Maybe> resolveAttribute( .map(value -> Map.entry(attributeMetadata.getKey(), value)); } - private Optional extractString( + private Optional extractNonEmptyString( Map attributeValueMap, String key) { return Optional.ofNullable(attributeValueMap.get(key)) .filter(value -> value.getTypeCase().equals(TypeCase.VALUE)) .map(AttributeValue::getValue) .filter(value -> value.getTypeCase().equals(Value.TypeCase.STRING)) - .map(Value::getString); + .map(Value::getString) + .filter(not(String::isEmpty)); } private GrpcRxExecutionContext spanTenantContext(S span) { diff --git a/hypertrace-trace-enricher/trace-reader/src/test/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReaderTest.java b/hypertrace-trace-enricher/trace-reader/src/test/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReaderTest.java index 04b2151a1..4104397fd 100644 --- a/hypertrace-trace-enricher/trace-reader/src/test/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReaderTest.java +++ b/hypertrace-trace-enricher/trace-reader/src/test/java/org/hypertrace/trace/reader/entities/DefaultTraceEntityReaderTest.java @@ -156,6 +156,23 @@ void omitsEntityBasedOnMissingAttributes() { .getAssociatedEntityForSpan(TEST_ENTITY_TYPE_NAME, TEST_TRACE, TEST_SPAN) .isEmpty() .blockingGet()); + verifyNoInteractions(mockDataClient); + } + + @Test + void omitsEntityBasedOnEmptyId() { + mockSingleEntityType(); + mockGetAllAttributes(TEST_ENTITY_ID_ATTRIBUTE, TEST_ENTITY_NAME_ATTRIBUTE); + mockTenantId(); + mockAttributeRead(TEST_ENTITY_ID_ATTRIBUTE, stringLiteral("")); + mockAttributeRead(TEST_ENTITY_NAME_ATTRIBUTE, stringLiteral(TEST_ENTITY_NAME_ATTRIBUTE_VALUE)); + + assertTrue( + this.entityReader + .getAssociatedEntityForSpan(TEST_ENTITY_TYPE_NAME, TEST_TRACE, TEST_SPAN) + .isEmpty() + .blockingGet()); + verifyNoInteractions(mockDataClient); } @Test