Skip to content

Commit 41e2d51

Browse files
committed
feat(context): Add non default propagator registration
1 parent d3cfbcb commit 41e2d51

File tree

4 files changed

+72
-13
lines changed

4 files changed

+72
-13
lines changed

components/context/src/main/java/datadog/context/SingletonContext.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,9 @@ public int hashCode() {
5757
result = 31 * result + Objects.hashCode(this.value);
5858
return result;
5959
}
60+
61+
@Override
62+
public String toString() {
63+
return "SingletonContext{" + "index=" + this.index + ", value=" + this.value + '}';
64+
}
6065
}
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package datadog.context.propagation;
22

3-
import javax.annotation.Nullable;
4-
53
@FunctionalInterface
64
public interface CarrierSetter<C> {
75
/**
@@ -11,5 +9,5 @@ public interface CarrierSetter<C> {
119
* @param key the key to set.
1210
* @param value the value to set.
1311
*/
14-
void set(@Nullable C carrier, String key, String value);
12+
void set(C carrier, String key, String value);
1513
}

components/context/src/main/java/datadog/context/propagation/Propagators.java

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
package datadog.context.propagation;
22

3+
import static datadog.context.propagation.Propagators.RegisteredPropagator.of;
34
import static java.util.Collections.synchronizedMap;
45
import static java.util.Comparator.comparingInt;
56

67
import java.util.IdentityHashMap;
78
import java.util.Map;
89

10+
/**
11+
* This class is the entrypoint of the context propagation API allowing to retrieve the {@link
12+
* Propagator} to use.
13+
*/
914
public final class Propagators {
10-
private static final Map<Concern, Propagator> PROPAGATORS =
15+
private static final Map<Concern, RegisteredPropagator> PROPAGATORS =
1116
synchronizedMap(new IdentityHashMap<>());
17+
private static final RegisteredPropagator NOOP = of(NoopPropagator.INSTANCE, false);
1218
private static volatile Propagator defaultPropagator = null;
1319
private static volatile boolean defaultPropagatorSet = false;
1420

@@ -23,8 +29,10 @@ public static Propagator defaultPropagator() {
2329
if (!defaultPropagatorSet) {
2430
Propagator[] propagatorsByPriority =
2531
PROPAGATORS.entrySet().stream()
32+
.filter(entry -> entry.getValue().isUsedAsDefault())
2633
.sorted(comparingInt(entry -> entry.getKey().priority()))
2734
.map(Map.Entry::getValue)
35+
.map(RegisteredPropagator::propagator)
2836
.toArray(Propagator[]::new);
2937
defaultPropagator = composite(propagatorsByPriority);
3038
defaultPropagatorSet = true;
@@ -39,7 +47,7 @@ public static Propagator defaultPropagator() {
3947
* @return the related propagator if registered, a {@link #noop()} propagator otherwise.
4048
*/
4149
public static Propagator forConcern(Concern concern) {
42-
return PROPAGATORS.getOrDefault(concern, NoopPropagator.INSTANCE);
50+
return PROPAGATORS.getOrDefault(concern, NOOP).propagator();
4351
}
4452

4553
/**
@@ -89,13 +97,49 @@ public static Propagator composite(Propagator... propagators) {
8997
* @param propagator The propagator to register.
9098
*/
9199
public static void register(Concern concern, Propagator propagator) {
92-
PROPAGATORS.put(concern, propagator);
93-
defaultPropagatorSet = false;
100+
register(concern, propagator, true);
101+
}
102+
103+
/**
104+
* Registers a propagator for concern.
105+
*
106+
* @param concern The concern to register a propagator for.
107+
* @param propagator The propagator to register.
108+
* @param usedAsDefault Whether the propagator should be used as default propagator.
109+
* @see Propagators#defaultPropagator()
110+
*/
111+
public static void register(Concern concern, Propagator propagator, boolean usedAsDefault) {
112+
PROPAGATORS.put(concern, of(propagator, usedAsDefault));
113+
if (usedAsDefault) {
114+
defaultPropagatorSet = false;
115+
}
94116
}
95117

96118
/** Clear all registered propagators. For testing purpose only. */
97119
static void reset() {
98120
PROPAGATORS.clear();
99121
defaultPropagatorSet = false;
100122
}
123+
124+
static class RegisteredPropagator {
125+
private final Propagator propagator;
126+
private final boolean usedAsDefault;
127+
128+
private RegisteredPropagator(Propagator propagator, boolean usedAsDefault) {
129+
this.propagator = propagator;
130+
this.usedAsDefault = usedAsDefault;
131+
}
132+
133+
static RegisteredPropagator of(Propagator propagator, boolean useAsDefault) {
134+
return new RegisteredPropagator(propagator, useAsDefault);
135+
}
136+
137+
protected Propagator propagator() {
138+
return this.propagator;
139+
}
140+
141+
boolean isUsedAsDefault() {
142+
return this.usedAsDefault;
143+
}
144+
}
101145
}

components/context/src/test/java/datadog/context/propagation/PropagatorsTest.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
import static org.junit.jupiter.api.Assertions.assertEquals;
77
import static org.junit.jupiter.api.Assertions.assertFalse;
88
import static org.junit.jupiter.api.Assertions.assertNotNull;
9+
import static org.junit.jupiter.api.Assertions.assertNull;
910
import static org.junit.jupiter.api.Assertions.assertTrue;
1011

1112
import datadog.context.Context;
1213
import datadog.context.ContextKey;
1314
import java.util.HashMap;
1415
import java.util.Map;
1516
import java.util.function.BiConsumer;
16-
import javax.annotation.Nullable;
17+
import javax.annotation.ParametersAreNonnullByDefault;
1718
import org.junit.jupiter.api.AfterEach;
1819
import org.junit.jupiter.api.BeforeEach;
1920
import org.junit.jupiter.api.Test;
@@ -46,11 +47,12 @@ class PropagatorsTest {
4647
.with(DEBUGGER_KEY, "debug")
4748
.with(PROFILING_KEY, "profile");
4849

50+
@ParametersAreNonnullByDefault
4951
static class MapCarrierAccessor
5052
implements CarrierSetter<Map<String, String>>, CarrierVisitor<Map<String, String>> {
5153
@Override
52-
public void set(@Nullable Map<String, String> carrier, String key, String value) {
53-
if (carrier != null && key != null) {
54+
public void set(Map<String, String> carrier, String key, String value) {
55+
if (carrier != null && key != null && value != null) {
5456
carrier.put(key, value);
5557
}
5658
}
@@ -136,12 +138,12 @@ void testDefaultPropagator() {
136138
Propagator single = Propagators.defaultPropagator();
137139
assertInjectExtractContext(CONTEXT, single, TRACING_KEY);
138140

139-
Propagators.register(IAST, IAST_PROPAGATOR);
141+
Propagators.register(IAST, IAST_PROPAGATOR, false);
140142
Propagators.register(DEBUGGER, DEBUGGER_PROPAGATOR);
141143
Propagators.register(PROFILING, PROFILING_PROPAGATOR);
142144
Propagator composite = Propagators.defaultPropagator();
143-
assertInjectExtractContext(
144-
CONTEXT, composite, TRACING_KEY, IAST_KEY, DEBUGGER_KEY, PROFILING_KEY);
145+
assertDoNotInjectExtractContext(CONTEXT, composite, IAST_KEY);
146+
assertInjectExtractContext(CONTEXT, composite, TRACING_KEY, DEBUGGER_KEY, PROFILING_KEY);
145147
assertFalse(
146148
DEBUGGER_PROPAGATOR.keyFound,
147149
"Debugger propagator should have run before tracing propagator");
@@ -219,4 +221,14 @@ void assertInjectExtractContext(Context context, Propagator propagator, ContextK
219221
context.get(key), extracted.get(key), "Key " + key + " not injected nor extracted");
220222
}
221223
}
224+
225+
private void assertDoNotInjectExtractContext(
226+
Context context, Propagator propagator, ContextKey<?>... keys) {
227+
Map<String, String> carrier = new HashMap<>();
228+
propagator.inject(context, carrier, ACCESSOR);
229+
Context extracted = propagator.extract(root(), carrier, ACCESSOR);
230+
for (ContextKey<?> key : keys) {
231+
assertNull(extracted.get(key), "Key " + key + " was injected");
232+
}
233+
}
222234
}

0 commit comments

Comments
 (0)