From abfcb411d78d02f3a465b88bf8922417c4a3fa55 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Tue, 20 May 2025 17:09:36 -0700 Subject: [PATCH 1/6] initial EntityProvider prototype --- .../io/opentelemetry/sdk/entities/Entity.java | 25 +++ .../sdk/entities/EntityListener.java | 9 + .../sdk/entities/EntityProvider.java | 44 +++++ .../sdk/entities/SdkEntityProvider.java | 120 ++++++++++++ .../sdk/entities/SdkEntityProviderTest.java | 181 ++++++++++++++++++ .../sdk/trace/TracerSharedState.java | 1 + 6 files changed, 380 insertions(+) create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java create mode 100644 sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java new file mode 100644 index 00000000000..e9d91ebe051 --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java @@ -0,0 +1,25 @@ +package io.opentelemetry.sdk.entities; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.common.Attributes; +import javax.annotation.concurrent.Immutable; + +@Immutable +@AutoValue +abstract public class Entity { + + public static Entity create(String id, String name, Attributes attributes) { + return new AutoValue_Entity(id, name, attributes); + } + + public abstract String getId(); + + public abstract String getName(); + + public abstract Attributes getAttributes(); + + public Entity withAttributes(Attributes newAttributes) { + return new AutoValue_Entity(getId(), getName(), newAttributes); + } + +} diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java new file mode 100644 index 00000000000..a1f40d80147 --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java @@ -0,0 +1,9 @@ +package io.opentelemetry.sdk.entities; + +import io.opentelemetry.sdk.resources.Resource; + +public interface EntityListener { + + void onEntityState(Entity state, Resource resource); + void onEntityDelete(Entity state, Resource resource); +} diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java new file mode 100644 index 00000000000..622a5bcea94 --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java @@ -0,0 +1,44 @@ +package io.opentelemetry.sdk.entities; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.resources.Resource; + +public interface EntityProvider { + + /** + * Returns the current representation of the Resource, as materialized by the + * Entities contained herein. + */ + Resource getResource(); + + /** + * Adds a listener to the end of the list of EntityListeners. The listener + * will be notified when changes are made to the EntityProvider. + * @param listener - an EntityListener + */ + void addListener(EntityListener listener); + + /** + * Adds a new Entity to the EntityProvider. If an Entity with the same id already exists, + * it will be removed and a new instance will be inserted at the end of the list of + * entities. After the entity is added, the resource is rebuilt and the listeners are + * notified. + */ + void addEntity(String id, String name, Attributes attributes); + + /** + * Updates an existing Entity with the given id with new attributes. If an Entity + * with the given id does not exist, this is effective a no-op. This method does not + * change the order of ids, so the change is effectively made "in-place". After the + * Entity has been updated, the listeners will be notified. + */ + void updateEntity(String id, Attributes attributes); + + /** + * Deletes the Entity with the given id. If the Entity does not exist within + * this EntityProvider, then it is effectively a no-op. If the Entity is removed, + * the Resource will be rebuilt and listeners will then be notified. + */ + void deleteEntity(String id); + +} diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java new file mode 100644 index 00000000000..fb54b95af4e --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java @@ -0,0 +1,120 @@ +package io.opentelemetry.sdk.entities; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.internal.GuardedBy; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.resources.ResourceBuilder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +public class SdkEntityProvider implements EntityProvider { + + private final Object lock = new Object(); + private final AtomicReference resource = new AtomicReference<>(Resource.empty()); + @GuardedBy("lock") + private final LinkedHashMap entities = new LinkedHashMap<>(); + @GuardedBy("lock") + private final List listeners = new ArrayList<>(); + + public SdkEntityProvider() { + this(Collections.emptyList()); + } + + public SdkEntityProvider(List initialEntities) { + for (Entity entity : initialEntities) { + entities.put(entity.getId(), entity); + } + rebuildResource(); + } + + @Override + public Resource getResource() { + Resource result = resource.get(); + return result == null ? Resource.empty() : result; + } + + @Override + public void addListener(EntityListener listener) { + synchronized(lock){ + listeners.add(listener); + } + } + + @Override + public void addEntity(String id, String name, Attributes attributes) { + Entity entity = Entity.create(id, name, attributes); + List listeners; + Resource resource; + synchronized(lock){ + entities.remove(id); + entities.put(id, entity); + + resource = rebuildResource(); + listeners = new ArrayList<>(this.listeners); + } + for (EntityListener listener : listeners) { + listener.onEntityState(entity, resource); + } + + } + + @Override + public void updateEntity(String id, Attributes attributes) { + List listeners; + Resource resource; + Entity updatedEntity; + synchronized(lock){ + Entity entity = entities.get(id); + if(entity == null){ + return; + } + updatedEntity = entity.withAttributes(attributes); + entities.put(id, updatedEntity); + resource = rebuildResource(); + listeners = new ArrayList<>(this.listeners); + } + for (EntityListener listener : listeners) { + listener.onEntityState(updatedEntity, resource); + } + } + + @Override + public void deleteEntity(String id) { + Entity removedEntity; + Resource resource; + synchronized(lock){ + removedEntity = entities.remove(id); + if(removedEntity == null){ + return; + } + resource = rebuildResource(); + } + for (EntityListener listener : listeners) { + listener.onEntityDelete(removedEntity, resource); + } + } + +// private void doMutationInsideLock(){ +// +// } + + private Resource rebuildResource() { + Resource newResource = doRebuildResource(); + resource.set(newResource); + return newResource; + } + + private Resource doRebuildResource() { + if (entities.isEmpty()) { + return Resource.empty(); + } + ResourceBuilder builder = Resource.builder(); + for (Entity entity : entities.values()) { + builder.putAll(entity.getAttributes()); + } + return builder.build(); + } +} diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java new file mode 100644 index 00000000000..b2fe0861d97 --- /dev/null +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java @@ -0,0 +1,181 @@ +package io.opentelemetry.sdk.entities; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +class SdkEntityProviderTest { + + AttributeKey k1 = stringKey("a1.k"); + AttributeKey k2 = stringKey("a2.k"); + Attributes a1 = Attributes.of(k1, "boop"); + Attributes a2 = Attributes.of(k2, "bleep"); + Entity e1 = Entity.create("foo", "fooname", a1); + Entity e2 = Entity.create("bar", "barname", a2); + + @Test + void emptyListGivesConstructorGivesResource() { + Resource res = new SdkEntityProvider().getResource(); + assertThat(res).isSameAs(Resource.empty()); + } + + @Test + void constructorGivesResource() { + List entities = Arrays.asList(e1, e2); + Resource res = new SdkEntityProvider(entities).getResource(); + assertThat(res.getAttributes().asMap()).containsOnly( + entry(k1, "boop"), + entry(k2, "bleep") + ); + } + + @Test + void constructWithIdCollisions() { + Entity e1 = Entity.create("x", "fooname", a1); + Entity e2 = Entity.create("x", "barname", a2); + List entities = Arrays.asList(e1, e2); + + Resource res = new SdkEntityProvider(entities).getResource(); + assertThat(res.getAttributes().asMap()).containsOnly( + entry(k2, "bleep")); + } + + @Test + void addNewEntity() { + Attributes newAttr = Attributes.of(stringKey("new key"), "newval"); + EntityListener listener = mock(EntityListener.class); + ArgumentCaptor entityCaptor = ArgumentCaptor.forClass(Entity.class); + ArgumentCaptor resourceCaptor = ArgumentCaptor.forClass(Resource.class); + + doNothing().when(listener).onEntityState(entityCaptor.capture(), resourceCaptor.capture()); + + EntityProvider entityProvider = new SdkEntityProvider(singletonList(e1)); + entityProvider.addListener(listener); + + entityProvider.addEntity("new id", "new name", newAttr); + + assertThat(entityCaptor.getValue().getId()).isEqualTo("new id"); + assertThat(entityCaptor.getValue().getName()).isEqualTo("new name"); + assertThat(entityProvider.getResource().getAttributes().asMap()).containsOnly( + entry(k1, "boop"), + entry(stringKey("new key"), "newval") + ); + } + + @Test + void addWithExistingIdOverridesEntity() { + Attributes newAttr = Attributes.of(stringKey("jibro"), "newval"); + + EntityListener listener = mock(EntityListener.class); + + ArgumentCaptor entityCaptor = ArgumentCaptor.forClass(Entity.class); + ArgumentCaptor resourceCaptor = ArgumentCaptor.forClass(Resource.class); + doNothing().when(listener).onEntityState(entityCaptor.capture(), resourceCaptor.capture()); + + EntityProvider entityProvider = new SdkEntityProvider(singletonList(e1)); + entityProvider.addListener(listener); + + entityProvider.addEntity(e1.getId(), "new name", newAttr); + + assertThat(entityCaptor.getValue().getId()).isEqualTo(e1.getId()); + assertThat(entityCaptor.getValue().getName()).isEqualTo("new name"); + assertThat(resourceCaptor.getValue()).isSameAs(entityProvider.getResource()); + assertThat(entityProvider.getResource().getAttributes().asMap()).containsOnly( + entry(stringKey("jibro"), "newval") + ); + } + + @Test + void updateNotFoundNoListeners() { + EntityListener listener = mock(EntityListener.class); + + EntityProvider entityProvider = new SdkEntityProvider(singletonList(e1)); + entityProvider.addListener(listener); + + Resource resource = entityProvider.getResource(); + entityProvider.updateEntity("notfound", Attributes.empty()); + verifyNoInteractions(listener); + assertThat(entityProvider.getResource()).isSameAs(resource); + } + + @Test + void updateEntity() { + AttributeKey newKey = stringKey("jibro"); + Attributes newAttr = Attributes.of(newKey, "newval"); + EntityListener listener = mock(EntityListener.class); + + ArgumentCaptor entityCaptor = ArgumentCaptor.forClass(Entity.class); + ArgumentCaptor resourceCaptor = ArgumentCaptor.forClass(Resource.class); + doNothing().when(listener).onEntityState(entityCaptor.capture(), resourceCaptor.capture()); + + EntityProvider entityProvider = new SdkEntityProvider(singletonList(e1)); + entityProvider.addListener(listener); + + entityProvider.updateEntity(e1.getId(), newAttr); + + assertThat(entityCaptor.getValue().getId()).isEqualTo(e1.getId()); + assertThat(entityCaptor.getValue().getName()).isEqualTo(e1.getName()); + assertThat(entityCaptor.getValue().getAttributes()).isEqualTo(newAttr); + assertThat(entityProvider.getResource()).isSameAs(resourceCaptor.getValue()); + assertThat(resourceCaptor.getValue().getAttributes().asMap()).containsOnly( + entry(newKey, "newval") + ); + } + + @Test + void deleteEntity() { + EntityListener listener = mock(EntityListener.class); + + ArgumentCaptor entityCaptor = ArgumentCaptor.forClass(Entity.class); + ArgumentCaptor resourceCaptor = ArgumentCaptor.forClass(Resource.class); + doNothing().when(listener).onEntityDelete(entityCaptor.capture(), resourceCaptor.capture()); + + EntityProvider entityProvider = new SdkEntityProvider(Arrays.asList(e1, e2)); + entityProvider.addListener(listener); + + entityProvider.deleteEntity(e1.getId()); + + assertThat(entityCaptor.getValue().getId()).isEqualTo(e1.getId()); + assertThat(entityCaptor.getValue().getName()).isEqualTo(e1.getName()); + assertThat(entityProvider.getResource()).isSameAs(resourceCaptor.getValue()); + assertThat(resourceCaptor.getValue().getAttributes().asMap()).containsOnly( + entry(k2, "bleep") + ); + } + + @Test + void deleteEntityNotFound() { + EntityListener listener = mock(EntityListener.class); + + EntityProvider entityProvider = new SdkEntityProvider(Arrays.asList(e1, e2)); + + Resource resource = entityProvider.getResource(); + entityProvider.addListener(listener); + entityProvider.deleteEntity("NO WAY"); + verifyNoInteractions(listener); + assertThat(entityProvider.getResource()).isSameAs(resource); + } + + @Test + void deleteLastReturnsEmptyResource() { + EntityProvider entityProvider = new SdkEntityProvider(Arrays.asList(e1, e2)); + assertThat(entityProvider.getResource().getAttributes().size()).isPositive(); + entityProvider.deleteEntity(e1.getId()); + entityProvider.deleteEntity(e2.getId()); + assertThat(entityProvider.getResource().getAttributes().size()).isZero(); + assertThat(entityProvider.getResource()).isSameAs(Resource.empty()); + } + +} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java index 37bb6675c06..098387a0237 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java @@ -33,6 +33,7 @@ final class TracerSharedState { Clock clock, IdGenerator idGenerator, Resource resource, +// xxx entityprovider instead of resource here ??, Supplier spanLimitsSupplier, Sampler sampler, List spanProcessors) { From 126c7cf435b90c29ad76c27f00adf3525adac1aa Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Tue, 20 May 2025 17:44:28 -0700 Subject: [PATCH 2/6] initial prototype of EntityProvider --- .../trace/ExtendedTraceApiUsageTest.java | 8 ++-- .../otlp/trace/SpanPipelineOtlpBenchmark.java | 8 +++- .../OtlpExporterIntegrationTest.java | 15 ++++--- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 7 ++- .../AutoConfiguredOpenTelemetrySdkTest.java | 7 ++- .../DeclarativeConfigurationTest.java | 12 ++++- .../OpenTelemetryConfigurationFactory.java | 8 +++- ...OpenTelemetryConfigurationFactoryTest.java | 7 ++- .../sdk/OpenTelemetrySdkTest.java | 11 ++++- .../io/opentelemetry/sdk/entities/Entity.java | 17 ++++++- .../sdk/entities/EntityListener.java | 6 +++ .../sdk/entities/EntityProvider.java | 45 ++++++++++++------- .../sdk/entities/SdkEntityProvider.java | 38 +++++++++++----- .../sdk/entities/SdkEntityProviderTest.java | 34 ++++++-------- .../sdk/trace/SpanBenchmark.java | 10 ++++- .../sdk/trace/SdkTracerProvider.java | 6 +-- .../sdk/trace/SdkTracerProviderBuilder.java | 44 ++++++++++++++---- .../sdk/trace/TracerSharedState.java | 10 ++--- .../sdk/trace/SdkTracerProviderTest.java | 13 ++++-- 19 files changed, 216 insertions(+), 90 deletions(-) diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java index 752cd279650..04d7476beb4 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java @@ -20,7 +20,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.trace.IdGenerator; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -44,7 +44,7 @@ void tracerEnabled() { SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder() // Default resource used for demonstration purposes - .setResource(Resource.getDefault()) + .setEntityProvider(SdkEntityProvider.getDefault()) // In-memory exporter used for demonstration purposes .addSpanProcessor(SimpleSpanProcessor.create(exporter)); // Disable tracerB @@ -99,7 +99,7 @@ void setParentFrom() { SdkTracerProvider tracerProvider = SdkTracerProvider.builder() // Default resource used for demonstration purposes - .setResource(Resource.getDefault()) + .setEntityProvider(SdkEntityProvider.getDefault()) // SimpleSpanProcessor with InMemorySpanExporter used for demonstration purposes .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) .build(); @@ -159,7 +159,7 @@ void startAndCallOrRun() { SdkTracerProvider tracerProvider = SdkTracerProvider.builder() // Default resource used for demonstration purposes - .setResource(Resource.getDefault()) + .setEntityProvider(SdkEntityProvider.getDefault()) // SimpleSpanProcessor with InMemorySpanExporter used for demonstration purposes .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) .build(); diff --git a/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java b/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java index a5536b31c3b..44c0123eab3 100644 --- a/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java +++ b/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java @@ -5,6 +5,8 @@ package io.opentelemetry.exporter.otlp.trace; +import static java.util.Collections.singletonList; + import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; import com.linecorp.armeria.server.grpc.protocol.AbstractUnaryGrpcService; @@ -15,6 +17,9 @@ import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Scope; import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; @@ -75,9 +80,10 @@ protected CompletionStage handleMessage( @BeforeEach public void setUp() { + EntityProvider entityProvider = new SdkEntityProvider(singletonList(Entity.create(RESOURCE))); tracerProvider = SdkTracerProvider.builder() - .setResource(RESOURCE) + .setEntityProvider(entityProvider) .addSpanProcessor( BatchSpanProcessor.builder( OtlpGrpcSpanExporter.builder() diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 83121892006..df18e946aa4 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.integrationtest; import static io.opentelemetry.api.common.Value.of; +import static java.util.Collections.singletonList; import static java.util.concurrent.CompletableFuture.completedFuture; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -62,6 +63,9 @@ import io.opentelemetry.proto.trace.v1.ScopeSpans; import io.opentelemetry.proto.trace.v1.Span.Link; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -80,7 +84,6 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; @@ -291,10 +294,12 @@ void testOtlpHttpTraceExport_mtls() throws Exception { } private static void testTraceExport(SpanExporter spanExporter) { + + EntityProvider entityProvider = new SdkEntityProvider(singletonList(Entity.create(RESOURCE))); SdkTracerProvider tracerProvider = SdkTracerProvider.builder() .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) - .setResource(RESOURCE) + .setEntityProvider(entityProvider) .build(); SpanContext linkContext = @@ -344,7 +349,7 @@ private static void testTraceExport(SpanExporter spanExporter) { assertThat(protoSpan.getName()).isEqualTo("my span name"); assertThat(protoSpan.getAttributesList()) .isEqualTo( - Collections.singletonList( + singletonList( io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) @@ -515,7 +520,7 @@ private static void testMetricExport(MetricExporter metricExporter) { assertThat(dataPoint.getAsInt()).isEqualTo(100); assertThat(dataPoint.getAttributesList()) .isEqualTo( - Collections.singletonList( + singletonList( io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) @@ -792,7 +797,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .build()); assertThat(protoLog1.getAttributesList()) .isEqualTo( - Collections.singletonList( + singletonList( io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index e12848f0d81..52ed1dae718 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.autoconfigure; +import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; import io.opentelemetry.api.GlobalOpenTelemetry; @@ -20,6 +21,9 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; @@ -512,7 +516,8 @@ void configureSdk( closeables.add(meterProvider); SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); - tracerProviderBuilder.setResource(resource); + EntityProvider entityProvider = new SdkEntityProvider(singletonList(Entity.create(resource))); + tracerProviderBuilder.setEntityProvider(entityProvider); TracerProviderConfiguration.configureTracerProvider( tracerProviderBuilder, config, diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index c7ae65de9a0..6a7e6b903a3 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.autoconfigure; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; @@ -43,6 +44,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; @@ -504,7 +507,9 @@ void tracerProviderCustomizer() { AutoConfiguredOpenTelemetrySdk.builder() .addTracerProviderCustomizer( (tracerProviderBuilder, config) -> { - tracerProviderBuilder.setResource(Resource.builder().put("cat", "meow").build()); + Entity entity = Entity.create(Resource.builder().put("cat", "meow").build()); + tracerProviderBuilder.setEntityProvider( + new SdkEntityProvider(singletonList(entity))); return tracerProviderBuilder.addSpanProcessor( SimpleSpanProcessor.create(spanExporter)); }) diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java index 2b323ffc800..0a7c1f551e9 100644 --- a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.autoconfigure; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -31,6 +32,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; @@ -120,8 +123,13 @@ void configFile_Valid() { OpenTelemetrySdk.builder() .setTracerProvider( SdkTracerProvider.builder() - .setResource( - Resource.getDefault().toBuilder().put("service.name", "test").build()) + .setEntityProvider( + new SdkEntityProvider( + singletonList( + Entity.create( + Resource.getDefault().toBuilder() + .put("service.name", "test") + .build())))) .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) .build()) .build(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index a64e0b07dec..dd3117fe79c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -5,9 +5,14 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import static java.util.Collections.singletonList; + import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.resources.Resource; import java.util.Objects; @@ -62,6 +67,7 @@ public OpenTelemetrySdk create( } if (model.getTracerProvider() != null) { + EntityProvider entityProvider = new SdkEntityProvider(singletonList(Entity.create(resource))); builder.setTracerProvider( context.addCloseable( TracerProviderFactory.getInstance() @@ -69,7 +75,7 @@ public OpenTelemetrySdk create( TracerProviderAndAttributeLimits.create( model.getAttributeLimits(), model.getTracerProvider()), context) - .setResource(resource) + .setEntityProvider(entityProvider) .build())); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 16ec2c284d2..148f9c5f0e3 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -23,6 +23,9 @@ import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; @@ -149,6 +152,8 @@ void create_Configured() { .put("shape", "square") .put("order", "second") .build(); + EntityProvider entityProvider = + new SdkEntityProvider(Collections.singletonList(Entity.create(expectedResource))); OpenTelemetrySdk expectedSdk = OpenTelemetrySdk.builder() .setPropagators( @@ -176,7 +181,7 @@ void create_Configured() { .build()) .setTracerProvider( SdkTracerProvider.builder() - .setResource(expectedResource) + .setEntityProvider(entityProvider) .setSpanLimits( SpanLimits.builder() .setMaxNumberOfAttributes(1) diff --git a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java index 8fb5eafdf47..9b649657ec1 100644 --- a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java +++ b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java @@ -22,6 +22,9 @@ import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; @@ -40,6 +43,8 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.time.Duration; +import java.util.Collections; +import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -269,7 +274,7 @@ void fullOpenTelemetrySdkConfigurationDemo() { .addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class))) .setClock(mock(Clock.class)) .setIdGenerator(mock(IdGenerator.class)) - .setResource(Resource.empty()) + .setEntityProvider(SdkEntityProvider.empty()) .setSpanLimits(SpanLimits.builder().setMaxNumberOfAttributes(512).build()) .build()) .setPropagators(ContextPropagators.create(mock(TextMapPropagator.class))) @@ -379,11 +384,13 @@ void stringRepresentation() { when(propagator.toString()).thenReturn("MockTextMapPropagator{}"); Resource resource = Resource.builder().put(AttributeKey.stringKey("service.name"), "otel-test").build(); + List entities = Collections.singletonList(Entity.create(resource)); + EntityProvider entityProvider = new SdkEntityProvider(entities); OpenTelemetrySdk sdk = OpenTelemetrySdk.builder() .setTracerProvider( SdkTracerProvider.builder() - .setResource(resource) + .setEntityProvider(entityProvider) .addSpanProcessor( SimpleSpanProcessor.create( SpanExporter.composite(spanExporter, spanExporter))) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java index e9d91ebe051..438b8582b54 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/Entity.java @@ -1,17 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.sdk.entities; import com.google.auto.value.AutoValue; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.resources.Resource; import javax.annotation.concurrent.Immutable; @Immutable @AutoValue -abstract public class Entity { +public abstract class Entity { public static Entity create(String id, String name, Attributes attributes) { return new AutoValue_Entity(id, name, attributes); } + public static Entity create(Resource resource) { + // TODO: We didn't have an id/name, so we just use the hashCode() and this feels hacky + return create( + String.valueOf(resource.hashCode()), + String.valueOf(resource.hashCode()), + resource.getAttributes()); + } + public abstract String getId(); public abstract String getName(); @@ -21,5 +35,4 @@ public static Entity create(String id, String name, Attributes attributes) { public Entity withAttributes(Attributes newAttributes) { return new AutoValue_Entity(getId(), getName(), newAttributes); } - } diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java index a1f40d80147..a980e9bb616 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityListener.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.sdk.entities; import io.opentelemetry.sdk.resources.Resource; @@ -5,5 +10,6 @@ public interface EntityListener { void onEntityState(Entity state, Resource resource); + void onEntityDelete(Entity state, Resource resource); } diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java index 622a5bcea94..3bcf1742852 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/EntityProvider.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.sdk.entities; import io.opentelemetry.api.common.Attributes; @@ -6,39 +11,47 @@ public interface EntityProvider { /** - * Returns the current representation of the Resource, as materialized by the - * Entities contained herein. + * Returns the current representation of the Resource, as materialized by the Entities contained + * herein. */ Resource getResource(); /** - * Adds a listener to the end of the list of EntityListeners. The listener - * will be notified when changes are made to the EntityProvider. + * Adds a listener to the end of the list of EntityListeners. The listener will be notified when + * changes are made to the EntityProvider. + * * @param listener - an EntityListener */ void addListener(EntityListener listener); /** - * Adds a new Entity to the EntityProvider. If an Entity with the same id already exists, - * it will be removed and a new instance will be inserted at the end of the list of - * entities. After the entity is added, the resource is rebuilt and the listeners are - * notified. + * Adds a new Entity to the EntityProvider. If an Entity with the same id already exists, it will + * be removed and a new instance will be inserted at the end of the list of entities. After the + * entity is added, the resource is rebuilt and the listeners are notified. */ void addEntity(String id, String name, Attributes attributes); /** - * Updates an existing Entity with the given id with new attributes. If an Entity - * with the given id does not exist, this is effective a no-op. This method does not - * change the order of ids, so the change is effectively made "in-place". After the - * Entity has been updated, the listeners will be notified. + * Adds a new Entity to the EntityProvider. If an Entity with the same id already exists, it will + * be removed and a new instance will be inserted at the end of the list of entities. After the + * entity is added, the resource is rebuilt and the listeners are notified. + */ + default void addEntity(Entity entity) { + addEntity(entity.getId(), entity.getName(), entity.getAttributes()); + } + + /** + * Updates an existing Entity with the given id with new attributes. If an Entity with the given + * id does not exist, this is effective a no-op. This method does not change the order of ids, so + * the change is effectively made "in-place". After the Entity has been updated, the listeners + * will be notified. */ void updateEntity(String id, Attributes attributes); /** - * Deletes the Entity with the given id. If the Entity does not exist within - * this EntityProvider, then it is effectively a no-op. If the Entity is removed, - * the Resource will be rebuilt and listeners will then be notified. + * Deletes the Entity with the given id. If the Entity does not exist within this EntityProvider, + * then it is effectively a no-op. If the Entity is removed, the Resource will be rebuilt and + * listeners will then be notified. */ void deleteEntity(String id); - } diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java index fb54b95af4e..350e338a594 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/entities/SdkEntityProvider.java @@ -1,5 +1,12 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.sdk.entities; +import static java.util.Collections.singletonList; + import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.internal.GuardedBy; import io.opentelemetry.sdk.resources.Resource; @@ -14,8 +21,10 @@ public class SdkEntityProvider implements EntityProvider { private final Object lock = new Object(); private final AtomicReference resource = new AtomicReference<>(Resource.empty()); + @GuardedBy("lock") - private final LinkedHashMap entities = new LinkedHashMap<>(); + private final LinkedHashMap entities = new LinkedHashMap<>(); + @GuardedBy("lock") private final List listeners = new ArrayList<>(); @@ -30,6 +39,16 @@ public SdkEntityProvider(List initialEntities) { rebuildResource(); } + public static EntityProvider getDefault() { + Resource resource = Resource.getDefault(); + Entity entity = Entity.create(resource); + return new SdkEntityProvider(singletonList(entity)); + } + + public static EntityProvider empty() { + return new SdkEntityProvider(singletonList(Entity.create(Resource.empty()))); + } + @Override public Resource getResource() { Resource result = resource.get(); @@ -38,7 +57,7 @@ public Resource getResource() { @Override public void addListener(EntityListener listener) { - synchronized(lock){ + synchronized (lock) { listeners.add(listener); } } @@ -48,7 +67,7 @@ public void addEntity(String id, String name, Attributes attributes) { Entity entity = Entity.create(id, name, attributes); List listeners; Resource resource; - synchronized(lock){ + synchronized (lock) { entities.remove(id); entities.put(id, entity); @@ -58,7 +77,6 @@ public void addEntity(String id, String name, Attributes attributes) { for (EntityListener listener : listeners) { listener.onEntityState(entity, resource); } - } @Override @@ -66,9 +84,9 @@ public void updateEntity(String id, Attributes attributes) { List listeners; Resource resource; Entity updatedEntity; - synchronized(lock){ + synchronized (lock) { Entity entity = entities.get(id); - if(entity == null){ + if (entity == null) { return; } updatedEntity = entity.withAttributes(attributes); @@ -85,9 +103,9 @@ public void updateEntity(String id, Attributes attributes) { public void deleteEntity(String id) { Entity removedEntity; Resource resource; - synchronized(lock){ + synchronized (lock) { removedEntity = entities.remove(id); - if(removedEntity == null){ + if (removedEntity == null) { return; } resource = rebuildResource(); @@ -97,10 +115,6 @@ public void deleteEntity(String id) { } } -// private void doMutationInsideLock(){ -// -// } - private Resource rebuildResource() { Resource newResource = doRebuildResource(); resource.set(newResource); diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java index b2fe0861d97..8d81fd26bae 100644 --- a/sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/entities/SdkEntityProviderTest.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.sdk.entities; import static io.opentelemetry.api.common.AttributeKey.stringKey; @@ -35,10 +40,7 @@ void emptyListGivesConstructorGivesResource() { void constructorGivesResource() { List entities = Arrays.asList(e1, e2); Resource res = new SdkEntityProvider(entities).getResource(); - assertThat(res.getAttributes().asMap()).containsOnly( - entry(k1, "boop"), - entry(k2, "bleep") - ); + assertThat(res.getAttributes().asMap()).containsOnly(entry(k1, "boop"), entry(k2, "bleep")); } @Test @@ -48,8 +50,7 @@ void constructWithIdCollisions() { List entities = Arrays.asList(e1, e2); Resource res = new SdkEntityProvider(entities).getResource(); - assertThat(res.getAttributes().asMap()).containsOnly( - entry(k2, "bleep")); + assertThat(res.getAttributes().asMap()).containsOnly(entry(k2, "bleep")); } @Test @@ -68,10 +69,8 @@ void addNewEntity() { assertThat(entityCaptor.getValue().getId()).isEqualTo("new id"); assertThat(entityCaptor.getValue().getName()).isEqualTo("new name"); - assertThat(entityProvider.getResource().getAttributes().asMap()).containsOnly( - entry(k1, "boop"), - entry(stringKey("new key"), "newval") - ); + assertThat(entityProvider.getResource().getAttributes().asMap()) + .containsOnly(entry(k1, "boop"), entry(stringKey("new key"), "newval")); } @Test @@ -92,9 +91,8 @@ void addWithExistingIdOverridesEntity() { assertThat(entityCaptor.getValue().getId()).isEqualTo(e1.getId()); assertThat(entityCaptor.getValue().getName()).isEqualTo("new name"); assertThat(resourceCaptor.getValue()).isSameAs(entityProvider.getResource()); - assertThat(entityProvider.getResource().getAttributes().asMap()).containsOnly( - entry(stringKey("jibro"), "newval") - ); + assertThat(entityProvider.getResource().getAttributes().asMap()) + .containsOnly(entry(stringKey("jibro"), "newval")); } @Test @@ -129,9 +127,8 @@ void updateEntity() { assertThat(entityCaptor.getValue().getName()).isEqualTo(e1.getName()); assertThat(entityCaptor.getValue().getAttributes()).isEqualTo(newAttr); assertThat(entityProvider.getResource()).isSameAs(resourceCaptor.getValue()); - assertThat(resourceCaptor.getValue().getAttributes().asMap()).containsOnly( - entry(newKey, "newval") - ); + assertThat(resourceCaptor.getValue().getAttributes().asMap()) + .containsOnly(entry(newKey, "newval")); } @Test @@ -150,9 +147,7 @@ void deleteEntity() { assertThat(entityCaptor.getValue().getId()).isEqualTo(e1.getId()); assertThat(entityCaptor.getValue().getName()).isEqualTo(e1.getName()); assertThat(entityProvider.getResource()).isSameAs(resourceCaptor.getValue()); - assertThat(resourceCaptor.getValue().getAttributes().asMap()).containsOnly( - entry(k2, "bleep") - ); + assertThat(resourceCaptor.getValue().getAttributes().asMap()).containsOnly(entry(k2, "bleep")); } @Test @@ -177,5 +172,4 @@ void deleteLastReturnsEmptyResource() { assertThat(entityProvider.getResource().getAttributes().size()).isZero(); assertThat(entityProvider.getResource()).isSameAs(Resource.empty()); } - } diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java index cf0cf3737c8..8c21aded389 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java @@ -5,9 +5,14 @@ package io.opentelemetry.sdk.trace; +import static java.util.Collections.singletonList; + import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.concurrent.TimeUnit; @@ -35,11 +40,14 @@ public class SpanBenchmark { .put("service.instance.id", "123ab456-a123-12ab-12ab-12340a1abc12") .build()); + private final EntityProvider entityProvider = + new SdkEntityProvider(singletonList(Entity.create(serviceResource))); + @Setup(Level.Trial) public final void setup() { SdkTracerProvider tracerProvider = SdkTracerProvider.builder() - .setResource(serviceResource) + .setEntityProvider(entityProvider) .setSampler(Sampler.alwaysOn()) .build(); diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java index 8959c59a115..b58d939b783 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java @@ -11,9 +11,9 @@ import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.entities.EntityProvider; import io.opentelemetry.sdk.internal.ComponentRegistry; import io.opentelemetry.sdk.internal.ScopeConfigurator; -import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; import io.opentelemetry.sdk.trace.internal.TracerConfig; import io.opentelemetry.sdk.trace.samplers.Sampler; @@ -48,14 +48,14 @@ public static SdkTracerProviderBuilder builder() { SdkTracerProvider( Clock clock, IdGenerator idsGenerator, - Resource resource, + EntityProvider entityProvider, Supplier spanLimitsSupplier, Sampler sampler, List spanProcessors, ScopeConfigurator tracerConfigurator) { this.sharedState = new TracerSharedState( - clock, idsGenerator, resource, spanLimitsSupplier, sampler, spanProcessors); + clock, idsGenerator, entityProvider, spanLimitsSupplier, sampler, spanProcessors); this.tracerSdkComponentRegistry = new ComponentRegistry<>( instrumentationScopeInfo -> diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java index c9f604f76fc..432a93c90d1 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java @@ -7,9 +7,13 @@ import static java.util.Objects.requireNonNull; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.resources.Resource; @@ -30,7 +34,7 @@ public final class SdkTracerProviderBuilder { private Clock clock = Clock.getDefault(); private IdGenerator idsGenerator = IdGenerator.random(); - private Resource resource = Resource.getDefault(); + private EntityProvider entityProvider = SdkEntityProvider.getDefault(); private Supplier spanLimitsSupplier = SpanLimits::getDefault; private Sampler sampler = DEFAULT_SAMPLER; private ScopeConfiguratorBuilder tracerConfiguratorBuilder = @@ -69,26 +73,48 @@ public SdkTracerProviderBuilder setIdGenerator(IdGenerator idGenerator) { } /** - * Assign a {@link Resource} to be attached to all Spans created by Tracers. + * Assign an {@link EntityProvider} which can generate a Resource to be attached to all Spans + * created by Tracers. * - * @param resource A Resource implementation. + * @param entityProvider An EntityProvider implementation. * @return this */ - public SdkTracerProviderBuilder setResource(Resource resource) { - requireNonNull(resource, "resource"); - this.resource = resource; + public SdkTracerProviderBuilder setEntityProvider(EntityProvider entityProvider) { + requireNonNull(entityProvider, "entityProvider"); + this.entityProvider = entityProvider; return this; } /** - * Merge a {@link Resource} with the current. + * Merge an {@link Entity} into the EntityProvider. + * + * @since ??.??.?? + */ + public SdkTracerProviderBuilder addEntity(String id, String name, Attributes attributes) { + entityProvider.addEntity(id, name, attributes); + return this; + } + + /** + * Merge an {@link Entity} into the EntityProvider. + * + * @param entity {@link Entity} to merge with current EntityProvider. + * @since ??.??.?? + */ + public SdkTracerProviderBuilder addEntity(Entity entity) { + Objects.requireNonNull(entity, "resource"); + return addEntity(entity.getId(), entity.getName(), entity.getAttributes()); + } + + /** + * Creates an Entity from a {@link Resource} and merges it into the current EntityProvider. * * @param resource {@link Resource} to merge with current. * @since 1.29.0 */ public SdkTracerProviderBuilder addResource(Resource resource) { Objects.requireNonNull(resource, "resource"); - this.resource = this.resource.merge(resource); + entityProvider.addEntity(Entity.create(resource)); return this; } @@ -223,7 +249,7 @@ public SdkTracerProvider build() { return new SdkTracerProvider( clock, idsGenerator, - resource, + entityProvider, spanLimitsSupplier, sampler, spanProcessors, diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java index 098387a0237..0f527f0cb34 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java @@ -7,6 +7,7 @@ import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.entities.EntityProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.List; @@ -21,8 +22,8 @@ final class TracerSharedState { private final IdGenerator idGenerator; // tracks whether it is safe to skip id validation on ids from the above generator private final boolean idGeneratorSafeToSkipIdValidation; - private final Resource resource; + private final EntityProvider entityProvider; private final Supplier spanLimitsSupplier; private final Sampler sampler; private final SpanProcessor activeSpanProcessor; @@ -32,15 +33,14 @@ final class TracerSharedState { TracerSharedState( Clock clock, IdGenerator idGenerator, - Resource resource, -// xxx entityprovider instead of resource here ??, + EntityProvider entityProvider, Supplier spanLimitsSupplier, Sampler sampler, List spanProcessors) { this.clock = clock; this.idGenerator = idGenerator; this.idGeneratorSafeToSkipIdValidation = idGenerator instanceof RandomIdGenerator; - this.resource = resource; + this.entityProvider = entityProvider; this.spanLimitsSupplier = spanLimitsSupplier; this.sampler = sampler; this.activeSpanProcessor = SpanProcessor.composite(spanProcessors); @@ -59,7 +59,7 @@ boolean isIdGeneratorSafeToSkipIdValidation() { } Resource getResource() { - return resource; + return entityProvider.getResource(); } /** Returns the current {@link SpanLimits}. */ diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java index 578fd9099ee..967dbf01cc2 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.trace; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; @@ -18,6 +19,9 @@ import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.entities.Entity; +import io.opentelemetry.sdk.entities.EntityProvider; +import io.opentelemetry.sdk.entities.SdkEntityProvider; import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; @@ -87,10 +91,11 @@ void builder_serviceNameProvided() { Resource resource = Resource.create(Attributes.of(stringKey("service.name"), "mySpecialService")); + EntityProvider entityProvider = new SdkEntityProvider(singletonList(Entity.create(resource))); SdkTracerProvider tracerProvider = SdkTracerProvider.builder() .setClock(mock(Clock.class)) - .setResource(resource) + .setEntityProvider(entityProvider) .setIdGenerator(mock(IdGenerator.class)) .build(); @@ -122,10 +127,10 @@ void builder_NullClock() { } @Test - void builder_NullResource() { - assertThatThrownBy(() -> SdkTracerProvider.builder().setResource(null)) + void builder_NullEntityProvider() { + assertThatThrownBy(() -> SdkTracerProvider.builder().setEntityProvider(null)) .isInstanceOf(NullPointerException.class) - .hasMessage("resource"); + .hasMessage("entityProvider"); } @Test From 7df12a545f0b25661dc681cf79b1432a30b3d62e Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Tue, 20 May 2025 17:57:17 -0700 Subject: [PATCH 3/6] re-add setResource() and run jApiCmp --- .../opentelemetry-sdk-common.txt | 38 ++++++++++++++++++- .../opentelemetry-sdk-trace.txt | 6 ++- .../sdk/trace/SdkTracerProviderBuilder.java | 13 +++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index ddc7f6a4328..89a1967e1ab 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,38 @@ Comparing source compatibility of opentelemetry-sdk-common-1.51.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.50.0.jar -No changes. \ No newline at end of file ++++ NEW CLASS: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.entities.Entity (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW CONSTRUCTOR: PUBLIC(+) Entity() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.entities.Entity create(java.lang.String, java.lang.String, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.entities.Entity create(io.opentelemetry.sdk.resources.Resource) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Attributes getAttributes() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getId() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getName() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.entities.Entity withAttributes(io.opentelemetry.api.common.Attributes) ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.entities.EntityListener (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void onEntityDelete(io.opentelemetry.sdk.entities.Entity, io.opentelemetry.sdk.resources.Resource) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void onEntityState(io.opentelemetry.sdk.entities.Entity, io.opentelemetry.sdk.resources.Resource) ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.entities.EntityProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void addEntity(java.lang.String, java.lang.String, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) void addEntity(io.opentelemetry.sdk.entities.Entity) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void addListener(io.opentelemetry.sdk.entities.EntityListener) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void deleteEntity(java.lang.String) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.resources.Resource getResource() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void updateEntity(java.lang.String, io.opentelemetry.api.common.Attributes) ++++ NEW CLASS: PUBLIC(+) io.opentelemetry.sdk.entities.SdkEntityProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: io.opentelemetry.sdk.entities.EntityProvider + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW CONSTRUCTOR: PUBLIC(+) SdkEntityProvider() + +++ NEW CONSTRUCTOR: PUBLIC(+) SdkEntityProvider(java.util.List) + +++ NEW METHOD: PUBLIC(+) void addEntity(java.lang.String, java.lang.String, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) void addListener(io.opentelemetry.sdk.entities.EntityListener) + +++ NEW METHOD: PUBLIC(+) void deleteEntity(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.entities.EntityProvider empty() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.entities.EntityProvider getDefault() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.resources.Resource getResource() + +++ NEW METHOD: PUBLIC(+) void updateEntity(java.lang.String, io.opentelemetry.api.common.Attributes) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index cc1f1483cea..ff3944ec726 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,6 @@ Comparing source compatibility of opentelemetry-sdk-trace-1.51.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.50.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.SdkTracerProviderBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.SdkTracerProviderBuilder addEntity(java.lang.String, java.lang.String, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.SdkTracerProviderBuilder addEntity(io.opentelemetry.sdk.entities.Entity) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.SdkTracerProviderBuilder setEntityProvider(io.opentelemetry.sdk.entities.EntityProvider) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java index 432a93c90d1..0ba1adc07a5 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java @@ -21,6 +21,7 @@ import io.opentelemetry.sdk.trace.internal.TracerConfig; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.function.Predicate; @@ -106,6 +107,18 @@ public SdkTracerProviderBuilder addEntity(Entity entity) { return addEntity(entity.getId(), entity.getName(), entity.getAttributes()); } + /** + * Assign a {@link Resource} to be attached to all Spans created by Tracers. + * + * @param resource A Resource implementation. + * @return this + */ + public SdkTracerProviderBuilder setResource(Resource resource) { + requireNonNull(resource, "resource"); + this.entityProvider = new SdkEntityProvider(Collections.singletonList(Entity.create(resource))); + return this; + } + /** * Creates an Entity from a {@link Resource} and merges it into the current EntityProvider. * From 4cd447a23ce2fffb3d7a9408ec4dc2c2ab6bd9d6 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Tue, 20 May 2025 22:18:16 -0700 Subject: [PATCH 4/6] fix test --- .../java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java index 967dbf01cc2..b276d51b369 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java @@ -64,6 +64,7 @@ void builder_defaultResource() { assertThat(tracerProvider).isNotNull(); assertThat(tracerProvider) .extracting("sharedState") + .extracting("entityProvider") .hasFieldOrPropertyWithValue("resource", resourceWithDefaults); } @@ -102,6 +103,7 @@ void builder_serviceNameProvided() { assertThat(tracerProvider).isNotNull(); assertThat(tracerProvider) .extracting("sharedState") + .extracting("entityProvider") .hasFieldOrPropertyWithValue("resource", resource); } From f279641de1e498bc0852ed4a592963270e3f448a Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Tue, 20 May 2025 22:21:23 -0700 Subject: [PATCH 5/6] fix test --- .../io/opentelemetry/sdk/trace/SdkTracerProviderBuilderTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilderTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilderTest.java index 5972a914cef..702f777764c 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilderTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilderTest.java @@ -28,6 +28,7 @@ void addResource() { assertThat(sdkTracerProvider) .extracting("sharedState") + .extracting("entityProvider") .hasFieldOrPropertyWithValue("resource", Resource.getDefault().merge(customResource)); } From 3949ed30cf47335899ec73681a4028aaaccaa3ac Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Wed, 21 May 2025 14:59:21 -0700 Subject: [PATCH 6/6] remove addEntity methods --- .../sdk/trace/SdkTracerProviderBuilder.java | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java index 0ba1adc07a5..85e32176df6 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java @@ -7,7 +7,6 @@ import static java.util.Objects.requireNonNull; -import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -86,27 +85,6 @@ public SdkTracerProviderBuilder setEntityProvider(EntityProvider entityProvider) return this; } - /** - * Merge an {@link Entity} into the EntityProvider. - * - * @since ??.??.?? - */ - public SdkTracerProviderBuilder addEntity(String id, String name, Attributes attributes) { - entityProvider.addEntity(id, name, attributes); - return this; - } - - /** - * Merge an {@link Entity} into the EntityProvider. - * - * @param entity {@link Entity} to merge with current EntityProvider. - * @since ??.??.?? - */ - public SdkTracerProviderBuilder addEntity(Entity entity) { - Objects.requireNonNull(entity, "resource"); - return addEntity(entity.getId(), entity.getName(), entity.getAttributes()); - } - /** * Assign a {@link Resource} to be attached to all Spans created by Tracers. *