Skip to content

Commit fc80e8a

Browse files
committed
support config bridge
1 parent 93ca602 commit fc80e8a

File tree

5 files changed

+168
-148
lines changed

5 files changed

+168
-148
lines changed

declarative-config-bridge/src/main/java/io/opentelemetry/contrib/sdk/autoconfigure/ConfigPropertiesUtil.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,9 @@ public static ConfigProperties resolveModel(OpenTelemetryConfigurationModel mode
5252

5353
return new DeclarativeConfigPropertiesBridge(instrumentationConfig);
5454
}
55+
56+
public static String propertyYamlPath(String propertyName) {
57+
// todo test if this is correct
58+
return DeclarativeConfigPropertiesBridge.yamlPath(propertyName);
59+
}
5560
}

declarative-config-bridge/src/main/java/io/opentelemetry/contrib/sdk/autoconfigure/DeclarativeConfigPropertiesBridge.java

Lines changed: 110 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -49,110 +49,123 @@
4949
*/
5050
final class DeclarativeConfigPropertiesBridge implements ConfigProperties {
5151

52-
private static final String OTEL_INSTRUMENTATION_PREFIX = "otel.instrumentation.";
53-
54-
// The node at .instrumentation.java
55-
private final DeclarativeConfigProperties instrumentationJavaNode;
56-
57-
DeclarativeConfigPropertiesBridge(DeclarativeConfigProperties instrumentationNode) {
58-
instrumentationJavaNode = instrumentationNode.getStructured("java", empty());
59-
}
60-
61-
@Nullable
62-
@Override
63-
public String getString(String propertyName) {
64-
return getPropertyValue(propertyName, DeclarativeConfigProperties::getString);
65-
}
66-
67-
@Nullable
68-
@Override
69-
public Boolean getBoolean(String propertyName) {
70-
return getPropertyValue(propertyName, DeclarativeConfigProperties::getBoolean);
71-
}
72-
73-
@Nullable
74-
@Override
75-
public Integer getInt(String propertyName) {
76-
return getPropertyValue(propertyName, DeclarativeConfigProperties::getInt);
77-
}
78-
79-
@Nullable
80-
@Override
81-
public Long getLong(String propertyName) {
82-
return getPropertyValue(propertyName, DeclarativeConfigProperties::getLong);
83-
}
84-
85-
@Nullable
86-
@Override
87-
public Double getDouble(String propertyName) {
88-
return getPropertyValue(propertyName, DeclarativeConfigProperties::getDouble);
89-
}
90-
91-
@Nullable
92-
@Override
93-
public Duration getDuration(String propertyName) {
94-
Long millis = getPropertyValue(propertyName, DeclarativeConfigProperties::getLong);
95-
if (millis == null) {
96-
return null;
52+
private static final String OTEL_INSTRUMENTATION_PREFIX = "otel.instrumentation.";
53+
54+
// The node at .instrumentation.java
55+
private final DeclarativeConfigProperties instrumentationJavaNode;
56+
57+
DeclarativeConfigPropertiesBridge(DeclarativeConfigProperties instrumentationNode) {
58+
instrumentationJavaNode = instrumentationNode.getStructured("java", empty());
9759
}
98-
return Duration.ofMillis(millis);
99-
}
100-
101-
@Override
102-
public List<String> getList(String propertyName) {
103-
List<String> propertyValue =
104-
getPropertyValue(
105-
propertyName,
106-
(properties, lastPart) -> properties.getScalarList(lastPart, String.class));
107-
return propertyValue == null ? Collections.emptyList() : propertyValue;
108-
}
109-
110-
@Override
111-
public Map<String, String> getMap(String propertyName) {
112-
DeclarativeConfigProperties propertyValue =
113-
getPropertyValue(propertyName, DeclarativeConfigProperties::getStructured);
114-
if (propertyValue == null) {
115-
return Collections.emptyMap();
60+
61+
@Nullable
62+
@Override
63+
public String getString(String propertyName) {
64+
return getPropertyValue(propertyName, DeclarativeConfigProperties::getString);
11665
}
117-
Map<String, String> result = new HashMap<>();
118-
propertyValue
119-
.getPropertyKeys()
120-
.forEach(
121-
key -> {
122-
String value = propertyValue.getString(key);
123-
if (value == null) {
124-
return;
125-
}
126-
result.put(key, value);
127-
});
128-
return Collections.unmodifiableMap(result);
129-
}
130-
131-
@Nullable
132-
private <T> T getPropertyValue(
133-
String property, BiFunction<DeclarativeConfigProperties, String, T> extractor) {
134-
if (instrumentationJavaNode == null) {
135-
return null;
66+
67+
@Nullable
68+
@Override
69+
public Boolean getBoolean(String propertyName) {
70+
return getPropertyValue(propertyName, DeclarativeConfigProperties::getBoolean);
13671
}
13772

138-
if (property.startsWith(OTEL_INSTRUMENTATION_PREFIX)) {
139-
property = property.substring(OTEL_INSTRUMENTATION_PREFIX.length());
73+
@Nullable
74+
@Override
75+
public Integer getInt(String propertyName) {
76+
return getPropertyValue(propertyName, DeclarativeConfigProperties::getInt);
14077
}
141-
// Split the remainder of the property on "."
142-
String[] segments = property.split("\\.");
143-
if (segments.length == 0) {
144-
return null;
78+
79+
@Nullable
80+
@Override
81+
public Long getLong(String propertyName) {
82+
return getPropertyValue(propertyName, DeclarativeConfigProperties::getLong);
83+
}
84+
85+
@Nullable
86+
@Override
87+
public Double getDouble(String propertyName) {
88+
return getPropertyValue(propertyName, DeclarativeConfigProperties::getDouble);
89+
}
90+
91+
@Nullable
92+
@Override
93+
public Duration getDuration(String propertyName) {
94+
Long millis = getPropertyValue(propertyName, DeclarativeConfigProperties::getLong);
95+
if (millis == null) {
96+
return null;
97+
}
98+
return Duration.ofMillis(millis);
14599
}
146100

147-
// Extract the value by walking to the N-1 entry
148-
DeclarativeConfigProperties target = instrumentationJavaNode;
149-
if (segments.length > 1) {
150-
for (int i = 0; i < segments.length - 1; i++) {
151-
target = target.getStructured(segments[i], empty());
152-
}
101+
@Override
102+
public List<String> getList(String propertyName) {
103+
List<String> propertyValue =
104+
getPropertyValue(
105+
propertyName,
106+
(properties, lastPart) -> properties.getScalarList(lastPart, String.class));
107+
return propertyValue == null ? Collections.emptyList() : propertyValue;
153108
}
154-
String lastPart = segments[segments.length - 1];
155109

156-
return extractor.apply(target, lastPart);
157-
}
110+
@Override
111+
public Map<String, String> getMap(String propertyName) {
112+
DeclarativeConfigProperties propertyValue =
113+
getPropertyValue(propertyName, DeclarativeConfigProperties::getStructured);
114+
if (propertyValue == null) {
115+
return Collections.emptyMap();
116+
}
117+
Map<String, String> result = new HashMap<>();
118+
propertyValue
119+
.getPropertyKeys()
120+
.forEach(
121+
key -> {
122+
String value = propertyValue.getString(key);
123+
if (value == null) {
124+
return;
125+
}
126+
result.put(key, value);
127+
});
128+
return Collections.unmodifiableMap(result);
129+
}
130+
131+
@Nullable
132+
private <T> T getPropertyValue(
133+
String property, BiFunction<DeclarativeConfigProperties, String, T> extractor) {
134+
if (instrumentationJavaNode == null) {
135+
return null;
136+
}
137+
138+
String[] segments = getSegments(property);
139+
if (segments.length == 0) {
140+
return null;
141+
}
142+
143+
// Extract the value by walking to the N-1 entry
144+
DeclarativeConfigProperties target = instrumentationJavaNode;
145+
if (segments.length > 1) {
146+
for (int i = 0; i < segments.length - 1; i++) {
147+
target = target.getStructured(segments[i], empty());
148+
}
149+
}
150+
String lastPart = segments[segments.length - 1];
151+
152+
return extractor.apply(target, lastPart);
153+
}
154+
155+
private static String[] getSegments(String property) {
156+
if (property.startsWith(OTEL_INSTRUMENTATION_PREFIX)) {
157+
property = property.substring(OTEL_INSTRUMENTATION_PREFIX.length());
158+
}
159+
// Split the remainder of the property on "."
160+
return property.split("\\.");
161+
}
162+
163+
static String yamlPath(String property) {
164+
String[] segments = getSegments(property);
165+
if (segments.length == 0) {
166+
throw new IllegalArgumentException("Invalid property: " + property);
167+
}
168+
169+
return "'instrumentation/development' / 'java' / '" + String.join("' / '", segments) + "'";
170+
}
158171
}

gcp-auth-extension/src/main/java/io/opentelemetry/contrib/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,34 +124,38 @@ public int order() {
124124

125125
private static SpanExporter customizeSpanExporter(
126126
SpanExporter exporter, GoogleCredentials credentials, ConfigProperties configProperties) {
127-
if (isSignalTargeted(SIGNAL_TYPE_TRACES, configProperties)) {
127+
if (shouldConfigureExporter(SIGNAL_TYPE_TRACES, SIGNAL_TARGET_WARNING_FIX_SUGGESTION,
128+
configProperties)) {
128129
return addAuthorizationHeaders(exporter, credentials, configProperties);
129-
} else {
130-
String[] params = {SIGNAL_TYPE_TRACES, SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
131-
logger.log(
132-
Level.WARNING,
133-
"GCP Authentication Extension is not configured for signal type: {0}. {1}",
134-
params);
135130
}
136131
return exporter;
137132
}
138133

139134
private static MetricExporter customizeMetricExporter(
140135
MetricExporter exporter, GoogleCredentials credentials, ConfigProperties configProperties) {
141-
if (isSignalTargeted(SIGNAL_TYPE_METRICS, configProperties)) {
136+
if (shouldConfigureExporter(SIGNAL_TYPE_METRICS, SIGNAL_TARGET_WARNING_FIX_SUGGESTION,
137+
configProperties)) {
142138
return addAuthorizationHeaders(exporter, credentials, configProperties);
139+
}
140+
return exporter;
141+
}
142+
143+
static boolean shouldConfigureExporter(String signal,
144+
String fixSuggestion,
145+
ConfigProperties configProperties) {
146+
if (isSignalTargeted(signal, configProperties)) {
147+
return true;
143148
} else {
144-
String[] params = {SIGNAL_TYPE_METRICS, SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
145149
logger.log(
146150
Level.WARNING,
147151
"GCP Authentication Extension is not configured for signal type: {0}. {1}",
148-
params);
152+
new String[] {signal, fixSuggestion});
153+
return false;
149154
}
150-
return exporter;
151155
}
152156

153157
// Checks if the auth extension is configured to target the passed signal for authentication.
154-
static boolean isSignalTargeted(String checkSignal, ConfigProperties configProperties) {
158+
private static boolean isSignalTargeted(String checkSignal, ConfigProperties configProperties) {
155159
return
156160
targetSignals(configProperties).stream().anyMatch(
157161
targetedSignal ->

gcp-auth-extension/src/main/java/io/opentelemetry/contrib/gcp/auth/GcpAuthCustomizerProvider.java

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
package io.opentelemetry.contrib.gcp.auth;
77

8+
import static io.opentelemetry.contrib.gcp.auth.GcpAuthAutoConfigurationCustomizerProvider.SIGNAL_TYPE_METRICS;
89
import static io.opentelemetry.contrib.gcp.auth.GcpAuthAutoConfigurationCustomizerProvider.SIGNAL_TYPE_TRACES;
9-
import static io.opentelemetry.contrib.gcp.auth.GcpAuthAutoConfigurationCustomizerProvider.isSignalTargeted;
10+
import static io.opentelemetry.contrib.gcp.auth.GcpAuthAutoConfigurationCustomizerProvider.shouldConfigureExporter;
1011

1112
import com.google.auth.oauth2.GoogleCredentials;
1213
import com.google.auto.service.AutoService;
@@ -36,13 +37,12 @@
3637
@AutoService(DeclarativeConfigurationCustomizerProvider.class)
3738
public class GcpAuthCustomizerProvider implements DeclarativeConfigurationCustomizerProvider {
3839

39-
// private static final String SIGNAL_TARGET_WARNING_FIX_SUGGESTION =
40-
// String.format(
41-
// "You may safely ignore this warning if it is intentional, otherwise please configure the '%s' by exporting valid values to environment variable: %s or by setting valid values in system property: %s.",
42-
// ConfigurableOption.GOOGLE_OTEL_AUTH_TARGET_SIGNALS.getUserReadableName(),
43-
// ConfigurableOption.GOOGLE_OTEL_AUTH_TARGET_SIGNALS.getEnvironmentVariable(),
44-
// ConfigurableOption.GOOGLE_OTEL_AUTH_TARGET_SIGNALS.getSystemProperty());
45-
40+
static final String SIGNAL_TARGET_WARNING_FIX_SUGGESTION =
41+
String.format(
42+
"You may safely ignore this warning if it is intentional, otherwise please configure the '%s' by setting %s in the configuration file.",
43+
ConfigurableOption.GOOGLE_OTEL_AUTH_TARGET_SIGNALS.getUserReadableName(),
44+
ConfigPropertiesUtil.propertyYamlPath(
45+
ConfigurableOption.GOOGLE_OTEL_AUTH_TARGET_SIGNALS.getSystemProperty()));
4646

4747

4848
@Override
@@ -75,19 +75,12 @@ private static void customizeMeter(
7575
return;
7676
}
7777

78-
if (!isSignalTargeted(SIGNAL_TYPE_TRACES, configProperties)) {
79-
// todo
80-
// String[] params = {SIGNAL_TYPE_TRACES, SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
81-
// logger.log(
82-
// Level.WARNING,
83-
// "GCP Authentication Extension is not configured for signal type: {0}. {1}",
84-
// params);
85-
return;
86-
}
87-
88-
for (MetricReaderModel reader : meterProvider.getReaders()) {
89-
if (reader.getPeriodic() != null) {
90-
addAuth(meterModelHeaders(reader.getPeriodic().getExporter()), headerMap);
78+
if (shouldConfigureExporter(SIGNAL_TYPE_METRICS, SIGNAL_TARGET_WARNING_FIX_SUGGESTION,
79+
configProperties)) {
80+
for (MetricReaderModel reader : meterProvider.getReaders()) {
81+
if (reader.getPeriodic() != null) {
82+
addAuth(meterModelHeaders(reader.getPeriodic().getExporter()), headerMap);
83+
}
9184
}
9285
}
9386
}
@@ -117,26 +110,20 @@ private static void customizeTracer(
117110
return;
118111
}
119112

120-
if (!isSignalTargeted(SIGNAL_TYPE_TRACES, configProperties)) {
121-
// todo
122-
// String[] params = {SIGNAL_TYPE_TRACES, SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
123-
// logger.log(
124-
// Level.WARNING,
125-
// "GCP Authentication Extension is not configured for signal type: {0}. {1}",
126-
// params);
127-
return;
128-
}
129-
130-
for (SpanProcessorModel processor : tracerProvider.getProcessors()) {
131-
BatchSpanProcessorModel batch = processor.getBatch();
132-
if (batch != null) {
133-
addAuth(spanExporterModelHeaders(batch.getExporter()), headerMap);
134-
}
135-
SimpleSpanProcessorModel simple = processor.getSimple();
136-
if (simple != null) {
137-
addAuth(spanExporterModelHeaders(simple.getExporter()), headerMap);
113+
if (shouldConfigureExporter(SIGNAL_TYPE_TRACES, SIGNAL_TARGET_WARNING_FIX_SUGGESTION,
114+
configProperties)) {
115+
for (SpanProcessorModel processor : tracerProvider.getProcessors()) {
116+
BatchSpanProcessorModel batch = processor.getBatch();
117+
if (batch != null) {
118+
addAuth(spanExporterModelHeaders(batch.getExporter()), headerMap);
119+
}
120+
SimpleSpanProcessorModel simple = processor.getSimple();
121+
if (simple != null) {
122+
addAuth(spanExporterModelHeaders(simple.getExporter()), headerMap);
123+
}
138124
}
139125
}
126+
140127
}
141128

142129
private static List<List<NameStringValuePairModel>> spanExporterModelHeaders(

gcp-auth-extension/src/test/java/io/opentelemetry/contrib/gcp/auth/GcpAuthCustomizerProviderTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.opentelemetry.contrib.gcp.auth;
22

3+
import static io.opentelemetry.contrib.gcp.auth.GcpAuthCustomizerProvider.SIGNAL_TARGET_WARNING_FIX_SUGGESTION;
34
import static org.assertj.core.api.Assertions.assertThat;
45
import static org.mockito.Mockito.mock;
56
import static org.mockito.Mockito.when;
@@ -67,4 +68,14 @@ void declarativeConfig() throws IOException {
6768
// both metrics and traces should have the header
6869
assertThat(model.toString()).matches(String.format(".*%s.*%s.*", header, header));
6970
}
71+
72+
@Test
73+
void fixSuggestion() {
74+
assertThat(SIGNAL_TARGET_WARNING_FIX_SUGGESTION)
75+
.isEqualTo("You may safely ignore this warning if it is intentional, "
76+
+ "otherwise please configure the 'Target Signals for Google Authentication Extension' "
77+
+ "by setting "
78+
+ "'instrumentation/development' / 'java' / 'google' / 'otel' / 'auth' / 'target' / "
79+
+ "'signals' in the configuration file.");
80+
}
7081
}

0 commit comments

Comments
 (0)