Skip to content

Commit b4657a6

Browse files
authored
Merge pull request #1748 from alexliahushau/main
ISSUE-1660 Auto configuration for OpenTelemetry HTTP retry attributes
2 parents 46f6ef2 + 8359c4e commit b4657a6

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

riptide-spring-boot-autoconfigure/src/main/java/org/zalando/riptide/autoconfigure/OpenTelemetryPluginFactory.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,24 @@
22

33
import org.zalando.riptide.Plugin;
44
import org.zalando.riptide.opentelemetry.OpenTelemetryPlugin;
5+
import org.zalando.riptide.opentelemetry.span.RetrySpanDecorator;
6+
import org.zalando.riptide.opentelemetry.span.SpanDecorator;
57
import org.zalando.riptide.opentelemetry.span.StaticSpanDecorator;
68

9+
import java.util.ArrayList;
10+
import java.util.List;
11+
712
final class OpenTelemetryPluginFactory {
813
private OpenTelemetryPluginFactory() {
914

1015
}
1116

1217
public static Plugin create(final RiptideProperties.Client client) {
13-
StaticSpanDecorator decorator = new StaticSpanDecorator(client.getTelemetry().getAttributes());
14-
return new OpenTelemetryPlugin(decorator);
18+
final List<SpanDecorator> decorators = new ArrayList<>();
19+
decorators.add(new StaticSpanDecorator(client.getTelemetry().getAttributes()));
20+
if (client.getRetry().getEnabled()) {
21+
decorators.add(new RetrySpanDecorator());
22+
}
23+
return new OpenTelemetryPlugin(decorators.toArray(new SpanDecorator[0]));
1524
}
1625
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package org.zalando.riptide.autoconfigure;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.params.ParameterizedTest;
5+
import org.junit.jupiter.params.provider.CsvSource;
6+
import org.springframework.util.ReflectionUtils;
7+
import org.zalando.riptide.Plugin;
8+
import org.zalando.riptide.opentelemetry.OpenTelemetryPlugin;
9+
import org.zalando.riptide.opentelemetry.span.CompositeSpanDecorator;
10+
import org.zalando.riptide.opentelemetry.span.RetrySpanDecorator;
11+
import org.zalando.riptide.opentelemetry.span.SpanDecorator;
12+
13+
import java.lang.reflect.Field;
14+
import java.util.Map;
15+
import java.util.Optional;
16+
import java.util.stream.StreamSupport;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.junit.jupiter.api.Assertions.*;
20+
21+
public class OpenTelemetryPluginFactoryTest {
22+
23+
private static final Field SPAN_DECORATOR_FIELD = ReflectionUtils.findField(OpenTelemetryPlugin.class, "spanDecorator");
24+
private static final Field DECORATORS_FIELD = ReflectionUtils.findField(CompositeSpanDecorator.class, "decorators");
25+
26+
static {
27+
SPAN_DECORATOR_FIELD.setAccessible(true);
28+
DECORATORS_FIELD.setAccessible(true);
29+
}
30+
31+
@ParameterizedTest
32+
@CsvSource({
33+
"true, RetrySpanDecorator should be added when retry is enabled",
34+
"false, RetrySpanDecorator should not be added when retry is disabled"
35+
})
36+
void shouldCreatePluginWithRetrySpanDecoratorWhenClientRetryEnabled(
37+
final boolean isRetryEnabled,
38+
final String message
39+
) throws IllegalAccessException {
40+
final Plugin plugin = OpenTelemetryPluginFactory.create(createTestClient(isRetryEnabled));
41+
42+
assertNotNull(plugin);
43+
assertInstanceOf(OpenTelemetryPlugin.class, plugin);
44+
45+
final Optional<SpanDecorator> innerCompositeDecorator = StreamSupport.stream(
46+
((Iterable<SpanDecorator>) DECORATORS_FIELD.get(SPAN_DECORATOR_FIELD.get(plugin))).spliterator(), false
47+
).filter(decorator -> decorator instanceof CompositeSpanDecorator).findFirst();
48+
49+
assertThat(innerCompositeDecorator).isPresent();
50+
assertThat(
51+
StreamSupport.stream(
52+
((Iterable<SpanDecorator>) DECORATORS_FIELD.get(innerCompositeDecorator.get())).spliterator(), false
53+
).anyMatch(decorator -> decorator instanceof RetrySpanDecorator)
54+
).withFailMessage(message).isEqualTo(isRetryEnabled);
55+
}
56+
57+
@Test
58+
void shouldCreatePluginWithoutRetrySpanDecorator() throws IllegalAccessException {
59+
final Plugin plugin = OpenTelemetryPluginFactory.create(createTestClient(false));
60+
61+
assertNotNull(plugin);
62+
assertInstanceOf(OpenTelemetryPlugin.class, plugin);
63+
64+
final Optional<SpanDecorator> innerCompositeDecorator = StreamSupport.stream(
65+
((Iterable<SpanDecorator>) DECORATORS_FIELD.get(SPAN_DECORATOR_FIELD.get(plugin))).spliterator(), false
66+
).filter(decorator -> decorator instanceof CompositeSpanDecorator).findFirst();
67+
68+
assertThat(innerCompositeDecorator).isPresent();
69+
assertTrue(
70+
StreamSupport.stream(
71+
((Iterable<SpanDecorator>) DECORATORS_FIELD.get(innerCompositeDecorator.get())).spliterator(), false
72+
).noneMatch(decorator -> decorator instanceof RetrySpanDecorator),
73+
"RetrySpanDecorator should not be added when retry is disabled"
74+
);
75+
}
76+
77+
private static RiptideProperties.Client createTestClient(final boolean retryEnabled) {
78+
final RiptideProperties.Client client = new RiptideProperties.Client();
79+
final RiptideProperties.Telemetry telemetry = new RiptideProperties.Telemetry();
80+
telemetry.setAttributes(Map.of("service.name", "test-service"));
81+
client.setTelemetry(telemetry);
82+
83+
final RiptideProperties.Retry retry = new RiptideProperties.Retry();
84+
retry.setEnabled(retryEnabled);
85+
client.setRetry(retry);
86+
87+
return client;
88+
}
89+
90+
}

0 commit comments

Comments
 (0)