Skip to content

Commit e24ba9e

Browse files
committed
re-use sdk logic for configuring otlp exporters
1 parent b6b4ce3 commit e24ba9e

File tree

4 files changed

+96
-200
lines changed

4 files changed

+96
-200
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
import static org.assertj.core.api.Assertions.entry;
10+
11+
import io.opentelemetry.instrumentation.spring.autoconfigure.MapConverterTestAutoConfiguration;
12+
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
13+
import io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceConfigProperties;
14+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
15+
import java.util.Arrays;
16+
import java.util.stream.Stream;
17+
import org.junit.jupiter.api.DisplayName;
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
import org.junit.jupiter.params.provider.Arguments;
21+
import org.junit.jupiter.params.provider.MethodSource;
22+
import org.springframework.boot.autoconfigure.AutoConfigurations;
23+
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
24+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
25+
import org.springframework.core.env.Environment;
26+
import org.springframework.expression.spel.standard.SpelExpressionParser;
27+
28+
class OtlpExporterPropertiesTest {
29+
30+
private static final String[] HEADER_KEYS = {
31+
"otel.exporter.otlp.traces.headers",
32+
"otel.exporter.otlp.metrics.headers",
33+
"otel.exporter.otlp.logs.headers",
34+
"otel.exporter.otlp.headers",
35+
};
36+
37+
private final ApplicationContextRunner contextRunner =
38+
new ApplicationContextRunner()
39+
.withConfiguration(
40+
AutoConfigurations.of(
41+
OpenTelemetryAutoConfiguration.class, MapConverterTestAutoConfiguration.class));
42+
43+
public static Stream<Arguments> headerKeys() {
44+
return Arrays.stream(HEADER_KEYS).map(Arguments::of);
45+
}
46+
47+
@Test
48+
@DisplayName("test all property types")
49+
void allTypes() {
50+
this.contextRunner
51+
.withPropertyValues(
52+
"otel.exporter.otlp.enabled=true",
53+
"otel.exporter.otlp.timeout=1s",
54+
"otel.exporter.otlp.compression=gzip")
55+
.run(
56+
context -> {
57+
ConfigProperties config = getConfig(context);
58+
assertThat(config.getString("otel.exporter.otlp.compression")).isEqualTo("gzip");
59+
assertThat(config.getBoolean("otel.exporter.otlp.enabled")).isTrue();
60+
assertThat(config.getDuration("otel.exporter.otlp.timeout"))
61+
.isEqualByComparingTo(java.time.Duration.ofSeconds(1));
62+
});
63+
}
64+
65+
@ParameterizedTest
66+
@MethodSource("headerKeys")
67+
@DisplayName("should map headers from spring properties")
68+
void mapFlatHeaders(String key) {
69+
this.contextRunner
70+
.withSystemProperties(key + "=a=1,b=2")
71+
.run(
72+
context ->
73+
assertThat(getConfig(context).getMap(key))
74+
.containsExactly(entry("a", "1"), entry("b", "2")));
75+
}
76+
77+
@ParameterizedTest
78+
@MethodSource("headerKeys")
79+
@DisplayName("should map headers from spring application.yaml")
80+
void mapObjectHeaders(String key) {
81+
this.contextRunner
82+
.withPropertyValues(key + ".a=1", key + ".b=2")
83+
.run(
84+
context ->
85+
assertThat(getConfig(context).getMap(key))
86+
.containsExactly(entry("a", "1"), entry("b", "2")));
87+
}
88+
89+
private static ConfigProperties getConfig(AssertableApplicationContext context) {
90+
return new SpringResourceConfigProperties(
91+
context.getBean("environment", Environment.class),
92+
new SpelExpressionParser(),
93+
context.getBean(OtlpExporterProperties.class));
94+
}
95+
}

instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpLogExporterAutoConfigurationTest.java

-38
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@
77

88
import static org.assertj.core.api.Assertions.assertThat;
99

10-
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
11-
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
1210
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
1311
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
14-
import org.junit.jupiter.api.DisplayName;
1512
import org.junit.jupiter.api.Test;
1613
import org.springframework.boot.autoconfigure.AutoConfigurations;
1714
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -64,39 +61,4 @@ void otlpLogsDisabled() {
6461
.withPropertyValues("otel.logs.exporter=none")
6562
.run(context -> assertThat(context.containsBean("otelOtlpLogRecordExporter")).isFalse());
6663
}
67-
68-
@Test
69-
void otlpHttpUsedByDefault() {
70-
runner.run(
71-
context ->
72-
assertThat(
73-
context.getBean("otelOtlpLogRecordExporter", OtlpHttpLogRecordExporter.class))
74-
.isNotNull());
75-
}
76-
77-
@Test
78-
@DisplayName("use grpc when protocol set")
79-
void useGrpc() {
80-
runner
81-
.withPropertyValues("otel.exporter.otlp.protocol=grpc")
82-
.run(
83-
context ->
84-
assertThat(
85-
context.getBean(
86-
"otelOtlpLogRecordExporter", OtlpGrpcLogRecordExporter.class))
87-
.isNotNull());
88-
}
89-
90-
@Test
91-
@DisplayName("use http when unknown protocol set")
92-
void useHttpWhenAnUnknownProtocolIsSet() {
93-
runner
94-
.withPropertyValues("otel.exporter.otlp.protocol=unknown")
95-
.run(
96-
context ->
97-
assertThat(
98-
context.getBean(
99-
"otelOtlpLogRecordExporter", OtlpHttpLogRecordExporter.class))
100-
.isNotNull());
101-
}
10264
}

instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpMetricExporterAutoConfigurationTest.java

-38
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@
66
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
77

88
import static org.assertj.core.api.Assertions.assertThat;
9-
import static org.assertj.core.api.Assertions.assertThatThrownBy;
109

1110
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
12-
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
1311
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
14-
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
15-
import org.junit.jupiter.api.DisplayName;
1612
import org.junit.jupiter.api.Test;
1713
import org.springframework.boot.autoconfigure.AutoConfigurations;
1814
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -35,32 +31,6 @@ void otlpEnabled() {
3531
.isNotNull());
3632
}
3733

38-
@Test
39-
@DisplayName("use grpc when protocol set")
40-
void useGrpc() {
41-
runner
42-
.withPropertyValues("otel.exporter.otlp.protocol=grpc")
43-
.run(
44-
context ->
45-
assertThat(context.getBean("otelOtlpMetricExporter", OtlpGrpcMetricExporter.class))
46-
.isNotNull());
47-
}
48-
49-
@Test
50-
@DisplayName("use http when unknown protocol set")
51-
void useHttpWhenAnUnknownProtocolIsSet() {
52-
runner
53-
.withPropertyValues("otel.exporter.otlp.protocol=unknown")
54-
.run(
55-
context ->
56-
assertThatThrownBy(
57-
() ->
58-
context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
59-
.rootCause()
60-
.isInstanceOf(ConfigurationException.class)
61-
.hasMessage("Unsupported OTLP metrics protocol: unknown"));
62-
}
63-
6434
@Test
6535
void otlpMetricsEnabled() {
6636
runner
@@ -91,12 +61,4 @@ void otlpMetricsDisabled() {
9161
.withPropertyValues("otel.metrics.exporter=none")
9262
.run(context -> assertThat(context.containsBean("otelOtlpMetricExporter")).isFalse());
9363
}
94-
95-
@Test
96-
void otlpHttpUsedByDefault() {
97-
runner.run(
98-
context ->
99-
assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
100-
.isNotNull());
101-
}
10264
}

instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfigurationTest.java

+1-124
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,21 @@
77

88
import static org.assertj.core.api.Assertions.assertThat;
99

10-
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
1110
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
12-
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
13-
import io.opentelemetry.instrumentation.spring.autoconfigure.MapConverterTestAutoConfiguration;
1411
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
15-
import io.opentelemetry.sdk.trace.export.SpanExporter;
16-
import java.util.stream.Collectors;
17-
import org.junit.jupiter.api.AfterEach;
1812
import org.junit.jupiter.api.DisplayName;
1913
import org.junit.jupiter.api.Test;
20-
import org.mockito.Mockito;
2114
import org.springframework.boot.autoconfigure.AutoConfigurations;
2215
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2316

2417
/** Spring Boot auto configuration test for {@link OtlpSpanExporterAutoConfiguration}. */
2518
class OtlpSpanExporterAutoConfigurationTest {
2619

27-
private final OtlpExporterProperties otlpExporterProperties =
28-
Mockito.mock(OtlpExporterProperties.class);
29-
3020
private final ApplicationContextRunner contextRunner =
3121
new ApplicationContextRunner()
3222
.withConfiguration(
3323
AutoConfigurations.of(
34-
OpenTelemetryAutoConfiguration.class,
35-
OtlpSpanExporterAutoConfiguration.class,
36-
MapConverterTestAutoConfiguration.class));
37-
38-
@AfterEach
39-
void tearDown() {
40-
Mockito.verifyNoMoreInteractions(otlpExporterProperties);
41-
}
24+
OpenTelemetryAutoConfiguration.class, OtlpSpanExporterAutoConfiguration.class));
4225

4326
@Test
4427
@DisplayName("when exporters are ENABLED should initialize OtlpHttpSpanExporter bean")
@@ -75,110 +58,4 @@ void otlpTracesDisabledOld() {
7558
.withPropertyValues("otel.exporter.otlp.traces.enabled=false")
7659
.run(context -> assertThat(context.containsBean("otelOtlpSpanExporter")).isFalse());
7760
}
78-
79-
@Test
80-
void otlpTracesDisabled() {
81-
this.contextRunner
82-
.withPropertyValues("otel.traces.exporter=none")
83-
.run(context -> assertThat(context.containsBean("otelOtlpSpanExporter")).isFalse());
84-
}
85-
86-
@Test
87-
@DisplayName("when otlp enabled property is MISSING should initialize OtlpHttpSpanExporter bean")
88-
void exporterPresentByDefault() {
89-
this.contextRunner.run(
90-
context ->
91-
assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
92-
.isNotNull());
93-
}
94-
95-
@Test
96-
@DisplayName("use http/protobuf when protocol set")
97-
void useHttp() {
98-
this.contextRunner
99-
// .withBean(OtlpExporterProperties.class, () -> otlpExporterProperties)
100-
.withPropertyValues(
101-
"otel.exporter.otlp.enabled=true",
102-
"otel.exporter.otlp.protocol=http/protobuf",
103-
"otel.exporter.otlp.endpoint=http://localhost:4317",
104-
"otel.exporter.otlp.headers.x=1",
105-
"otel.exporter.otlp.headers.y=2",
106-
"otel.exporter.otlp.timeout=1s")
107-
.run(
108-
context ->
109-
assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
110-
.hasFieldOrProperty("delegate")
111-
.asString()
112-
.contains("x=OBFUSCATED, y=OBFUSCATED"));
113-
114-
// Mockito.verify(otlpHttpSpanExporterBuilder).build();
115-
//
116-
// Mockito.verify(otlpHttpSpanExporterBuilder).setEndpoint("http://localhost:4317/v1/traces");
117-
// Mockito.verify(otlpHttpSpanExporterBuilder).addHeader("x", "1");
118-
// Mockito.verify(otlpHttpSpanExporterBuilder).addHeader("y", "2");
119-
// Mockito.verify(otlpHttpSpanExporterBuilder).setTimeout(java.time.Duration.ofSeconds(1));
120-
// Mockito.verifyNoMoreInteractions(otlpHttpSpanExporterBuilder);
121-
}
122-
123-
@Test
124-
@DisplayName("use http/protobuf with environment variables for headers using the MapConverter")
125-
void useHttpWithEnv() {
126-
this.contextRunner
127-
// .withBean(OtlpHttpSpanExporterBuilder.class, () -> otlpHttpSpanExporterBuilder)
128-
.withPropertyValues(
129-
"otel.exporter.otlp.enabled=true", "otel.exporter.otlp.protocol=http/protobuf")
130-
// are similar to environment variables in that they use the same converters
131-
.withSystemProperties("otel.exporter.otlp.headers=x=1,y=2")
132-
.run(
133-
context ->
134-
assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
135-
.hasFieldOrProperty("delegate")
136-
.asString()
137-
.contains("x=OBFUSCATED, y=OBFUSCATED"));
138-
139-
// Mockito.verify(otlpHttpSpanExporterBuilder).build();
140-
// Mockito.verify(otlpHttpSpanExporterBuilder).addHeader("x", "1");
141-
// Mockito.verify(otlpHttpSpanExporterBuilder).addHeader("y", "2");
142-
// Mockito.verifyNoMoreInteractions(otlpHttpSpanExporterBuilder);
143-
}
144-
145-
@Test
146-
@DisplayName("use grpc when protocol set")
147-
void useGrpc() {
148-
this.contextRunner
149-
.withPropertyValues("otel.exporter.otlp.protocol=grpc")
150-
.run(
151-
context ->
152-
assertThat(context.getBean(OtlpGrpcSpanExporter.class))
153-
.as("Should contain the gRPC span exporter when grpc is set")
154-
.isNotNull());
155-
}
156-
157-
@Test
158-
@DisplayName("use http when unknown protocol set")
159-
void useHttpWhenAnUnknownProtocolIsSet() {
160-
this.contextRunner
161-
.withPropertyValues("otel.exporter.otlp.protocol=unknown")
162-
.run(
163-
context ->
164-
assertThat(context.getBean(OtlpHttpSpanExporter.class))
165-
.as("Should contain the http span exporter when an unknown is set")
166-
.isNotNull());
167-
}
168-
169-
@Test
170-
@DisplayName("logging exporter can still be configured")
171-
void loggingExporter() {
172-
this.contextRunner
173-
.withBean(
174-
LoggingSpanExporter.class,
175-
LoggingSpanExporter::create,
176-
bd -> bd.setDestroyMethodName(""))
177-
.run(
178-
context ->
179-
assertThat(
180-
context.getBeanProvider(SpanExporter.class).stream()
181-
.collect(Collectors.toList()))
182-
.hasSize(2));
183-
}
18461
}

0 commit comments

Comments
 (0)