Skip to content

Commit eec2120

Browse files
authored
Add DeclarativeConfigContext (#7293)
1 parent 54e5ea7 commit eec2120

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+310
-502
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@
66
package io.opentelemetry.sdk.extension.incubator.fileconfig;
77

88
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
9-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
109
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel;
1110
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramAggregationModel;
1211
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramAggregationModel;
1312
import io.opentelemetry.sdk.metrics.Aggregation;
14-
import java.io.Closeable;
1513
import java.util.List;
1614

1715
final class AggregationFactory implements Factory<AggregationModel, Aggregation> {
@@ -25,8 +23,7 @@ static AggregationFactory getInstance() {
2523
}
2624

2725
@Override
28-
public Aggregation create(
29-
AggregationModel model, SpiHelper spiHelper, List<Closeable> closeables) {
26+
public Aggregation create(AggregationModel model, DeclarativeConfigContext context) {
3027
if (model.getDrop() != null) {
3128
return Aggregation.drop();
3229
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
import io.opentelemetry.api.common.Attributes;
1212
import io.opentelemetry.api.common.AttributesBuilder;
1313
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
14-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
1514
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel;
16-
import java.io.Closeable;
1715
import java.util.List;
1816
import javax.annotation.Nullable;
1917

@@ -28,8 +26,7 @@ static AttributeListFactory getInstance() {
2826
}
2927

3028
@Override
31-
public Attributes create(
32-
List<AttributeNameValueModel> model, SpiHelper spiHelper, List<Closeable> closeables) {
29+
public Attributes create(List<AttributeNameValueModel> model, DeclarativeConfigContext context) {
3330
AttributesBuilder builder = Attributes.builder();
3431

3532
for (AttributeNameValueModel nameValueModel : model) {

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55

66
package io.opentelemetry.sdk.extension.incubator.fileconfig;
77

8-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
98
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.CardinalityLimitsModel;
109
import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector;
1110
import io.opentelemetry.sdk.metrics.internal.state.MetricStorage;
12-
import java.io.Closeable;
13-
import java.util.List;
1411
import javax.annotation.Nullable;
1512

1613
final class CardinalityLimitsFactory
@@ -26,7 +23,7 @@ static CardinalityLimitsFactory getInstance() {
2623

2724
@Override
2825
public CardinalityLimitSelector create(
29-
CardinalityLimitsModel model, SpiHelper spiHelper, List<Closeable> closeables) {
26+
CardinalityLimitsModel model, DeclarativeConfigContext context) {
3027
int defaultLimit = getOrDefault(model.getDefault(), MetricStorage.DEFAULT_MAX_CARDINALITY);
3128
int counterLimit = getOrDefault(model.getCounter(), defaultLimit);
3229
int gaugeLimit = getOrDefault(model.getGauge(), defaultLimit);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.extension.incubator.fileconfig;
7+
8+
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
9+
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
10+
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
11+
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
12+
import java.io.Closeable;
13+
import java.util.ArrayList;
14+
import java.util.Collections;
15+
import java.util.List;
16+
import java.util.function.Function;
17+
import java.util.stream.Collectors;
18+
19+
/** Declarative configuration context and state carrier. */
20+
class DeclarativeConfigContext {
21+
22+
private final SpiHelper spiHelper;
23+
private final List<Closeable> closeables = new ArrayList<>();
24+
25+
DeclarativeConfigContext(SpiHelper spiHelper) {
26+
this.spiHelper = spiHelper;
27+
}
28+
29+
/**
30+
* Add the {@code closeable} to the list of closeables to clean up if configuration fails
31+
* exceptionally, and return it.
32+
*/
33+
<T extends Closeable> T addCloseable(T closeable) {
34+
closeables.add(closeable);
35+
return closeable;
36+
}
37+
38+
List<Closeable> getCloseables() {
39+
return Collections.unmodifiableList(closeables);
40+
}
41+
42+
/**
43+
* Find a registered {@link ComponentProvider} with {@link ComponentProvider#getType()} matching
44+
* {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link
45+
* ComponentProvider#create(DeclarativeConfigProperties)} with the given {@code model}.
46+
*
47+
* @throws DeclarativeConfigException if no matching providers are found, or if multiple are found
48+
* (i.e. conflict), or if {@link ComponentProvider#create(DeclarativeConfigProperties)} throws
49+
*/
50+
@SuppressWarnings({"unchecked", "rawtypes"})
51+
<T> T loadComponent(Class<T> type, String name, Object model) {
52+
DeclarativeConfigProperties config =
53+
DeclarativeConfiguration.toConfigProperties(model, spiHelper.getComponentLoader());
54+
55+
// TODO(jack-berg): cache loaded component providers
56+
List<ComponentProvider> componentProviders = spiHelper.load(ComponentProvider.class);
57+
List<ComponentProvider<?>> matchedProviders =
58+
componentProviders.stream()
59+
.map(
60+
(Function<ComponentProvider, ComponentProvider<?>>)
61+
componentProvider -> componentProvider)
62+
.filter(
63+
componentProvider ->
64+
componentProvider.getType() == type && name.equals(componentProvider.getName()))
65+
.collect(Collectors.toList());
66+
if (matchedProviders.isEmpty()) {
67+
throw new DeclarativeConfigException(
68+
"No component provider detected for " + type.getName() + " with name \"" + name + "\".");
69+
}
70+
if (matchedProviders.size() > 1) {
71+
throw new DeclarativeConfigException(
72+
"Component provider conflict. Multiple providers detected for "
73+
+ type.getName()
74+
+ " with name \""
75+
+ name
76+
+ "\": "
77+
+ componentProviders.stream()
78+
.map(provider -> provider.getClass().getName())
79+
.collect(Collectors.joining(",", "[", "]")));
80+
}
81+
// Exactly one matching component provider
82+
ComponentProvider<T> provider = (ComponentProvider<T>) matchedProviders.get(0);
83+
84+
try {
85+
return provider.create(config);
86+
} catch (Throwable throwable) {
87+
throw new DeclarativeConfigException(
88+
"Error configuring " + type.getName() + " with name \"" + name + "\"", throwable);
89+
}
90+
}
91+
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.io.Closeable;
2222
import java.io.IOException;
2323
import java.io.InputStream;
24-
import java.util.ArrayList;
2524
import java.util.Collections;
2625
import java.util.List;
2726
import java.util.Map;
@@ -221,12 +220,12 @@ static <T> T convertToModel(
221220
}
222221

223222
static <M, R> R createAndMaybeCleanup(Factory<M, R> factory, SpiHelper spiHelper, M model) {
224-
List<Closeable> closeables = new ArrayList<>();
223+
DeclarativeConfigContext context = new DeclarativeConfigContext(spiHelper);
225224
try {
226-
return factory.create(model, spiHelper, closeables);
225+
return factory.create(model, context);
227226
} catch (RuntimeException e) {
228227
logger.info("Error encountered interpreting model. Closing partially configured components.");
229-
for (Closeable closeable : closeables) {
228+
for (Closeable closeable : context.getCloseables()) {
230229
try {
231230
logger.fine("Closing " + closeable.getClass().getName());
232231
closeable.close();

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,14 @@
55

66
package io.opentelemetry.sdk.extension.incubator.fileconfig;
77

8-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
9-
import java.io.Closeable;
10-
import java.util.List;
11-
128
interface Factory<ModelT, ResultT> {
139

1410
/**
1511
* Interpret the model and create {@link ResultT} with corresponding configuration.
1612
*
1713
* @param model the configuration model
18-
* @param spiHelper the service loader helper
19-
* @param closeables mutable list of closeables created
14+
* @param context the configuration context
2015
* @return the {@link ResultT}
2116
*/
22-
ResultT create(ModelT model, SpiHelper spiHelper, List<Closeable> closeables);
17+
ResultT create(ModelT model, DeclarativeConfigContext context);
2318
}

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

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,13 @@
88
import static java.util.stream.Collectors.joining;
99

1010
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
11-
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
12-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
13-
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
14-
import java.io.Closeable;
15-
import java.util.List;
1611
import java.util.Map;
17-
import java.util.function.Function;
18-
import java.util.stream.Collectors;
1912
import javax.annotation.Nullable;
2013

2114
final class FileConfigUtil {
2215

2316
private FileConfigUtil() {}
2417

25-
/** Add the {@code closeable} to the {@code closeables} and return it. */
26-
static <T> T addAndReturn(List<Closeable> closeables, T closeable) {
27-
if (closeable instanceof Closeable) {
28-
closeables.add((Closeable) closeable);
29-
}
30-
return closeable;
31-
}
32-
3318
static <T> T assertNotNull(@Nullable T object, String description) {
3419
if (object == null) {
3520
throw new NullPointerException(description + " is null");
@@ -44,69 +29,6 @@ static <T> T requireNonNull(@Nullable T object, String description) {
4429
return object;
4530
}
4631

47-
/**
48-
* Find a registered {@link ComponentProvider} which {@link ComponentProvider#getType()} matching
49-
* {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link
50-
* ComponentProvider#create(DeclarativeConfigProperties)} with the given {@code model}.
51-
*
52-
* @throws DeclarativeConfigException if no matching providers are found, or if multiple are found
53-
* (i.e. conflict), or if {@link ComponentProvider#create(DeclarativeConfigProperties)} throws
54-
*/
55-
static <T> T loadComponent(SpiHelper spiHelper, Class<T> type, String name, Object model) {
56-
// Map model to generic structured config properties
57-
DeclarativeConfigProperties config =
58-
DeclarativeConfiguration.toConfigProperties(model, spiHelper.getComponentLoader());
59-
return loadComponentHelper(spiHelper, type, name, config);
60-
}
61-
62-
/**
63-
* Find a registered {@link ComponentProvider} with {@link ComponentProvider#getType()} matching
64-
* {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link
65-
* ComponentProvider#create(DeclarativeConfigProperties)} with the given {@code config}.
66-
*
67-
* @throws DeclarativeConfigException if no matching providers are found, or if multiple are found
68-
* (i.e. conflict), or if {@link ComponentProvider#create(DeclarativeConfigProperties)} throws
69-
*/
70-
@SuppressWarnings({"unchecked", "rawtypes"})
71-
private static <T> T loadComponentHelper(
72-
SpiHelper spiHelper, Class<T> type, String name, DeclarativeConfigProperties config) {
73-
// TODO(jack-berg): cache loaded component providers
74-
List<ComponentProvider> componentProviders = spiHelper.load(ComponentProvider.class);
75-
List<ComponentProvider<?>> matchedProviders =
76-
componentProviders.stream()
77-
.map(
78-
(Function<ComponentProvider, ComponentProvider<?>>)
79-
componentProvider -> componentProvider)
80-
.filter(
81-
componentProvider ->
82-
componentProvider.getType() == type && name.equals(componentProvider.getName()))
83-
.collect(Collectors.toList());
84-
if (matchedProviders.isEmpty()) {
85-
throw new DeclarativeConfigException(
86-
"No component provider detected for " + type.getName() + " with name \"" + name + "\".");
87-
}
88-
if (matchedProviders.size() > 1) {
89-
throw new DeclarativeConfigException(
90-
"Component provider conflict. Multiple providers detected for "
91-
+ type.getName()
92-
+ " with name \""
93-
+ name
94-
+ "\": "
95-
+ componentProviders.stream()
96-
.map(provider -> provider.getClass().getName())
97-
.collect(Collectors.joining(",", "[", "]")));
98-
}
99-
// Exactly one matching component provider
100-
ComponentProvider<T> provider = (ComponentProvider<T>) matchedProviders.get(0);
101-
102-
try {
103-
return provider.create(config);
104-
} catch (Throwable throwable) {
105-
throw new DeclarativeConfigException(
106-
"Error configuring " + type.getName() + " with name \"" + name + "\"", throwable);
107-
}
108-
}
109-
11032
static Map.Entry<String, Object> getSingletonMapEntry(
11133
Map<String, Object> additionalProperties, String resourceName) {
11234
if (additionalProperties.isEmpty()) {

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66
package io.opentelemetry.sdk.extension.incubator.fileconfig;
77

88
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
9-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
109
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewSelectorModel;
1110
import io.opentelemetry.sdk.metrics.InstrumentSelector;
1211
import io.opentelemetry.sdk.metrics.InstrumentSelectorBuilder;
1312
import io.opentelemetry.sdk.metrics.InstrumentType;
14-
import java.io.Closeable;
15-
import java.util.List;
1613

1714
final class InstrumentSelectorFactory implements Factory<ViewSelectorModel, InstrumentSelector> {
1815

@@ -25,8 +22,7 @@ static InstrumentSelectorFactory getInstance() {
2522
}
2623

2724
@Override
28-
public InstrumentSelector create(
29-
ViewSelectorModel model, SpiHelper spiHelper, List<Closeable> closeables) {
25+
public InstrumentSelector create(ViewSelectorModel model, DeclarativeConfigContext context) {
3026
InstrumentSelectorBuilder builder = InstrumentSelector.builder();
3127
if (model.getInstrumentName() != null) {
3228
builder.setName(model.getInstrumentName());

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55

66
package io.opentelemetry.sdk.extension.incubator.fileconfig;
77

8-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
98
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel;
109
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel;
1110
import io.opentelemetry.sdk.logs.LogLimits;
1211
import io.opentelemetry.sdk.logs.LogLimitsBuilder;
13-
import java.io.Closeable;
14-
import java.util.List;
1512

1613
final class LogLimitsFactory implements Factory<LogRecordLimitsAndAttributeLimits, LogLimits> {
1714

@@ -25,7 +22,7 @@ static LogLimitsFactory getInstance() {
2522

2623
@Override
2724
public LogLimits create(
28-
LogRecordLimitsAndAttributeLimits model, SpiHelper spiHelper, List<Closeable> closeables) {
25+
LogRecordLimitsAndAttributeLimits model, DeclarativeConfigContext context) {
2926
LogLimitsBuilder builder = LogLimits.builder();
3027

3128
AttributeLimitsModel attributeLimitsModel = model.getAttributeLimits();

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@
55

66
package io.opentelemetry.sdk.extension.incubator.fileconfig;
77

8-
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
98
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
109
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
11-
import java.io.Closeable;
12-
import java.util.List;
1310
import java.util.Map;
1411

1512
final class LogRecordExporterFactory implements Factory<LogRecordExporterModel, LogRecordExporter> {
@@ -23,8 +20,7 @@ static LogRecordExporterFactory getInstance() {
2320
}
2421

2522
@Override
26-
public LogRecordExporter create(
27-
LogRecordExporterModel model, SpiHelper spiHelper, List<Closeable> closeables) {
23+
public LogRecordExporter create(LogRecordExporterModel model, DeclarativeConfigContext context) {
2824

2925
model.getAdditionalProperties().compute("otlp_http", (k, v) -> model.getOtlpHttp());
3026
model.getAdditionalProperties().compute("otlp_grpc", (k, v) -> model.getOtlpGrpc());
@@ -36,8 +32,7 @@ public LogRecordExporter create(
3632
Map.Entry<String, Object> keyValue =
3733
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "log record exporter");
3834
LogRecordExporter logRecordExporter =
39-
FileConfigUtil.loadComponent(
40-
spiHelper, LogRecordExporter.class, keyValue.getKey(), keyValue.getValue());
41-
return FileConfigUtil.addAndReturn(closeables, logRecordExporter);
35+
context.loadComponent(LogRecordExporter.class, keyValue.getKey(), keyValue.getValue());
36+
return context.addCloseable(logRecordExporter);
4237
}
4338
}

0 commit comments

Comments
 (0)