Skip to content

Commit 325822c

Browse files
authored
Use autoconfigured ClassLoader to load declarative config (#6725)
1 parent 39b2411 commit 325822c

File tree

6 files changed

+84
-28
lines changed

6 files changed

+84
-28
lines changed

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
107107
private Function<ConfigProperties, ConfigProperties> configPropertiesCustomizer =
108108
Function.identity();
109109

110-
private SpiHelper spiHelper =
111-
SpiHelper.create(AutoConfiguredOpenTelemetrySdk.class.getClassLoader());
110+
private ComponentLoader componentLoader =
111+
SpiHelper.serviceComponentLoader(AutoConfiguredOpenTelemetrySdk.class.getClassLoader());
112112

113113
private boolean registerShutdownHook = true;
114114

@@ -401,14 +401,14 @@ public AutoConfiguredOpenTelemetrySdkBuilder setResultAsGlobal() {
401401
public AutoConfiguredOpenTelemetrySdkBuilder setServiceClassLoader(
402402
ClassLoader serviceClassLoader) {
403403
requireNonNull(serviceClassLoader, "serviceClassLoader");
404-
this.spiHelper = SpiHelper.create(serviceClassLoader);
404+
this.componentLoader = SpiHelper.serviceComponentLoader(serviceClassLoader);
405405
return this;
406406
}
407407

408408
/** Sets the {@link ComponentLoader} to be used to load SPI implementations. */
409409
AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader componentLoader) {
410410
requireNonNull(componentLoader, "componentLoader");
411-
this.spiHelper = SpiHelper.create(componentLoader);
411+
this.componentLoader = componentLoader;
412412
return this;
413413
}
414414

@@ -417,6 +417,7 @@ AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader compone
417417
* the settings of this {@link AutoConfiguredOpenTelemetrySdkBuilder}.
418418
*/
419419
public AutoConfiguredOpenTelemetrySdk build() {
420+
SpiHelper spiHelper = SpiHelper.create(componentLoader);
420421
if (!customized) {
421422
customized = true;
422423
mergeSdkTracerProviderConfigurer();
@@ -428,7 +429,8 @@ public AutoConfiguredOpenTelemetrySdk build() {
428429

429430
ConfigProperties config = getConfig();
430431

431-
AutoConfiguredOpenTelemetrySdk fromFileConfiguration = maybeConfigureFromFile(config);
432+
AutoConfiguredOpenTelemetrySdk fromFileConfiguration =
433+
maybeConfigureFromFile(config, componentLoader);
432434
if (fromFileConfiguration != null) {
433435
maybeRegisterShutdownHook(fromFileConfiguration.getOpenTelemetrySdk());
434436
maybeSetAsGlobal(fromFileConfiguration.getOpenTelemetrySdk());
@@ -527,7 +529,8 @@ public AutoConfiguredOpenTelemetrySdk build() {
527529
}
528530

529531
@Nullable
530-
private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigProperties config) {
532+
private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(
533+
ConfigProperties config, ComponentLoader componentLoader) {
531534
String otelConfigFile = config.getString("otel.config.file");
532535
if (otelConfigFile != null && !otelConfigFile.isEmpty()) {
533536
logger.warning(
@@ -552,8 +555,10 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigPrope
552555
Class<?> openTelemetryConfiguration =
553556
Class.forName(
554557
"io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel");
555-
Method create = configurationFactory.getMethod("create", openTelemetryConfiguration);
556-
OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model);
558+
Method create =
559+
configurationFactory.getMethod(
560+
"create", openTelemetryConfiguration, ComponentLoader.class);
561+
OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model, componentLoader);
557562
Method toConfigProperties =
558563
configurationFactory.getMethod("toConfigProperties", openTelemetryConfiguration);
559564
StructuredConfigProperties structuredConfigProperties =
@@ -608,7 +613,7 @@ void callAutoConfigureListeners(SpiHelper spiHelper, OpenTelemetrySdk openTeleme
608613
@SuppressWarnings("deprecation") // Support deprecated SdkTracerProviderConfigurer
609614
private void mergeSdkTracerProviderConfigurer() {
610615
for (io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer configurer :
611-
spiHelper.load(
616+
componentLoader.load(
612617
io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer.class)) {
613618
addTracerProviderCustomizer(
614619
(builder, config) -> {

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,24 @@ private SpiHelper(ComponentLoader componentLoader) {
4141

4242
/** Create a {@link SpiHelper} which loads SPIs using the {@code classLoader}. */
4343
public static SpiHelper create(ClassLoader classLoader) {
44-
return new SpiHelper(new ServiceLoaderComponentLoader(classLoader));
44+
return new SpiHelper(serviceComponentLoader(classLoader));
4545
}
4646

4747
/** Create a {@link SpiHelper} which loads SPIs using the {@code componentLoader}. */
4848
public static SpiHelper create(ComponentLoader componentLoader) {
4949
return new SpiHelper(componentLoader);
5050
}
5151

52+
/** Create a {@link ComponentLoader} which loads using the {@code classLoader}. */
53+
public static ComponentLoader serviceComponentLoader(ClassLoader classLoader) {
54+
return new ServiceLoaderComponentLoader(classLoader);
55+
}
56+
57+
/** Return the backing underlying {@link ComponentLoader}. */
58+
public ComponentLoader getComponentLoader() {
59+
return componentLoader;
60+
}
61+
5262
/**
5363
* Load implementations of an SPI which are configurable (i.e. they accept {@link
5464
* ConfigProperties}.

sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ static <T> T requireNonNull(@Nullable T object, String description) {
4949
*/
5050
static <T> T loadComponent(SpiHelper spiHelper, Class<T> type, String name, Object model) {
5151
// Map model to generic structured config properties
52-
StructuredConfigProperties config = FileConfiguration.toConfigProperties(model);
52+
StructuredConfigProperties config =
53+
FileConfiguration.toConfigProperties(model, spiHelper.getComponentLoader());
5354
return spiHelper.loadComponent(type, name, config);
5455
}
5556
}

sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.fasterxml.jackson.core.type.TypeReference;
1111
import com.fasterxml.jackson.databind.ObjectMapper;
1212
import io.opentelemetry.sdk.OpenTelemetrySdk;
13+
import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader;
1314
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
1415
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
1516
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
@@ -49,6 +50,8 @@ public final class FileConfiguration {
4950
private static final Logger logger = Logger.getLogger(FileConfiguration.class.getName());
5051
private static final Pattern ENV_VARIABLE_REFERENCE =
5152
Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)}");
53+
private static final ComponentLoader DEFAULT_COMPONENT_LOADER =
54+
SpiHelper.serviceComponentLoader(FileConfiguration.class.getClassLoader());
5255

5356
private static final ObjectMapper MAPPER;
5457

@@ -86,9 +89,24 @@ public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) {
8689
* @throws ConfigurationException if unable to interpret
8790
*/
8891
public static OpenTelemetrySdk create(OpenTelemetryConfigurationModel configurationModel) {
92+
return create(configurationModel, DEFAULT_COMPONENT_LOADER);
93+
}
94+
95+
/**
96+
* Interpret the {@code configurationModel} to create {@link OpenTelemetrySdk} instance
97+
* corresponding to the configuration.
98+
*
99+
* @param configurationModel the configuration model
100+
* @param componentLoader the component loader used to load {@link ComponentProvider}
101+
* implementations
102+
* @return the {@link OpenTelemetrySdk}
103+
* @throws ConfigurationException if unable to interpret
104+
*/
105+
public static OpenTelemetrySdk create(
106+
OpenTelemetryConfigurationModel configurationModel, ComponentLoader componentLoader) {
89107
return createAndMaybeCleanup(
90108
OpenTelemetryConfigurationFactory.getInstance(),
91-
SpiHelper.create(FileConfiguration.class.getClassLoader()),
109+
SpiHelper.create(componentLoader),
92110
configurationModel);
93111
}
94112

@@ -130,7 +148,7 @@ static Object loadYaml(InputStream inputStream, Map<String, String> environmentV
130148
*/
131149
public static StructuredConfigProperties toConfigProperties(
132150
OpenTelemetryConfigurationModel model) {
133-
return toConfigProperties((Object) model);
151+
return toConfigProperties(model, DEFAULT_COMPONENT_LOADER);
134152
}
135153

136154
/**
@@ -141,13 +159,14 @@ public static StructuredConfigProperties toConfigProperties(
141159
*/
142160
public static StructuredConfigProperties toConfigProperties(InputStream configuration) {
143161
Object yamlObj = loadYaml(configuration, System.getenv());
144-
return toConfigProperties(yamlObj);
162+
return toConfigProperties(yamlObj, DEFAULT_COMPONENT_LOADER);
145163
}
146164

147-
static StructuredConfigProperties toConfigProperties(Object model) {
165+
static StructuredConfigProperties toConfigProperties(
166+
Object model, ComponentLoader componentLoader) {
148167
Map<String, Object> configurationMap =
149168
MAPPER.convertValue(model, new TypeReference<Map<String, Object>>() {});
150-
return YamlStructuredConfigProperties.create(configurationMap);
169+
return YamlStructuredConfigProperties.create(configurationMap, componentLoader);
151170
}
152171

153172
/**
@@ -162,21 +181,27 @@ static StructuredConfigProperties toConfigProperties(Object model) {
162181
// ComponentProvider
163182
public static io.opentelemetry.sdk.trace.samplers.Sampler createSampler(
164183
StructuredConfigProperties genericSamplerModel) {
165-
SamplerModel samplerModel = convertToModel(genericSamplerModel, SamplerModel.class);
184+
YamlStructuredConfigProperties yamlStructuredConfigProperties =
185+
requireYamlStructuredConfigProperties(genericSamplerModel);
186+
SamplerModel samplerModel = convertToModel(yamlStructuredConfigProperties, SamplerModel.class);
166187
return createAndMaybeCleanup(
167188
SamplerFactory.getInstance(),
168-
SpiHelper.create(FileConfiguration.class.getClassLoader()),
189+
SpiHelper.create(yamlStructuredConfigProperties.getComponentLoader()),
169190
samplerModel);
170191
}
171192

172-
static <T> T convertToModel(
173-
StructuredConfigProperties structuredConfigProperties, Class<T> modelType) {
193+
private static YamlStructuredConfigProperties requireYamlStructuredConfigProperties(
194+
StructuredConfigProperties structuredConfigProperties) {
174195
if (!(structuredConfigProperties instanceof YamlStructuredConfigProperties)) {
175196
throw new ConfigurationException(
176197
"Only YamlStructuredConfigProperties can be converted to model");
177198
}
178-
return MAPPER.convertValue(
179-
((YamlStructuredConfigProperties) structuredConfigProperties).toMap(), modelType);
199+
return (YamlStructuredConfigProperties) structuredConfigProperties;
200+
}
201+
202+
static <T> T convertToModel(
203+
YamlStructuredConfigProperties structuredConfigProperties, Class<T> modelType) {
204+
return MAPPER.convertValue(structuredConfigProperties.toMap(), modelType);
180205
}
181206

182207
static <M, R> R createAndMaybeCleanup(Factory<M, R> factory, SpiHelper spiHelper, M model) {

sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ final class ResourceFactory
2525
Resource> {
2626

2727
private static final StructuredConfigProperties EMPTY_CONFIG =
28-
FileConfiguration.toConfigProperties(Collections.emptyMap());
28+
FileConfiguration.toConfigProperties(
29+
Collections.emptyMap(),
30+
SpiHelper.serviceComponentLoader(ResourceFactory.class.getClassLoader()));
2931
private static final ResourceFactory INSTANCE = new ResourceFactory();
3032

3133
private ResourceFactory() {}

sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import static java.util.stream.Collectors.joining;
99
import static java.util.stream.Collectors.toList;
1010

11+
import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader;
1112
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
1213
import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties;
1314
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
@@ -37,14 +38,17 @@ final class YamlStructuredConfigProperties implements StructuredConfigProperties
3738

3839
private final Map<String, List<YamlStructuredConfigProperties>> listEntries;
3940
private final Map<String, YamlStructuredConfigProperties> mapEntries;
41+
private final ComponentLoader componentLoader;
4042

4143
private YamlStructuredConfigProperties(
4244
Map<String, Object> simpleEntries,
4345
Map<String, List<YamlStructuredConfigProperties>> listEntries,
44-
Map<String, YamlStructuredConfigProperties> mapEntries) {
46+
Map<String, YamlStructuredConfigProperties> mapEntries,
47+
ComponentLoader componentLoader) {
4548
this.simpleEntries = simpleEntries;
4649
this.listEntries = listEntries;
4750
this.mapEntries = mapEntries;
51+
this.componentLoader = componentLoader;
4852
}
4953

5054
/**
@@ -57,7 +61,8 @@ private YamlStructuredConfigProperties(
5761
* @see FileConfiguration#toConfigProperties(OpenTelemetryConfigurationModel)
5862
*/
5963
@SuppressWarnings("unchecked")
60-
static YamlStructuredConfigProperties create(Map<String, Object> properties) {
64+
static YamlStructuredConfigProperties create(
65+
Map<String, Object> properties, ComponentLoader componentLoader) {
6166
Map<String, Object> simpleEntries = new HashMap<>();
6267
Map<String, List<YamlStructuredConfigProperties>> listEntries = new HashMap<>();
6368
Map<String, YamlStructuredConfigProperties> mapEntries = new HashMap<>();
@@ -75,13 +80,15 @@ static YamlStructuredConfigProperties create(Map<String, Object> properties) {
7580
if (isListOfMaps(value)) {
7681
List<YamlStructuredConfigProperties> list =
7782
((List<Map<String, Object>>) value)
78-
.stream().map(YamlStructuredConfigProperties::create).collect(toList());
83+
.stream()
84+
.map(map -> YamlStructuredConfigProperties.create(map, componentLoader))
85+
.collect(toList());
7986
listEntries.put(key, list);
8087
continue;
8188
}
8289
if (isMap(value)) {
8390
YamlStructuredConfigProperties configProperties =
84-
YamlStructuredConfigProperties.create((Map<String, Object>) value);
91+
YamlStructuredConfigProperties.create((Map<String, Object>) value, componentLoader);
8592
mapEntries.put(key, configProperties);
8693
continue;
8794
}
@@ -91,7 +98,8 @@ static YamlStructuredConfigProperties create(Map<String, Object> properties) {
9198
+ "\" has unrecognized object type "
9299
+ value.getClass().getName());
93100
}
94-
return new YamlStructuredConfigProperties(simpleEntries, listEntries, mapEntries);
101+
return new YamlStructuredConfigProperties(
102+
simpleEntries, listEntries, mapEntries, componentLoader);
95103
}
96104

97105
private static boolean isPrimitiveList(Object object) {
@@ -292,4 +300,9 @@ public Map<String, Object> toMap() {
292300
mapEntries.forEach((key, value) -> result.put(key, value.toMap()));
293301
return Collections.unmodifiableMap(result);
294302
}
303+
304+
/** Return the {@link ComponentLoader}. */
305+
public ComponentLoader getComponentLoader() {
306+
return componentLoader;
307+
}
295308
}

0 commit comments

Comments
 (0)