2727import io .grpc .ServerCallHandler ;
2828import io .grpc .ServerInterceptor ;
2929import io .grpc .Status ;
30+ import io .opentelemetry .api .GlobalOpenTelemetry ;
31+ import io .opentelemetry .api .common .AttributeKey ;
32+ import io .opentelemetry .api .trace .propagation .W3CTraceContextPropagator ;
33+ import io .opentelemetry .context .propagation .ContextPropagators ;
34+ import io .opentelemetry .sdk .OpenTelemetrySdk ;
35+ import io .opentelemetry .sdk .testing .exporter .InMemorySpanExporter ;
36+ import io .opentelemetry .sdk .trace .SdkTracerProvider ;
37+ import io .opentelemetry .sdk .trace .data .SpanData ;
38+ import io .opentelemetry .sdk .trace .export .SimpleSpanProcessor ;
3039import java .util .ArrayList ;
3140import java .util .List ;
3241import java .util .Map ;
3544import java .util .concurrent .ConcurrentHashMap ;
3645import java .util .concurrent .CopyOnWriteArrayList ;
3746import java .util .regex .Matcher ;
47+ import org .junit .AfterClass ;
48+ import org .junit .BeforeClass ;
3849import org .junit .Test ;
3950import org .junit .runner .RunWith ;
4051import org .junit .runners .JUnit4 ;
@@ -68,6 +79,13 @@ public static class ServerHeaderEnforcer implements ServerInterceptor {
6879 private Map <String , CopyOnWriteArrayList <XGoogSpannerRequestId >> streamingResults ;
6980 private List <String > gotValues ;
7081 private Set <String > checkMethods ;
82+ private static InMemorySpanExporter spanExporter ;
83+ private static OpenTelemetrySdk openTelemetry ;
84+
85+ // This variable when set to true will allow checking for span
86+ // attributes like `x_goog_spanner_request_id`, of which that
87+ // requires considerable plumbing in this package.
88+ private static final boolean ENABLED_USER_DEFINED_TRACES = false ;
7189
7290 ServerHeaderEnforcer (Set <String > checkMethods ) {
7391 this .gotValues = new CopyOnWriteArrayList <String >();
@@ -76,6 +94,38 @@ public static class ServerHeaderEnforcer implements ServerInterceptor {
7694 this .streamingResults =
7795 new ConcurrentHashMap <String , CopyOnWriteArrayList <XGoogSpannerRequestId >>();
7896 this .checkMethods = checkMethods ;
97+ ServerHeaderEnforcer .setupOpenTelemetry ();
98+ }
99+
100+ @ BeforeClass
101+ public static void setupOpenTelemetry () {
102+ SpannerOptions .resetActiveTracingFramework ();
103+ SpannerOptions .enableOpenTelemetryTraces ();
104+ GlobalOpenTelemetry .resetForTest ();
105+
106+ spanExporter = InMemorySpanExporter .create ();
107+
108+ SdkTracerProvider tracerProvider =
109+ SdkTracerProvider .builder ()
110+ .addSpanProcessor (SimpleSpanProcessor .create (spanExporter ))
111+ .build ();
112+
113+ openTelemetry =
114+ OpenTelemetrySdk .builder ()
115+ .setPropagators (ContextPropagators .create (W3CTraceContextPropagator .getInstance ()))
116+ .setTracerProvider (tracerProvider )
117+ .buildAndRegisterGlobal ();
118+ }
119+
120+ @ AfterClass
121+ public static void closeOpenTelemetry () {
122+ if (openTelemetry != null ) {
123+ openTelemetry .close ();
124+ }
125+ }
126+
127+ public List <SpanData > getFinishedSpans () {
128+ return this .spanExporter .getFinishedSpanItems ();
79129 }
80130
81131 @ Override
@@ -108,6 +158,15 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
108158 // Firstly assert and validate that at least we've got a requestId.
109159 Matcher m = XGoogSpannerRequestId .REGEX .matcher (gotReqIdStr );
110160 assertTrue (m .matches ());
161+ if (ENABLED_USER_DEFINED_TRACES ) {
162+ List <SpanData > spans = this .getFinishedSpans ();
163+ assertNotNull (spans );
164+ SpanData span = spans .get (0 );
165+ String gotReqIdFromSpanAttribute =
166+ span .getAttributes ().get (AttributeKey .stringKey ("x_goog_spanner_request_id" ));
167+ assertNotNull (gotReqIdFromSpanAttribute );
168+ assertEquals (gotReqIdStr , gotReqIdFromSpanAttribute );
169+ }
111170
112171 XGoogSpannerRequestId reqId = XGoogSpannerRequestId .of (gotReqIdStr );
113172 if (!saver .containsKey (methodName )) {
0 commit comments