From 897bbef1ada3387a0c50cbd43f2c9dbf3c93d7ad Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 31 Dec 2025 17:14:27 -0600 Subject: [PATCH 1/3] Improve pattern for validating and loading SDK extension plugins --- .../fileconfig/ComposableSamplerFactory.java | 54 +++++---- .../fileconfig/DeclarativeConfigContext.java | 7 +- .../incubator/fileconfig/FileConfigUtil.java | 52 +++------ .../fileconfig/LogRecordExporterFactory.java | 31 ++--- .../fileconfig/LogRecordProcessorFactory.java | 98 +++++++++------- .../fileconfig/MetricExporterFactory.java | 27 ++--- .../fileconfig/MetricReaderFactory.java | 45 +++---- .../fileconfig/PropagatorFactory.java | 4 +- .../fileconfig/ResourceDetectorFactory.java | 25 +--- .../incubator/fileconfig/SamplerFactory.java | 110 +++++++++--------- .../fileconfig/SpanExporterFactory.java | 25 +--- .../fileconfig/SpanProcessorFactory.java | 90 +++++++------- .../fileconfig/TextMapPropagatorFactory.java | 36 ++---- ...ComposableRuleBasedSamplerFactoryTest.java | 8 +- .../fileconfig/MetricReaderFactoryTest.java | 2 +- .../fileconfig/ResourceFactoryTest.java | 4 +- 16 files changed, 278 insertions(+), 340 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java index 2160d2dcf06..5f7e25e5bb0 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableParentThresholdSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableProbabilitySamplerModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableRuleBasedSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableSamplerModel; import io.opentelemetry.sdk.extension.incubator.trace.samplers.ComposableSampler; import java.util.Map; @@ -26,33 +26,47 @@ static ComposableSamplerFactory getInstance() { @Override public ComposableSampler create( ExperimentalComposableSamplerModel model, DeclarativeConfigContext context) { + // We don't use the variable till later but call validate first to confirm there are not + // multiple samplers. + Map.Entry samplerKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "composable sampler"); + if (model.getAlwaysOn() != null) { return ComposableSampler.alwaysOn(); } if (model.getAlwaysOff() != null) { return ComposableSampler.alwaysOff(); } - ExperimentalComposableProbabilitySamplerModel probability = model.getProbability(); - if (probability != null) { - Double ratio = probability.getRatio(); - if (ratio == null) { - ratio = 1.0d; - } - return ComposableSampler.probability(ratio); + if (model.getProbability() != null) { + return createProbabilitySampler(model.getProbability()); } - ExperimentalComposableRuleBasedSamplerModel ruleBased = model.getRuleBased(); - if (ruleBased != null) { - return ComposableRuleBasedSamplerFactory.getInstance().create(ruleBased, context); + if (model.getRuleBased() != null) { + return ComposableRuleBasedSamplerFactory.getInstance().create(model.getRuleBased(), context); } - ExperimentalComposableParentThresholdSamplerModel parentThreshold = model.getParentThreshold(); - if (parentThreshold != null) { - ExperimentalComposableSamplerModel rootModel = - FileConfigUtil.requireNonNull(parentThreshold.getRoot(), "parent threshold sampler root"); - ComposableSampler rootSampler = INSTANCE.create(rootModel, context); - return ComposableSampler.parentThreshold(rootSampler); + if (model.getParentThreshold() != null) { + return createParentThresholdSampler(model.getParentThreshold(), context); } - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "composable sampler"); - return context.loadComponent(ComposableSampler.class, keyValue.getKey(), keyValue.getValue()); + + return context.loadComponent( + ComposableSampler.class, samplerKeyValue.getKey(), samplerKeyValue.getValue()); + } + + private static ComposableSampler createProbabilitySampler( + ExperimentalComposableProbabilitySamplerModel probabilityModel) { + Double ratio = probabilityModel.getRatio(); + if (ratio == null) { + ratio = 1.0d; + } + return ComposableSampler.probability(ratio); + } + + private static ComposableSampler createParentThresholdSampler( + ExperimentalComposableParentThresholdSamplerModel parentThresholdModel, + DeclarativeConfigContext context) { + ExperimentalComposableSamplerModel rootModel = + FileConfigUtil.requireNonNull( + parentThresholdModel.getRoot(), "parent threshold sampler root"); + ComposableSampler rootSampler = INSTANCE.create(rootModel, context); + return ComposableSampler.parentThreshold(rootSampler); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java index e93d85c3604..ada90de4ab9 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java @@ -82,11 +82,8 @@ SpiHelper getSpiHelper() { * @throws DeclarativeConfigException if no matching providers are found, or if multiple are found * (i.e. conflict), or if {@link ComponentProvider#create(DeclarativeConfigProperties)} throws */ - @SuppressWarnings({"unchecked", "rawtypes"}) - T loadComponent(Class type, String name, Object model) { - DeclarativeConfigProperties config = - DeclarativeConfiguration.toConfigProperties(model, spiHelper.getComponentLoader()); - + @SuppressWarnings({"unchecked"}) + T loadComponent(Class type, String name, DeclarativeConfigProperties config) { // TODO(jack-berg): cache loaded component providers List componentProviders = spiHelper.load(ComponentProvider.class); List matchedProviders = diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index f79d7a54932..a7949c2e698 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -8,20 +8,16 @@ import static java.util.stream.Collectors.joining; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import java.util.AbstractMap; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; final class FileConfigUtil { private FileConfigUtil() {} - static T assertNotNull(@Nullable T object, String description) { - if (object == null) { - throw new NullPointerException(description + " is null"); - } - return object; - } - static T requireNonNull(@Nullable T object, String description) { if (object == null) { throw new DeclarativeConfigException(description + " is required but is null"); @@ -29,34 +25,22 @@ static T requireNonNull(@Nullable T object, String description) { return object; } - static Map.Entry getSingletonMapEntry( - Map additionalProperties, String resourceName) { - if (additionalProperties.isEmpty()) { - throw new DeclarativeConfigException(resourceName + " must be set"); - } - if (additionalProperties.size() > 1) { - throw new DeclarativeConfigException( - "Invalid configuration - multiple " - + resourceName - + "s set: " - + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); - } - return additionalProperties.entrySet().stream() - .findFirst() - .orElseThrow( - () -> - new IllegalStateException( - "Missing " + resourceName + ". This is a programming error.")); - } - - static void requireNullResource( - @Nullable Object resource, String resourceName, Map additionalProperties) { - if (resource != null) { + static Map.Entry validateSingleKeyValue( + DeclarativeConfigContext context, Object model, String resourceName) { + DeclarativeConfigProperties modelConfigProperties = + DeclarativeConfiguration.toConfigProperties( + model, context.getSpiHelper().getComponentLoader()); + Set propertyKeys = modelConfigProperties.getPropertyKeys(); + if (propertyKeys.size() != 1) { + String suffix = + propertyKeys.isEmpty() + ? "" + : ": " + propertyKeys.stream().collect(joining(",", "[", "]")); throw new DeclarativeConfigException( - "Invalid configuration - multiple " - + resourceName - + "s set: " - + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); + resourceName + " must have exactly one entry but has " + propertyKeys.size() + suffix); } + String key = propertyKeys.iterator().next(); + DeclarativeConfigProperties value = modelConfigProperties.getStructured(key); + return new AbstractMap.SimpleEntry<>(key, value); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index 9ebf2e692f6..006ebcadd80 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import java.util.LinkedHashMap; import java.util.Map; final class LogRecordExporterFactory implements Factory { @@ -21,26 +21,13 @@ static LogRecordExporterFactory getInstance() { @Override public LogRecordExporter create(LogRecordExporterModel model, DeclarativeConfigContext context) { - Map exporterResourceByName = new LinkedHashMap<>(); - - if (model.getOtlpHttp() != null) { - exporterResourceByName.put("otlp_http", model.getOtlpHttp()); - } - if (model.getOtlpGrpc() != null) { - exporterResourceByName.put("otlp_grpc", model.getOtlpGrpc()); - } - if (model.getOtlpFileDevelopment() != null) { - exporterResourceByName.put("otlp_file/development", model.getOtlpFileDevelopment()); - } - if (model.getConsole() != null) { - exporterResourceByName.put("console", model.getConsole()); - } - exporterResourceByName.putAll(model.getAdditionalProperties()); - - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(exporterResourceByName, "log record exporter"); - LogRecordExporter metricExporter = - context.loadComponent(LogRecordExporter.class, keyValue.getKey(), keyValue.getValue()); - return context.addCloseable(metricExporter); + Map.Entry logRecordExporterKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "log record exporter"); + LogRecordExporter logRecordExporter = + context.loadComponent( + LogRecordExporter.class, + logRecordExporterKeyValue.getKey(), + logRecordExporterKeyValue.getValue()); + return context.addCloseable(logRecordExporter); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 6e5491e6623..c1a54fa330c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -5,11 +5,11 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorPropertyModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; @@ -33,54 +33,64 @@ static LogRecordProcessorFactory getInstance() { @Override public LogRecordProcessor create( LogRecordProcessorModel model, DeclarativeConfigContext context) { - BatchLogRecordProcessorModel batchModel = model.getBatch(); - if (batchModel != null) { - LogRecordExporterModel exporterModel = - FileConfigUtil.requireNonNull( - batchModel.getExporter(), "batch log record processor exporter"); + // We don't use the variable till later but call validate first to confirm there are not + // multiple samplers. + Map.Entry processorKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "log record processor"); - LogRecordExporter logRecordExporter = - LogRecordExporterFactory.getInstance().create(exporterModel, context); - BatchLogRecordProcessorBuilder builder = BatchLogRecordProcessor.builder(logRecordExporter); - if (batchModel.getExportTimeout() != null) { - builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); - } - if (batchModel.getMaxExportBatchSize() != null) { - builder.setMaxExportBatchSize(batchModel.getMaxExportBatchSize()); - } - if (batchModel.getMaxQueueSize() != null) { - builder.setMaxQueueSize(batchModel.getMaxQueueSize()); - } - if (batchModel.getScheduleDelay() != null) { - builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay())); - } - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(meterProvider); - } - - return context.addCloseable(builder.build()); + if (model.getBatch() != null) { + return createBatchLogRecordProcessor(model.getBatch(), context); } - - SimpleLogRecordProcessorModel simpleModel = model.getSimple(); - if (simpleModel != null) { - LogRecordExporterModel exporterModel = - FileConfigUtil.requireNonNull( - simpleModel.getExporter(), "simple log record processor exporter"); - LogRecordExporter logRecordExporter = - LogRecordExporterFactory.getInstance().create(exporterModel, context); - MeterProvider meterProvider = context.getMeterProvider(); - return context.addCloseable( - SimpleLogRecordProcessor.builder(logRecordExporter) - .setMeterProvider(() -> meterProvider) - .build()); + if (model.getSimple() != null) { + return createSimpleLogRecordProcessor(model.getSimple(), context); } - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry( - model.getAdditionalProperties(), "log record processor"); LogRecordProcessor logRecordProcessor = - context.loadComponent(LogRecordProcessor.class, keyValue.getKey(), keyValue.getValue()); + context.loadComponent( + LogRecordProcessor.class, processorKeyValue.getKey(), processorKeyValue.getValue()); return context.addCloseable(logRecordProcessor); } + + private static LogRecordProcessor createBatchLogRecordProcessor( + BatchLogRecordProcessorModel batchModel, DeclarativeConfigContext context) { + LogRecordExporterModel exporterModel = + FileConfigUtil.requireNonNull( + batchModel.getExporter(), "batch log record processor exporter"); + + LogRecordExporter logRecordExporter = + LogRecordExporterFactory.getInstance().create(exporterModel, context); + BatchLogRecordProcessorBuilder builder = BatchLogRecordProcessor.builder(logRecordExporter); + if (batchModel.getExportTimeout() != null) { + builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); + } + if (batchModel.getMaxExportBatchSize() != null) { + builder.setMaxExportBatchSize(batchModel.getMaxExportBatchSize()); + } + if (batchModel.getMaxQueueSize() != null) { + builder.setMaxQueueSize(batchModel.getMaxQueueSize()); + } + if (batchModel.getScheduleDelay() != null) { + builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay())); + } + MeterProvider meterProvider = context.getMeterProvider(); + if (meterProvider != null) { + builder.setMeterProvider(meterProvider); + } + + return context.addCloseable(builder.build()); + } + + private static LogRecordProcessor createSimpleLogRecordProcessor( + SimpleLogRecordProcessorModel simpleModel, DeclarativeConfigContext context) { + LogRecordExporterModel exporterModel = + FileConfigUtil.requireNonNull( + simpleModel.getExporter(), "simple log record processor exporter"); + LogRecordExporter logRecordExporter = + LogRecordExporterFactory.getInstance().create(exporterModel, context); + MeterProvider meterProvider = context.getMeterProvider(); + return context.addCloseable( + SimpleLogRecordProcessor.builder(logRecordExporter) + .setMeterProvider(() -> meterProvider) + .build()); + } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index a7ab5eb7b10..df56834d3b1 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.metrics.export.MetricExporter; -import java.util.LinkedHashMap; import java.util.Map; final class MetricExporterFactory implements Factory { @@ -21,26 +21,13 @@ static MetricExporterFactory getInstance() { @Override public MetricExporter create(PushMetricExporterModel model, DeclarativeConfigContext context) { - Map exporterResourceByName = new LinkedHashMap<>(); - - if (model.getOtlpHttp() != null) { - exporterResourceByName.put("otlp_http", model.getOtlpHttp()); - } - if (model.getOtlpGrpc() != null) { - exporterResourceByName.put("otlp_grpc", model.getOtlpGrpc()); - } - if (model.getOtlpFileDevelopment() != null) { - exporterResourceByName.put("otlp_file/development", model.getOtlpFileDevelopment()); - } - if (model.getConsole() != null) { - exporterResourceByName.put("console", model.getConsole()); - } - exporterResourceByName.putAll(model.getAdditionalProperties()); - - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(exporterResourceByName, "metric exporter"); + Map.Entry metricExporterKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "metric exporter"); MetricExporter metricExporter = - context.loadComponent(MetricExporter.class, keyValue.getKey(), keyValue.getValue()); + context.loadComponent( + MetricExporter.class, + metricExporterKeyValue.getKey(), + metricExporterKeyValue.getValue()); return context.addCloseable(metricExporter); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index 464ad868e74..9b94661daa1 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -8,7 +8,7 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalPrometheusMetricExporterModel; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel; @@ -20,6 +20,7 @@ import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder; import java.time.Duration; +import java.util.Map; final class MetricReaderFactory implements Factory { @@ -35,14 +36,13 @@ static MetricReaderFactory getInstance() { @Override public MetricReaderAndCardinalityLimits create( MetricReaderModel model, DeclarativeConfigContext context) { - PeriodicMetricReaderModel periodicModel = model.getPeriodic(); - if (periodicModel != null) { - return PeriodicMetricReaderFactory.INSTANCE.create(periodicModel, context); - } + FileConfigUtil.validateSingleKeyValue(context, model, "metric reader"); - PullMetricReaderModel pullModel = model.getPull(); - if (pullModel != null) { - return PullMetricReaderFactory.INSTANCE.create(pullModel, context); + if (model.getPeriodic() != null) { + return PeriodicMetricReaderFactory.INSTANCE.create(model.getPeriodic(), context); + } + if (model.getPull() != null) { + return PullMetricReaderFactory.INSTANCE.create(model.getPull(), context); } throw new DeclarativeConfigException("reader must be set"); @@ -92,26 +92,19 @@ public MetricReaderAndCardinalityLimits create( PullMetricReaderModel model, DeclarativeConfigContext context) { PullMetricExporterModel exporterModel = requireNonNull(model.getExporter(), "pull metric reader exporter"); - - ExperimentalPrometheusMetricExporterModel prometheusModel = - exporterModel.getPrometheusDevelopment(); - - if (prometheusModel != null) { - MetricReader metricReader = - context.addCloseable( - context.loadComponent( - MetricReader.class, "prometheus/development", prometheusModel)); - CardinalityLimitSelector cardinalityLimitSelector = null; - if (model.getCardinalityLimits() != null) { - cardinalityLimitSelector = - CardinalityLimitsFactory.getInstance().create(model.getCardinalityLimits(), context); - } - - return MetricReaderAndCardinalityLimits.create(metricReader, cardinalityLimitSelector); + CardinalityLimitSelector cardinalityLimitSelector = null; + if (model.getCardinalityLimits() != null) { + cardinalityLimitSelector = + CardinalityLimitsFactory.getInstance().create(model.getCardinalityLimits(), context); } - throw new DeclarativeConfigException( - "prometheus is the only currently supported pull reader"); + Map.Entry metricReaderKeyValue = + FileConfigUtil.validateSingleKeyValue(context, exporterModel, "metric reader"); + MetricReader metricReader = + context.loadComponent( + MetricReader.class, metricReaderKeyValue.getKey(), metricReaderKeyValue.getValue()); + return MetricReaderAndCardinalityLimits.create( + context.addCloseable(metricReader), cardinalityLimitSelector); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java index e9f2422f9fd..70c643270c1 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; @@ -55,7 +56,8 @@ public ContextPropagators create(PropagatorModel model, DeclarativeConfigContext // Only add entries which weren't already previously added if (propagatorNames.add(propagatorName)) { textMapPropagators.add( - TextMapPropagatorFactory.getPropagator(context, propagatorName) + TextMapPropagatorFactory.getPropagator( + context, propagatorName, DeclarativeConfigProperties.empty()) .getTextMapPropagator()); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java index 56966606e9b..edf03445c5a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel; import io.opentelemetry.sdk.resources.Resource; -import java.util.LinkedHashMap; import java.util.Map; final class ResourceDetectorFactory @@ -23,24 +23,9 @@ static ResourceDetectorFactory getInstance() { @Override public Resource create( ExperimentalResourceDetectorModel model, DeclarativeConfigContext context) { - Map detectorResourceByName = new LinkedHashMap<>(); - - if (model.getContainer() != null) { - detectorResourceByName.put("container", model.getContainer()); - } - if (model.getHost() != null) { - detectorResourceByName.put("host", model.getHost()); - } - if (model.getProcess() != null) { - detectorResourceByName.put("process", model.getProcess()); - } - if (model.getService() != null) { - detectorResourceByName.put("service", model.getService()); - } - detectorResourceByName.putAll(model.getAdditionalProperties()); - - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(detectorResourceByName, "resource detector"); - return context.loadComponent(Resource.class, keyValue.getKey(), keyValue.getValue()); + Map.Entry detectorKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "resource detector"); + return context.loadComponent( + Resource.class, detectorKeyValue.getKey(), detectorKeyValue.getValue()); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java index 921eebe3670..2143514f16b 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableSamplerModel; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalProbabilitySamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; @@ -28,71 +28,75 @@ static SamplerFactory getInstance() { @Override public Sampler create(SamplerModel model, DeclarativeConfigContext context) { + // We don't use the variable till later but call validate first to confirm there are not + // multiple samplers. + Map.Entry samplerKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "sampler"); + if (model.getAlwaysOn() != null) { return Sampler.alwaysOn(); } if (model.getAlwaysOff() != null) { return Sampler.alwaysOff(); } - TraceIdRatioBasedSamplerModel traceIdRatioBasedModel = model.getTraceIdRatioBased(); - if (traceIdRatioBasedModel != null) { - Double ratio = traceIdRatioBasedModel.getRatio(); - if (ratio == null) { - ratio = 1.0d; - } - return Sampler.traceIdRatioBased(ratio); + if (model.getTraceIdRatioBased() != null) { + return createTraceIdRatioBasedSampler(model.getTraceIdRatioBased()); } - ParentBasedSamplerModel parentBasedModel = model.getParentBased(); - if (parentBasedModel != null) { - Sampler root = - parentBasedModel.getRoot() == null - ? Sampler.alwaysOn() - : create(parentBasedModel.getRoot(), context); - ParentBasedSamplerBuilder builder = Sampler.parentBasedBuilder(root); - if (parentBasedModel.getRemoteParentSampled() != null) { - Sampler sampler = create(parentBasedModel.getRemoteParentSampled(), context); - builder.setRemoteParentSampled(sampler); - } - if (parentBasedModel.getRemoteParentNotSampled() != null) { - Sampler sampler = create(parentBasedModel.getRemoteParentNotSampled(), context); - builder.setRemoteParentNotSampled(sampler); - } - if (parentBasedModel.getLocalParentSampled() != null) { - Sampler sampler = create(parentBasedModel.getLocalParentSampled(), context); - builder.setLocalParentSampled(sampler); - } - if (parentBasedModel.getLocalParentNotSampled() != null) { - Sampler sampler = create(parentBasedModel.getLocalParentNotSampled(), context); - builder.setLocalParentNotSampled(sampler); - } - return builder.build(); + if (model.getParentBased() != null) { + return createParedBasedSampler(model.getParentBased(), context); } - ExperimentalProbabilitySamplerModel probability = model.getProbabilityDevelopment(); - if (probability != null) { - Double ratio = probability.getRatio(); - if (ratio == null) { - ratio = 1.0d; - } - return CompositeSampler.wrap(ComposableSampler.probability(ratio)); + if (model.getProbabilityDevelopment() != null) { + return createProbabilitySampler(model.getProbabilityDevelopment()); } - ExperimentalComposableSamplerModel composite = model.getCompositeDevelopment(); - if (composite != null) { + if (model.getCompositeDevelopment() != null) { return CompositeSampler.wrap( - ComposableSamplerFactory.getInstance().create(composite, context)); + ComposableSamplerFactory.getInstance().create(model.getCompositeDevelopment(), context)); + } + + return context.loadComponent( + Sampler.class, samplerKeyValue.getKey(), samplerKeyValue.getValue()); + } + + private static Sampler createTraceIdRatioBasedSampler(TraceIdRatioBasedSamplerModel model) { + Double ratio = model.getRatio(); + if (ratio == null) { + ratio = 1.0d; } + return Sampler.traceIdRatioBased(ratio); + } - String key = null; - Object value = null; - if (model.getJaegerRemoteDevelopment() != null) { - key = "jaeger_remote/development"; - value = model.getJaegerRemoteDevelopment(); + private static Sampler createParedBasedSampler( + ParentBasedSamplerModel parentBasedModel, DeclarativeConfigContext context) { + Sampler root = + parentBasedModel.getRoot() == null + ? Sampler.alwaysOn() + : INSTANCE.create(parentBasedModel.getRoot(), context); + ParentBasedSamplerBuilder builder = Sampler.parentBasedBuilder(root); + if (parentBasedModel.getRemoteParentSampled() != null) { + Sampler sampler = INSTANCE.create(parentBasedModel.getRemoteParentSampled(), context); + builder.setRemoteParentSampled(sampler); } - if (key == null || value == null) { - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "sampler"); - key = keyValue.getKey(); - value = keyValue.getValue(); + if (parentBasedModel.getRemoteParentNotSampled() != null) { + Sampler sampler = INSTANCE.create(parentBasedModel.getRemoteParentNotSampled(), context); + builder.setRemoteParentNotSampled(sampler); + } + if (parentBasedModel.getLocalParentSampled() != null) { + Sampler sampler = INSTANCE.create(parentBasedModel.getLocalParentSampled(), context); + builder.setLocalParentSampled(sampler); + } + if (parentBasedModel.getLocalParentNotSampled() != null) { + Sampler sampler = INSTANCE.create(parentBasedModel.getLocalParentNotSampled(), context); + builder.setLocalParentNotSampled(sampler); + } + return builder.build(); + } + + private static Sampler createProbabilitySampler( + ExperimentalProbabilitySamplerModel probabilityModel) { + Double ratio = probabilityModel.getRatio(); + if (ratio == null) { + ratio = 1.0d; } - return context.loadComponent(Sampler.class, key, value); + return CompositeSampler.wrap(ComposableSampler.probability(ratio)); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java index 08ac568fb60..3d75cdde2da 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.LinkedHashMap; import java.util.Map; final class SpanExporterFactory implements Factory { @@ -22,26 +22,11 @@ static SpanExporterFactory getInstance() { @Override public SpanExporter create(SpanExporterModel model, DeclarativeConfigContext context) { - Map exporterResourceByName = new LinkedHashMap<>(); - - if (model.getOtlpHttp() != null) { - exporterResourceByName.put("otlp_http", model.getOtlpHttp()); - } - if (model.getOtlpGrpc() != null) { - exporterResourceByName.put("otlp_grpc", model.getOtlpGrpc()); - } - if (model.getOtlpFileDevelopment() != null) { - exporterResourceByName.put("otlp_file/development", model.getOtlpFileDevelopment()); - } - if (model.getConsole() != null) { - exporterResourceByName.put("console", model.getConsole()); - } - exporterResourceByName.putAll(model.getAdditionalProperties()); - - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(exporterResourceByName, "span exporter"); + Map.Entry spanExporterKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "span exporter"); SpanExporter spanExporter = - context.loadComponent(SpanExporter.class, keyValue.getKey(), keyValue.getValue()); + context.loadComponent( + SpanExporter.class, spanExporterKeyValue.getKey(), spanExporterKeyValue.getValue()); return context.addCloseable(spanExporter); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 5720141483c..1af925dabae 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -5,12 +5,12 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorPropertyModel; import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder; @@ -32,50 +32,60 @@ static SpanProcessorFactory getInstance() { @Override public SpanProcessor create(SpanProcessorModel model, DeclarativeConfigContext context) { - BatchSpanProcessorModel batchModel = model.getBatch(); - if (batchModel != null) { - SpanExporterModel exporterModel = - FileConfigUtil.requireNonNull(batchModel.getExporter(), "batch span processor exporter"); - SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, context); - BatchSpanProcessorBuilder builder = BatchSpanProcessor.builder(spanExporter); - if (batchModel.getExportTimeout() != null) { - builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); - } - if (batchModel.getMaxExportBatchSize() != null) { - builder.setMaxExportBatchSize(batchModel.getMaxExportBatchSize()); - } - if (batchModel.getMaxQueueSize() != null) { - builder.setMaxQueueSize(batchModel.getMaxQueueSize()); - } - if (batchModel.getScheduleDelay() != null) { - builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay())); - } - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(() -> meterProvider); - } + // We don't use the variable till later but call validate first to confirm there are not + // multiple samplers. + Map.Entry processorKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "span processor"); - return context.addCloseable(builder.build()); + if (model.getBatch() != null) { + return createBatchLogRecordProcessor(model.getBatch(), context); } - - SimpleSpanProcessorModel simpleModel = model.getSimple(); - if (simpleModel != null) { - SpanExporterModel exporterModel = - FileConfigUtil.requireNonNull( - simpleModel.getExporter(), "simple span processor exporter"); - SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, context); - SimpleSpanProcessorBuilder builder = SimpleSpanProcessor.builder(spanExporter); - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(() -> meterProvider); - } - return context.addCloseable(builder.build()); + if (model.getSimple() != null) { + return createSimpleLogRecordProcessor(model.getSimple(), context); } - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "span processor"); SpanProcessor spanProcessor = - context.loadComponent(SpanProcessor.class, keyValue.getKey(), keyValue.getValue()); + context.loadComponent( + SpanProcessor.class, processorKeyValue.getKey(), processorKeyValue.getValue()); return context.addCloseable(spanProcessor); } + + private static SpanProcessor createBatchLogRecordProcessor( + BatchSpanProcessorModel batchModel, DeclarativeConfigContext context) { + SpanExporterModel exporterModel = + FileConfigUtil.requireNonNull(batchModel.getExporter(), "batch span processor exporter"); + SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, context); + BatchSpanProcessorBuilder builder = BatchSpanProcessor.builder(spanExporter); + if (batchModel.getExportTimeout() != null) { + builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); + } + if (batchModel.getMaxExportBatchSize() != null) { + builder.setMaxExportBatchSize(batchModel.getMaxExportBatchSize()); + } + if (batchModel.getMaxQueueSize() != null) { + builder.setMaxQueueSize(batchModel.getMaxQueueSize()); + } + if (batchModel.getScheduleDelay() != null) { + builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay())); + } + MeterProvider meterProvider = context.getMeterProvider(); + if (meterProvider != null) { + builder.setMeterProvider(() -> meterProvider); + } + + return context.addCloseable(builder.build()); + } + + private static SpanProcessor createSimpleLogRecordProcessor( + SimpleSpanProcessorModel simpleModel, DeclarativeConfigContext context) { + SpanExporterModel exporterModel = + FileConfigUtil.requireNonNull(simpleModel.getExporter(), "simple span processor exporter"); + SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, context); + SimpleSpanProcessorBuilder builder = SimpleSpanProcessor.builder(spanExporter); + MeterProvider meterProvider = context.getMeterProvider(); + if (meterProvider != null) { + builder.setMeterProvider(() -> meterProvider); + } + return context.addCloseable(builder.build()); + } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java index ac85badb3fd..4d64ce5f1fb 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java @@ -6,11 +6,10 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TextMapPropagatorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TextMapPropagatorPropertyModel; -import java.util.Collections; import java.util.Map; final class TextMapPropagatorFactory @@ -27,41 +26,20 @@ static TextMapPropagatorFactory getInstance() { @Override public TextMapPropagatorAndName create( TextMapPropagatorModel model, DeclarativeConfigContext context) { - if (model.getTracecontext() != null) { - return getPropagator(context, "tracecontext"); - } - if (model.getBaggage() != null) { - return getPropagator(context, "baggage"); - } - if (model.getB3() != null) { - return getPropagator(context, "b3"); - } - if (model.getB3multi() != null) { - return getPropagator(context, "b3multi"); - } - if (model.getJaeger() != null) { - return getPropagator(context, "jaeger"); - } - if (model.getOttrace() != null) { - return getPropagator(context, "ottrace"); - } - - Map.Entry keyValue = - FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "propagator"); - TextMapPropagator propagator = - context.loadComponent(TextMapPropagator.class, keyValue.getKey(), keyValue.getValue()); - return TextMapPropagatorAndName.create(propagator, keyValue.getKey()); + Map.Entry propagatorKeyValue = + FileConfigUtil.validateSingleKeyValue(context, model, "propagator"); + return getPropagator(context, propagatorKeyValue.getKey(), propagatorKeyValue.getValue()); } - static TextMapPropagatorAndName getPropagator(DeclarativeConfigContext context, String name) { + static TextMapPropagatorAndName getPropagator( + DeclarativeConfigContext context, String name, DeclarativeConfigProperties configProperties) { TextMapPropagator textMapPropagator; if (name.equals("tracecontext")) { textMapPropagator = W3CTraceContextPropagator.getInstance(); } else if (name.equals("baggage")) { textMapPropagator = W3CBaggagePropagator.getInstance(); } else { - textMapPropagator = - context.loadComponent(TextMapPropagator.class, name, Collections.emptyMap()); + textMapPropagator = context.loadComponent(TextMapPropagator.class, name, configProperties); } return TextMapPropagatorAndName.create(textMapPropagator, name); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java index 683acf3c9cd..9825ab5699c 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java @@ -13,7 +13,6 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.ComposableRuleBasedSamplerFactory.DeclarativeConfigSamplingPredicate.toSpanParent; import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -22,6 +21,7 @@ import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.ComposableRuleBasedSamplerFactory.AttributeMatcher; import io.opentelemetry.sdk.extension.incubator.fileconfig.ComposableRuleBasedSamplerFactory.DeclarativeConfigSamplingPredicate; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableAlwaysOffSamplerModel; @@ -47,12 +47,14 @@ class ComposableRuleBasedSamplerFactoryTest { + private final DeclarativeConfigContext context = + new DeclarativeConfigContext(SpiHelper.create(SamplerFactoryTest.class.getClassLoader())); + @ParameterizedTest @MethodSource("createTestCases") void create(ExperimentalComposableRuleBasedSamplerModel model, ComposableSampler expectedResult) { ComposableSampler composableSampler = - ComposableRuleBasedSamplerFactory.getInstance() - .create(model, mock(DeclarativeConfigContext.class)); + ComposableRuleBasedSamplerFactory.getInstance().create(model, context); assertThat(composableSampler.toString()).isEqualTo(expectedResult.toString()); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index bc63ca7bdcb..20f20fc4152 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -228,7 +228,7 @@ void create_InvalidPullReader() { .withExporter(new PullMetricExporterModel())), context)) .isInstanceOf(DeclarativeConfigException.class) - .hasMessage("prometheus is the only currently supported pull reader"); + .hasMessage("metric reader must have exactly one entry but has 0"); } /** diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java index 1ed195376f6..58da73d00cf 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java @@ -170,13 +170,13 @@ private static Stream createInvalidDetectorsArgs() { new ExperimentalResourceDetectorModel() .withAdditionalProperty("foo", null) .withAdditionalProperty("bar", null)))), - "Invalid configuration - multiple resource detectors set: [foo,bar]"), + "resource detector must have exactly one entry but has 2: [foo,bar]"), Arguments.of( new ResourceModel() .withDetectionDevelopment( new ExperimentalResourceDetectionModel() .withDetectors( Collections.singletonList(new ExperimentalResourceDetectorModel()))), - "resource detector must be set")); + "resource detector must have exactly one entry but has 0")); } } From e9a1c6640ea765bf15f9d450edb046e61e519e68 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Fri, 2 Jan 2026 09:56:50 -0600 Subject: [PATCH 2/3] ComponentProvider loading adds closeables --- .../incubator/fileconfig/DeclarativeConfigContext.java | 3 +++ .../incubator/fileconfig/LogRecordExporterFactory.java | 10 ++++------ .../fileconfig/LogRecordProcessorFactory.java | 6 ++---- .../incubator/fileconfig/MetricExporterFactory.java | 8 ++------ .../incubator/fileconfig/MetricReaderFactory.java | 6 ++---- .../incubator/fileconfig/SpanExporterFactory.java | 6 ++---- .../incubator/fileconfig/SpanProcessorFactory.java | 6 ++---- 7 files changed, 17 insertions(+), 28 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java index ada90de4ab9..151040035bf 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java @@ -112,6 +112,9 @@ T loadComponent(Class type, String name, DeclarativeConfigProperties conf try { Object component = provider.create(config); + if (component instanceof Closeable) { + closeables.add((Closeable) component); + } if (component != null && !type.isInstance(component)) { throw new DeclarativeConfigException( "Error configuring " diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index 006ebcadd80..c8300adf366 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -23,11 +23,9 @@ static LogRecordExporterFactory getInstance() { public LogRecordExporter create(LogRecordExporterModel model, DeclarativeConfigContext context) { Map.Entry logRecordExporterKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "log record exporter"); - LogRecordExporter logRecordExporter = - context.loadComponent( - LogRecordExporter.class, - logRecordExporterKeyValue.getKey(), - logRecordExporterKeyValue.getValue()); - return context.addCloseable(logRecordExporter); + return context.loadComponent( + LogRecordExporter.class, + logRecordExporterKeyValue.getKey(), + logRecordExporterKeyValue.getValue()); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index c1a54fa330c..35a8dd50b6a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -45,10 +45,8 @@ public LogRecordProcessor create( return createSimpleLogRecordProcessor(model.getSimple(), context); } - LogRecordProcessor logRecordProcessor = - context.loadComponent( - LogRecordProcessor.class, processorKeyValue.getKey(), processorKeyValue.getValue()); - return context.addCloseable(logRecordProcessor); + return context.loadComponent( + LogRecordProcessor.class, processorKeyValue.getKey(), processorKeyValue.getValue()); } private static LogRecordProcessor createBatchLogRecordProcessor( diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index df56834d3b1..b6909e43202 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -23,11 +23,7 @@ static MetricExporterFactory getInstance() { public MetricExporter create(PushMetricExporterModel model, DeclarativeConfigContext context) { Map.Entry metricExporterKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "metric exporter"); - MetricExporter metricExporter = - context.loadComponent( - MetricExporter.class, - metricExporterKeyValue.getKey(), - metricExporterKeyValue.getValue()); - return context.addCloseable(metricExporter); + return context.loadComponent( + MetricExporter.class, metricExporterKeyValue.getKey(), metricExporterKeyValue.getValue()); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index 9b94661daa1..ff0dc9af8fa 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -63,8 +63,7 @@ public MetricReaderAndCardinalityLimits create( MetricExporter metricExporter = MetricExporterFactory.getInstance().create(exporterModel, context); - PeriodicMetricReaderBuilder builder = - PeriodicMetricReader.builder(context.addCloseable(metricExporter)); + PeriodicMetricReaderBuilder builder = PeriodicMetricReader.builder(metricExporter); if (model.getInterval() != null) { builder.setInterval(Duration.ofMillis(model.getInterval())); @@ -103,8 +102,7 @@ public MetricReaderAndCardinalityLimits create( MetricReader metricReader = context.loadComponent( MetricReader.class, metricReaderKeyValue.getKey(), metricReaderKeyValue.getValue()); - return MetricReaderAndCardinalityLimits.create( - context.addCloseable(metricReader), cardinalityLimitSelector); + return MetricReaderAndCardinalityLimits.create(metricReader, cardinalityLimitSelector); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java index 3d75cdde2da..aa0434b7a2b 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java @@ -24,9 +24,7 @@ static SpanExporterFactory getInstance() { public SpanExporter create(SpanExporterModel model, DeclarativeConfigContext context) { Map.Entry spanExporterKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "span exporter"); - SpanExporter spanExporter = - context.loadComponent( - SpanExporter.class, spanExporterKeyValue.getKey(), spanExporterKeyValue.getValue()); - return context.addCloseable(spanExporter); + return context.loadComponent( + SpanExporter.class, spanExporterKeyValue.getKey(), spanExporterKeyValue.getValue()); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 1af925dabae..444b40ac1e2 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -44,10 +44,8 @@ public SpanProcessor create(SpanProcessorModel model, DeclarativeConfigContext c return createSimpleLogRecordProcessor(model.getSimple(), context); } - SpanProcessor spanProcessor = - context.loadComponent( - SpanProcessor.class, processorKeyValue.getKey(), processorKeyValue.getValue()); - return context.addCloseable(spanProcessor); + return context.loadComponent( + SpanProcessor.class, processorKeyValue.getKey(), processorKeyValue.getValue()); } private static SpanProcessor createBatchLogRecordProcessor( From 87ff6a7b8b5f38db9b52d81e118b11ccec4de5ba Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Fri, 2 Jan 2026 16:04:53 -0600 Subject: [PATCH 3/3] Move from Map.Entry to ConfigKeyValue --- .../fileconfig/ComposableSamplerFactory.java | 4 +-- .../incubator/fileconfig/ConfigKeyValue.java | 31 +++++++++++++++++++ .../incubator/fileconfig/FileConfigUtil.java | 6 ++-- .../fileconfig/LogRecordExporterFactory.java | 4 +-- .../fileconfig/LogRecordProcessorFactory.java | 4 +-- .../fileconfig/MetricExporterFactory.java | 4 +-- .../fileconfig/MetricReaderFactory.java | 4 +-- .../fileconfig/ResourceDetectorFactory.java | 4 +-- .../incubator/fileconfig/SamplerFactory.java | 4 +-- .../fileconfig/SpanExporterFactory.java | 4 +-- .../fileconfig/SpanProcessorFactory.java | 4 +-- .../fileconfig/TextMapPropagatorFactory.java | 3 +- 12 files changed, 43 insertions(+), 33 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigKeyValue.java diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java index 5f7e25e5bb0..faea5e6f1c1 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableSamplerFactory.java @@ -5,12 +5,10 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableParentThresholdSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableProbabilitySamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalComposableSamplerModel; import io.opentelemetry.sdk.extension.incubator.trace.samplers.ComposableSampler; -import java.util.Map; final class ComposableSamplerFactory implements Factory { @@ -28,7 +26,7 @@ public ComposableSampler create( ExperimentalComposableSamplerModel model, DeclarativeConfigContext context) { // We don't use the variable till later but call validate first to confirm there are not // multiple samplers. - Map.Entry samplerKeyValue = + ConfigKeyValue samplerKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "composable sampler"); if (model.getAlwaysOn() != null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigKeyValue.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigKeyValue.java new file mode 100644 index 00000000000..b1e4609c0dd --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigKeyValue.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; + +class ConfigKeyValue { + + private final String key; + private final DeclarativeConfigProperties value; + + private ConfigKeyValue(String key, DeclarativeConfigProperties value) { + this.key = key; + this.value = value; + } + + static ConfigKeyValue of(String key, DeclarativeConfigProperties value) { + return new ConfigKeyValue(key, value); + } + + String getKey() { + return key; + } + + DeclarativeConfigProperties getValue() { + return value; + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index a7949c2e698..e2968ac6337 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -9,8 +9,6 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import java.util.AbstractMap; -import java.util.Map; import java.util.Set; import javax.annotation.Nullable; @@ -25,7 +23,7 @@ static T requireNonNull(@Nullable T object, String description) { return object; } - static Map.Entry validateSingleKeyValue( + static ConfigKeyValue validateSingleKeyValue( DeclarativeConfigContext context, Object model, String resourceName) { DeclarativeConfigProperties modelConfigProperties = DeclarativeConfiguration.toConfigProperties( @@ -41,6 +39,6 @@ static Map.Entry validateSingleKeyValue( } String key = propertyKeys.iterator().next(); DeclarativeConfigProperties value = modelConfigProperties.getStructured(key); - return new AbstractMap.SimpleEntry<>(key, value); + return ConfigKeyValue.of(key, value == null ? DeclarativeConfigProperties.empty() : value); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index c8300adf366..fe8f151480a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import java.util.Map; final class LogRecordExporterFactory implements Factory { private static final LogRecordExporterFactory INSTANCE = new LogRecordExporterFactory(); @@ -21,7 +19,7 @@ static LogRecordExporterFactory getInstance() { @Override public LogRecordExporter create(LogRecordExporterModel model, DeclarativeConfigContext context) { - Map.Entry logRecordExporterKeyValue = + ConfigKeyValue logRecordExporterKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "log record exporter"); return context.loadComponent( LogRecordExporter.class, diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 35a8dd50b6a..43370ca8805 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -5,7 +5,6 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; @@ -17,7 +16,6 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; import java.time.Duration; -import java.util.Map; final class LogRecordProcessorFactory implements Factory { @@ -35,7 +33,7 @@ public LogRecordProcessor create( LogRecordProcessorModel model, DeclarativeConfigContext context) { // We don't use the variable till later but call validate first to confirm there are not // multiple samplers. - Map.Entry processorKeyValue = + ConfigKeyValue processorKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "log record processor"); if (model.getBatch() != null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index b6909e43202..033e86cc0e1 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.metrics.export.MetricExporter; -import java.util.Map; final class MetricExporterFactory implements Factory { private static final MetricExporterFactory INSTANCE = new MetricExporterFactory(); @@ -21,7 +19,7 @@ static MetricExporterFactory getInstance() { @Override public MetricExporter create(PushMetricExporterModel model, DeclarativeConfigContext context) { - Map.Entry metricExporterKeyValue = + ConfigKeyValue metricExporterKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "metric exporter"); return context.loadComponent( MetricExporter.class, metricExporterKeyValue.getKey(), metricExporterKeyValue.getValue()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index ff0dc9af8fa..d48943bee08 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -8,7 +8,6 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel; @@ -20,7 +19,6 @@ import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder; import java.time.Duration; -import java.util.Map; final class MetricReaderFactory implements Factory { @@ -97,7 +95,7 @@ public MetricReaderAndCardinalityLimits create( CardinalityLimitsFactory.getInstance().create(model.getCardinalityLimits(), context); } - Map.Entry metricReaderKeyValue = + ConfigKeyValue metricReaderKeyValue = FileConfigUtil.validateSingleKeyValue(context, exporterModel, "metric reader"); MetricReader metricReader = context.loadComponent( diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java index edf03445c5a..65cc69c2fae 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceDetectorFactory.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel; import io.opentelemetry.sdk.resources.Resource; -import java.util.Map; final class ResourceDetectorFactory implements Factory { @@ -23,7 +21,7 @@ static ResourceDetectorFactory getInstance() { @Override public Resource create( ExperimentalResourceDetectorModel model, DeclarativeConfigContext context) { - Map.Entry detectorKeyValue = + ConfigKeyValue detectorKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "resource detector"); return context.loadComponent( Resource.class, detectorKeyValue.getKey(), detectorKeyValue.getValue()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java index 2143514f16b..79137eaa508 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java @@ -5,7 +5,6 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalProbabilitySamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; @@ -14,7 +13,6 @@ import io.opentelemetry.sdk.extension.incubator.trace.samplers.CompositeSampler; import io.opentelemetry.sdk.trace.samplers.ParentBasedSamplerBuilder; import io.opentelemetry.sdk.trace.samplers.Sampler; -import java.util.Map; final class SamplerFactory implements Factory { @@ -30,7 +28,7 @@ static SamplerFactory getInstance() { public Sampler create(SamplerModel model, DeclarativeConfigContext context) { // We don't use the variable till later but call validate first to confirm there are not // multiple samplers. - Map.Entry samplerKeyValue = + ConfigKeyValue samplerKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "sampler"); if (model.getAlwaysOn() != null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java index aa0434b7a2b..b085f3af873 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Map; final class SpanExporterFactory implements Factory { @@ -22,7 +20,7 @@ static SpanExporterFactory getInstance() { @Override public SpanExporter create(SpanExporterModel model, DeclarativeConfigContext context) { - Map.Entry spanExporterKeyValue = + ConfigKeyValue spanExporterKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "span exporter"); return context.loadComponent( SpanExporter.class, spanExporterKeyValue.getKey(), spanExporterKeyValue.getValue()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 444b40ac1e2..97a6e168a90 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -5,7 +5,6 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; @@ -18,7 +17,6 @@ import io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.time.Duration; -import java.util.Map; final class SpanProcessorFactory implements Factory { @@ -34,7 +32,7 @@ static SpanProcessorFactory getInstance() { public SpanProcessor create(SpanProcessorModel model, DeclarativeConfigContext context) { // We don't use the variable till later but call validate first to confirm there are not // multiple samplers. - Map.Entry processorKeyValue = + ConfigKeyValue processorKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "span processor"); if (model.getBatch() != null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java index 4d64ce5f1fb..f8c13ff3559 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TextMapPropagatorModel; -import java.util.Map; final class TextMapPropagatorFactory implements Factory { @@ -26,7 +25,7 @@ static TextMapPropagatorFactory getInstance() { @Override public TextMapPropagatorAndName create( TextMapPropagatorModel model, DeclarativeConfigContext context) { - Map.Entry propagatorKeyValue = + ConfigKeyValue propagatorKeyValue = FileConfigUtil.validateSingleKeyValue(context, model, "propagator"); return getPropagator(context, propagatorKeyValue.getKey(), propagatorKeyValue.getValue()); }