Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit 916adcb

Browse files
authored
Restrict access to context key, add helper methods to interact with Context. (#1864)
1 parent 1a82946 commit 916adcb

File tree

15 files changed

+167
-59
lines changed

15 files changed

+167
-59
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- Add Cumulative (`DoubleCumulative`, `LongCumulative`, `DerivedDoubleCumulative`, `DerivedLongCumulative`) APIs.
77
- Add convenience APIs `TagContextBuilder.putLocal()` that adds non-propagating tags,
88
and `TagContextBuilder.putPropagating()` that adds unlimited propagating tags.
9+
- Deprecate context keys for tags and spans. Provide helper methods for interacting with context.
910

1011
## 0.20.0 - 2019-03-28
1112
- Add OpenCensus Java OC-Agent Trace Exporter.

api/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,17 @@
1717
package io.opencensus.tags.unsafe;
1818

1919
import io.grpc.Context;
20+
import io.opencensus.internal.Utils;
2021
import io.opencensus.tags.Tag;
2122
import io.opencensus.tags.TagContext;
2223
import java.util.Collections;
2324
import java.util.Iterator;
2425
import javax.annotation.concurrent.Immutable;
2526

27+
/*>>>
28+
import org.checkerframework.checker.nullness.qual.Nullable;
29+
*/
30+
2631
/**
2732
* Utility methods for accessing the {@link TagContext} contained in the {@link io.grpc.Context}.
2833
*
@@ -41,10 +46,39 @@ private ContextUtils() {}
4146
* {@link io.grpc.Context}.
4247
*
4348
* @since 0.8
49+
* @deprecated from API since 0.21. Use {@link #withValue(Context, TagContext)} and {@link
50+
* #getValue(Context)} instead.
4451
*/
45-
public static final Context.Key<TagContext> TAG_CONTEXT_KEY =
52+
// TODO(songy23): make this private once gRPC migrates to use the alternative APIs.
53+
@Deprecated
54+
public static final Context.Key</*@Nullable*/ TagContext> TAG_CONTEXT_KEY =
4655
Context.keyWithDefault("opencensus-tag-context-key", EMPTY_TAG_CONTEXT);
4756

57+
/**
58+
* Creates a new {@code Context} with the given value set.
59+
*
60+
* @param context the parent {@code Context}.
61+
* @param tagContext the value to be set.
62+
* @return a new context with the given value set.
63+
* @since 0.21
64+
*/
65+
public static Context withValue(
66+
Context context, @javax.annotation.Nullable TagContext tagContext) {
67+
return Utils.checkNotNull(context, "context").withValue(TAG_CONTEXT_KEY, tagContext);
68+
}
69+
70+
/**
71+
* Returns the value from the specified {@code Context}.
72+
*
73+
* @param context the specified {@code Context}.
74+
* @return the value from the specified {@code Context}.
75+
* @since 0.21
76+
*/
77+
public static TagContext getValue(Context context) {
78+
@javax.annotation.Nullable TagContext tags = TAG_CONTEXT_KEY.get(context);
79+
return tags == null ? EMPTY_TAG_CONTEXT : tags;
80+
}
81+
4882
@Immutable
4983
private static final class EmptyTagContext extends TagContext {
5084

api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private CurrentSpanUtils() {}
3434
*/
3535
@Nullable
3636
static Span getCurrentSpan() {
37-
return ContextUtils.CONTEXT_SPAN_KEY.get();
37+
return ContextUtils.getValue(Context.current());
3838
}
3939

4040
/**
@@ -90,7 +90,7 @@ private static final class ScopeInSpan implements Scope {
9090
private ScopeInSpan(Span span, boolean endSpan) {
9191
this.span = span;
9292
this.endSpan = endSpan;
93-
origContext = Context.current().withValue(ContextUtils.CONTEXT_SPAN_KEY, span).attach();
93+
origContext = ContextUtils.withValue(Context.current(), span).attach();
9494
}
9595

9696
@Override
@@ -116,8 +116,7 @@ private RunnableInSpan(Span span, Runnable runnable, boolean endSpan) {
116116

117117
@Override
118118
public void run() {
119-
Context origContext =
120-
Context.current().withValue(ContextUtils.CONTEXT_SPAN_KEY, span).attach();
119+
Context origContext = ContextUtils.withValue(Context.current(), span).attach();
121120
try {
122121
runnable.run();
123122
} catch (Throwable t) {
@@ -150,8 +149,7 @@ private CallableInSpan(Span span, Callable<V> callable, boolean endSpan) {
150149

151150
@Override
152151
public V call() throws Exception {
153-
Context origContext =
154-
Context.current().withValue(ContextUtils.CONTEXT_SPAN_KEY, span).attach();
152+
Context origContext = ContextUtils.withValue(Context.current(), span).attach();
155153
try {
156154
return callable.call();
157155
} catch (Exception e) {

api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package io.opencensus.trace.unsafe;
1818

1919
import io.grpc.Context;
20+
import io.opencensus.internal.Utils;
21+
import io.opencensus.trace.BlankSpan;
2022
import io.opencensus.trace.Span;
2123

2224
/*>>>
@@ -39,7 +41,36 @@ private ContextUtils() {}
3941
* The {@link io.grpc.Context.Key} used to interact with {@link io.grpc.Context}.
4042
*
4143
* @since 0.5
44+
* @deprecated from API since 0.21. Use {@link #withValue(Context, Span)} and {@link
45+
* #getValue(Context)} instead.
4246
*/
47+
// TODO(songy23): make this private once gRPC migrates to use the alternative APIs.
48+
@Deprecated
4349
public static final Context.Key</*@Nullable*/ Span> CONTEXT_SPAN_KEY =
44-
Context.key("opencensus-trace-span-key");
50+
Context.<Span>key("opencensus-trace-span-key");
51+
52+
/**
53+
* Creates a new {@code Context} with the given value set.
54+
*
55+
* @param context the parent {@code Context}.
56+
* @param span the value to be set.
57+
* @return a new context with the given value set.
58+
* @since 0.21
59+
*/
60+
public static Context withValue(Context context, @javax.annotation.Nullable Span span) {
61+
return Utils.checkNotNull(context, "context").withValue(CONTEXT_SPAN_KEY, span);
62+
}
63+
64+
/**
65+
* Returns the value from the specified {@code Context}.
66+
*
67+
* @param context the specified {@code Context}.
68+
* @return the value from the specified {@code Context}.
69+
* @since 0.21
70+
*/
71+
public static Span getValue(Context context) {
72+
@javax.annotation.Nullable
73+
Span span = CONTEXT_SPAN_KEY.get(Utils.checkNotNull(context, "context"));
74+
return span == null ? BlankSpan.INSTANCE : span;
75+
}
4576
}

api/src/test/java/io/opencensus/tags/unsafe/ContextUtilsTest.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,19 @@
3131
/** Unit tests for {@link ContextUtils}. */
3232
@RunWith(JUnit4.class)
3333
public final class ContextUtilsTest {
34-
@Test
35-
public void testContextKeyName() {
36-
// Context.Key.toString() returns the name.
37-
assertThat(ContextUtils.TAG_CONTEXT_KEY.toString()).isEqualTo("opencensus-tag-context-key");
38-
}
3934

4035
@Test
4136
public void testGetCurrentTagContext_DefaultContext() {
42-
TagContext tags = ContextUtils.TAG_CONTEXT_KEY.get();
37+
TagContext tags = ContextUtils.getValue(Context.current());
4338
assertThat(tags).isNotNull();
4439
assertThat(asList(tags)).isEmpty();
4540
}
4641

4742
@Test
4843
public void testGetCurrentTagContext_ContextSetToNull() {
49-
Context orig = Context.current().withValue(ContextUtils.TAG_CONTEXT_KEY, null).attach();
44+
Context orig = ContextUtils.withValue(Context.current(), null).attach();
5045
try {
51-
TagContext tags = ContextUtils.TAG_CONTEXT_KEY.get();
46+
TagContext tags = ContextUtils.getValue(Context.current());
5247
assertThat(tags).isNotNull();
5348
assertThat(asList(tags)).isEmpty();
5449
} finally {

api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,51 +68,51 @@ private void executeCallableAndExpectError(Callable<Object> callable, Throwable
6868

6969
@Test
7070
public void getCurrentSpan_WhenNoContext() {
71-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
71+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
7272
}
7373

7474
@Test
7575
public void getCurrentSpan() {
76-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
77-
Context origContext = Context.current().withValue(ContextUtils.CONTEXT_SPAN_KEY, span).attach();
76+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
77+
Context origContext = ContextUtils.withValue(Context.current(), span).attach();
7878
// Make sure context is detached even if test fails.
7979
try {
8080
assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span);
8181
} finally {
8282
Context.current().detach(origContext);
8383
}
84-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
84+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
8585
}
8686

8787
@Test
8888
public void withSpan_CloseDetaches() {
89-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
89+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
9090
Scope ws = CurrentSpanUtils.withSpan(span, false);
9191
try {
9292
assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span);
9393
} finally {
9494
ws.close();
9595
}
96-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
96+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
9797
verifyZeroInteractions(span);
9898
}
9999

100100
@Test
101101
public void withSpan_CloseDetachesAndEndsSpan() {
102-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
102+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
103103
Scope ss = CurrentSpanUtils.withSpan(span, true);
104104
try {
105105
assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span);
106106
} finally {
107107
ss.close();
108108
}
109-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
109+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
110110
verify(span).end(same(EndSpanOptions.DEFAULT));
111111
}
112112

113113
@Test
114114
public void withSpanRunnable() {
115-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
115+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
116116
Runnable runnable =
117117
new Runnable() {
118118
@Override
@@ -123,12 +123,12 @@ public void run() {
123123
};
124124
CurrentSpanUtils.withSpan(span, false, runnable).run();
125125
verifyZeroInteractions(span);
126-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
126+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
127127
}
128128

129129
@Test
130130
public void withSpanRunnable_EndSpan() {
131-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
131+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
132132
Runnable runnable =
133133
new Runnable() {
134134
@Override
@@ -139,13 +139,13 @@ public void run() {
139139
};
140140
CurrentSpanUtils.withSpan(span, true, runnable).run();
141141
verify(span).end(EndSpanOptions.DEFAULT);
142-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
142+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
143143
}
144144

145145
@Test
146146
public void withSpanRunnable_WithError() {
147147
final AssertionError error = new AssertionError("MyError");
148-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
148+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
149149
Runnable runnable =
150150
new Runnable() {
151151
@Override
@@ -158,13 +158,13 @@ public void run() {
158158
executeRunnableAndExpectError(runnable, error);
159159
verify(span).setStatus(Status.UNKNOWN.withDescription("MyError"));
160160
verify(span).end(EndSpanOptions.DEFAULT);
161-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
161+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
162162
}
163163

164164
@Test
165165
public void withSpanRunnable_WithErrorNoMessage() {
166166
final AssertionError error = new AssertionError();
167-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
167+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
168168
Runnable runnable =
169169
new Runnable() {
170170
@Override
@@ -177,13 +177,13 @@ public void run() {
177177
executeRunnableAndExpectError(runnable, error);
178178
verify(span).setStatus(Status.UNKNOWN.withDescription("AssertionError"));
179179
verify(span).end(EndSpanOptions.DEFAULT);
180-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
180+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
181181
}
182182

183183
@Test
184184
public void withSpanCallable() throws Exception {
185185
final Object ret = new Object();
186-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
186+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
187187
Callable<Object> callable =
188188
new Callable<Object>() {
189189
@Override
@@ -195,13 +195,13 @@ public Object call() throws Exception {
195195
};
196196
assertThat(CurrentSpanUtils.withSpan(span, false, callable).call()).isEqualTo(ret);
197197
verifyZeroInteractions(span);
198-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
198+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
199199
}
200200

201201
@Test
202202
public void withSpanCallable_EndSpan() throws Exception {
203203
final Object ret = new Object();
204-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
204+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
205205
Callable<Object> callable =
206206
new Callable<Object>() {
207207
@Override
@@ -213,13 +213,13 @@ public Object call() throws Exception {
213213
};
214214
assertThat(CurrentSpanUtils.withSpan(span, true, callable).call()).isEqualTo(ret);
215215
verify(span).end(EndSpanOptions.DEFAULT);
216-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
216+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
217217
}
218218

219219
@Test
220220
public void withSpanCallable_WithException() {
221221
final Exception exception = new Exception("MyException");
222-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
222+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
223223
Callable<Object> callable =
224224
new Callable<Object>() {
225225
@Override
@@ -232,13 +232,13 @@ public Object call() throws Exception {
232232
executeCallableAndExpectError(callable, exception);
233233
verify(span).setStatus(Status.UNKNOWN.withDescription("MyException"));
234234
verify(span).end(EndSpanOptions.DEFAULT);
235-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
235+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
236236
}
237237

238238
@Test
239239
public void withSpanCallable_WithExceptionNoMessage() {
240240
final Exception exception = new Exception();
241-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
241+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
242242
Callable<Object> callable =
243243
new Callable<Object>() {
244244
@Override
@@ -251,13 +251,13 @@ public Object call() throws Exception {
251251
executeCallableAndExpectError(callable, exception);
252252
verify(span).setStatus(Status.UNKNOWN.withDescription("Exception"));
253253
verify(span).end(EndSpanOptions.DEFAULT);
254-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
254+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
255255
}
256256

257257
@Test
258258
public void withSpanCallable_WithError() {
259259
final AssertionError error = new AssertionError("MyError");
260-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
260+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
261261
Callable<Object> callable =
262262
new Callable<Object>() {
263263
@Override
@@ -270,13 +270,13 @@ public Object call() throws Exception {
270270
executeCallableAndExpectError(callable, error);
271271
verify(span).setStatus(Status.UNKNOWN.withDescription("MyError"));
272272
verify(span).end(EndSpanOptions.DEFAULT);
273-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
273+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
274274
}
275275

276276
@Test
277277
public void withSpanCallable_WithErrorNoMessage() {
278278
final AssertionError error = new AssertionError();
279-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
279+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
280280
Callable<Object> callable =
281281
new Callable<Object>() {
282282
@Override
@@ -289,6 +289,6 @@ public Object call() throws Exception {
289289
executeCallableAndExpectError(callable, error);
290290
verify(span).setStatus(Status.UNKNOWN.withDescription("AssertionError"));
291291
verify(span).end(EndSpanOptions.DEFAULT);
292-
assertThat(CurrentSpanUtils.getCurrentSpan()).isNull();
292+
assertThat(CurrentSpanUtils.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE);
293293
}
294294
}

0 commit comments

Comments
 (0)