1
1
package datadog .trace .core .baggage ;
2
2
3
+ import static java .util .Collections .emptyMap ;
4
+
3
5
import datadog .context .Context ;
4
6
import datadog .context .propagation .CarrierSetter ;
5
7
import datadog .context .propagation .CarrierVisitor ;
6
8
import datadog .context .propagation .Propagator ;
7
9
import datadog .trace .api .Config ;
8
- import datadog .trace .bootstrap .instrumentation .api .BaggageContext ;
9
- import datadog .trace .core .util .EscapedData ;
10
+ import datadog .trace .bootstrap .instrumentation .api .Baggage ;
10
11
import datadog .trace .core .util .PercentEscaper ;
12
+ import datadog .trace .core .util .PercentEscaper .Escaped ;
11
13
import java .io .UnsupportedEncodingException ;
12
14
import java .net .URLDecoder ;
13
- import java .util .Collections ;
14
15
import java .util .HashMap ;
15
16
import java .util .Map ;
16
17
import java .util .function .BiConsumer ;
20
21
21
22
@ ParametersAreNonnullByDefault
22
23
public class BaggagePropagator implements Propagator {
23
- private static final Logger log = LoggerFactory .getLogger (BaggagePropagator .class );
24
+ private static final Logger LOG = LoggerFactory .getLogger (BaggagePropagator .class );
24
25
private static final PercentEscaper UTF_ESCAPER = PercentEscaper .create ();
25
26
static final String BAGGAGE_KEY = "baggage" ;
26
27
private final Config config ;
@@ -37,13 +38,13 @@ public BaggagePropagator(Config config) {
37
38
public BaggagePropagator (boolean injectBaggage , boolean extractBaggage ) {
38
39
this .injectBaggage = injectBaggage ;
39
40
this .extractBaggage = extractBaggage ;
40
- config = Config .get ();
41
+ this . config = Config .get ();
41
42
}
42
43
43
44
@ Override
44
45
public <C > void inject (Context context , C carrier , CarrierSetter <C > setter ) {
45
- int maxItems = config .getTraceBaggageMaxItems ();
46
- int maxBytes = config .getTraceBaggageMaxBytes ();
46
+ int maxItems = this . config .getTraceBaggageMaxItems ();
47
+ int maxBytes = this . config .getTraceBaggageMaxBytes ();
47
48
//noinspection ConstantValue
48
49
if (!this .injectBaggage
49
50
|| maxItems == 0
@@ -54,52 +55,52 @@ public <C> void inject(Context context, C carrier, CarrierSetter<C> setter) {
54
55
return ;
55
56
}
56
57
57
- BaggageContext baggageContext = BaggageContext .fromContext (context );
58
- if (baggageContext == null ) {
59
- log .debug ("BaggageContext instance is missing from the following context {}" , context );
58
+ Baggage baggage = Baggage .fromContext (context );
59
+ if (baggage == null ) {
60
+ LOG .debug ("Baggage instance is missing from the following context {}" , context );
60
61
return ;
61
62
}
62
63
63
- String baggageHeader = baggageContext . getW3cBaggageHeader ();
64
- if (baggageHeader != null ) {
65
- setter .set (carrier , BAGGAGE_KEY , baggageHeader );
64
+ String headerValue = baggage . getW3cHeader ();
65
+ if (headerValue != null ) {
66
+ setter .set (carrier , BAGGAGE_KEY , headerValue );
66
67
return ;
67
68
}
68
69
69
- int processedBaggage = 0 ;
70
+ int processedItems = 0 ;
70
71
int currentBytes = 0 ;
71
72
StringBuilder baggageText = new StringBuilder ();
72
- for (final Map .Entry <String , String > entry : baggageContext .asMap ().entrySet ()) {
73
+ for (final Map .Entry <String , String > entry : baggage .asMap ().entrySet ()) {
73
74
// if there are already baggage items processed, add and allocate bytes for a comma
74
75
int extraBytes = 1 ;
75
- if (processedBaggage != 0 ) {
76
+ if (processedItems != 0 ) {
76
77
baggageText .append (',' );
77
78
extraBytes ++;
78
79
}
79
80
80
- EscapedData escapedKey = UTF_ESCAPER .escapeKey (entry .getKey ());
81
- EscapedData escapedVal = UTF_ESCAPER .escapeValue (entry .getValue ());
81
+ Escaped escapedKey = UTF_ESCAPER .escapeKey (entry .getKey ());
82
+ Escaped escapedVal = UTF_ESCAPER .escapeValue (entry .getValue ());
82
83
83
- baggageText .append (escapedKey .getData () );
84
+ baggageText .append (escapedKey .data );
84
85
baggageText .append ('=' );
85
- baggageText .append (escapedVal .getData () );
86
+ baggageText .append (escapedVal .data );
86
87
87
- processedBaggage ++;
88
+ processedItems ++;
88
89
// reached the max number of baggage items allowed
89
- if (processedBaggage == maxItems ) {
90
+ if (processedItems == maxItems ) {
90
91
break ;
91
92
}
92
93
// Drop newest k/v pair if adding it leads to exceeding the limit
93
- if (currentBytes + escapedKey .getSize () + escapedVal .getSize () + extraBytes > maxBytes ) {
94
+ if (currentBytes + escapedKey .size + escapedVal .size + extraBytes > maxBytes ) {
94
95
baggageText .setLength (currentBytes );
95
96
break ;
96
97
}
97
- currentBytes += escapedKey .getSize () + escapedVal .getSize () + extraBytes ;
98
+ currentBytes += escapedKey .size + escapedVal .size + extraBytes ;
98
99
}
99
100
100
- String baggageString = baggageText .toString ();
101
- baggageContext . setW3cBaggageHeader ( baggageString );
102
- setter .set (carrier , BAGGAGE_KEY , baggageString );
101
+ headerValue = baggageText .toString ();
102
+ baggage . setW3cHeader ( headerValue );
103
+ setter .set (carrier , BAGGAGE_KEY , headerValue );
103
104
}
104
105
105
106
@ Override
@@ -108,57 +109,52 @@ public <C> Context extract(Context context, C carrier, CarrierVisitor<C> visitor
108
109
if (!this .extractBaggage || context == null || carrier == null || visitor == null ) {
109
110
return context ;
110
111
}
111
- BaggageContextExtractor baggageContextExtractor = new BaggageContextExtractor ();
112
- visitor .forEachKeyValue (carrier , baggageContextExtractor );
113
- BaggageContext extractedContext = baggageContextExtractor .extractedContext ;
114
- if (extractedContext == null ) {
115
- return context ;
116
- }
117
- return extractedContext .storeInto (context );
112
+ BaggageExtractor baggageExtractor = new BaggageExtractor ();
113
+ visitor .forEachKeyValue (carrier , baggageExtractor );
114
+ return baggageExtractor .extracted == null ? context : context .with (baggageExtractor .extracted );
118
115
}
119
116
120
- public static class BaggageContextExtractor implements BiConsumer <String , String > {
121
- private BaggageContext extractedContext ;
117
+ private static class BaggageExtractor implements BiConsumer <String , String > {
118
+ private static final char KEY_VALUE_SEPARATOR = '=' ;
119
+ private static final char PAIR_SEPARATOR = ',' ;
120
+ private Baggage extracted ;
122
121
123
- BaggageContextExtractor () {}
122
+ private BaggageExtractor () {}
124
123
125
124
/** URL decode value */
126
125
private String decode (final String value ) {
127
126
String decoded = value ;
128
127
try {
129
128
decoded = URLDecoder .decode (value , "UTF-8" );
130
129
} catch (final UnsupportedEncodingException | IllegalArgumentException e ) {
131
- log .debug ("Failed to decode {}" , value );
130
+ LOG .debug ("Failed to decode {}" , value );
132
131
}
133
132
return decoded ;
134
133
}
135
134
136
135
private Map <String , String > parseBaggageHeaders (String input ) {
137
136
Map <String , String > baggage = new HashMap <>();
138
- char keyValueSeparator = '=' ;
139
- char pairSeparator = ',' ;
140
137
int start = 0 ;
141
-
142
- int pairSeparatorInd = input .indexOf (pairSeparator );
138
+ int pairSeparatorInd = input .indexOf (PAIR_SEPARATOR );
143
139
pairSeparatorInd = pairSeparatorInd == -1 ? input .length () : pairSeparatorInd ;
144
- int kvSeparatorInd = input .indexOf (keyValueSeparator );
140
+ int kvSeparatorInd = input .indexOf (KEY_VALUE_SEPARATOR );
145
141
while (kvSeparatorInd != -1 ) {
146
142
int end = pairSeparatorInd ;
147
143
if (kvSeparatorInd > end ) {
148
- log .debug (
144
+ LOG .debug (
149
145
"Dropping baggage headers due to key with no value {}" , input .substring (start , end ));
150
- return Collections . emptyMap ();
146
+ return emptyMap ();
151
147
}
152
148
String key = decode (input .substring (start , kvSeparatorInd ).trim ());
153
149
String value = decode (input .substring (kvSeparatorInd + 1 , end ).trim ());
154
150
if (key .isEmpty () || value .isEmpty ()) {
155
- log .debug ("Dropping baggage headers due to empty k/v {}:{}" , key , value );
156
- return Collections . emptyMap ();
151
+ LOG .debug ("Dropping baggage headers due to empty k/v {}:{}" , key , value );
152
+ return emptyMap ();
157
153
}
158
154
baggage .put (key , value );
159
155
160
- kvSeparatorInd = input .indexOf (keyValueSeparator , pairSeparatorInd + 1 );
161
- pairSeparatorInd = input .indexOf (pairSeparator , pairSeparatorInd + 1 );
156
+ kvSeparatorInd = input .indexOf (KEY_VALUE_SEPARATOR , pairSeparatorInd + 1 );
157
+ pairSeparatorInd = input .indexOf (PAIR_SEPARATOR , pairSeparatorInd + 1 );
162
158
pairSeparatorInd = pairSeparatorInd == -1 ? input .length () : pairSeparatorInd ;
163
159
start = end + 1 ;
164
160
}
@@ -168,10 +164,10 @@ private Map<String, String> parseBaggageHeaders(String input) {
168
164
@ Override
169
165
public void accept (String key , String value ) {
170
166
// Only process tags that are relevant to baggage
171
- if (key != null && key .equalsIgnoreCase (BAGGAGE_KEY )) {
167
+ if (BAGGAGE_KEY .equalsIgnoreCase (key )) {
172
168
Map <String , String > baggage = parseBaggageHeaders (value );
173
169
if (!baggage .isEmpty ()) {
174
- extractedContext = BaggageContext .create (baggage , value );
170
+ this . extracted = Baggage .create (baggage , value );
175
171
}
176
172
}
177
173
}
0 commit comments