88import  com .google .errorprone .annotations .CanIgnoreReturnValue ;
99import  io .opentelemetry .api .OpenTelemetry ;
1010import  io .opentelemetry .context .propagation .TextMapGetter ;
11+ import  io .opentelemetry .instrumentation .api .incubator .config .internal .CoreCommonConfig ;
1112import  io .opentelemetry .instrumentation .api .incubator .semconv .http .HttpExperimentalAttributesExtractor ;
1213import  io .opentelemetry .instrumentation .api .incubator .semconv .http .HttpServerExperimentalMetrics ;
1314import  io .opentelemetry .instrumentation .api .instrumenter .AttributesExtractor ;
2526import  io .opentelemetry .instrumentation .api .semconv .http .HttpSpanNameExtractor ;
2627import  io .opentelemetry .instrumentation .api .semconv .http .HttpSpanNameExtractorBuilder ;
2728import  io .opentelemetry .instrumentation .api .semconv .http .HttpSpanStatusExtractor ;
29+ import  java .lang .reflect .Field ;
2830import  java .util .ArrayList ;
2931import  java .util .List ;
30- import  java .util .Optional ;
3132import  java .util .Set ;
3233import  java .util .function .Consumer ;
3334import  java .util .function .Function ;
35+ import  java .util .function .Supplier ;
36+ import  javax .annotation .Nullable ;
3437
3538/** 
3639 * This class is internal and is hence not for public use. Its APIs are unstable and can change at 
3740 * any time. 
3841 */ 
39- public  final  class  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE > {
42+ public  final  class  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > {
4043
4144  private  final  String  instrumentationName ;
4245  private  final  OpenTelemetry  openTelemetry ;
@@ -50,40 +53,39 @@ public final class DefaultHttpServerTelemetryBuilder<REQUEST, RESPONSE> {
5053  private  final  HttpServerAttributesExtractorBuilder <REQUEST , RESPONSE >
5154      httpAttributesExtractorBuilder ;
5255  private  final  HttpSpanNameExtractorBuilder <REQUEST > httpSpanNameExtractorBuilder ;
56+ 
57+   @ Nullable  private  TextMapGetter <REQUEST > headerGetter ;
5358  private  Function <SpanNameExtractor <REQUEST >, ? extends  SpanNameExtractor <? super  REQUEST >>
5459      spanNameExtractorTransformer  = Function .identity ();
5560  private  final  HttpServerRouteBuilder <REQUEST > httpServerRouteBuilder ;
5661  private  final  HttpServerAttributesGetter <REQUEST , RESPONSE > attributesGetter ;
57-   private  final  Optional <TextMapGetter <REQUEST >> headerSetter ;
5862  private  boolean  emitExperimentalHttpServerMetrics  = false ;
5963
60-   public  DefaultHttpServerTelemetryBuilder (
64+   public  DefaultHttpServerInstrumenterBuilder (
6165      String  instrumentationName ,
6266      OpenTelemetry  openTelemetry ,
63-       HttpServerAttributesGetter <REQUEST , RESPONSE > attributesGetter ,
64-       Optional <TextMapGetter <REQUEST >> headerSetter ) {
67+       HttpServerAttributesGetter <REQUEST , RESPONSE > attributesGetter ) {
6568    this .instrumentationName  = instrumentationName ;
6669    this .openTelemetry  = openTelemetry ;
6770    httpAttributesExtractorBuilder  = HttpServerAttributesExtractor .builder (attributesGetter );
6871    httpSpanNameExtractorBuilder  = HttpSpanNameExtractor .builder (attributesGetter );
6972    httpServerRouteBuilder  = HttpServerRoute .builder (attributesGetter );
7073    this .attributesGetter  = attributesGetter ;
71-     this .headerSetter  = headerSetter ;
7274  }
7375
7476  /** 
7577   * Adds an additional {@link AttributesExtractor} to invoke to set attributes to instrumented 
7678   * items. 
7779   */ 
7880  @ CanIgnoreReturnValue 
79-   public  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE > addAttributesExtractor (
81+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > addAttributesExtractor (
8082      AttributesExtractor <? super  REQUEST , ? super  RESPONSE > attributesExtractor ) {
8183    additionalExtractors .add (attributesExtractor );
8284    return  this ;
8385  }
8486
8587  @ CanIgnoreReturnValue 
86-   public  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE > setStatusExtractor (
88+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > setStatusExtractor (
8789      Function <
8890              SpanStatusExtractor <? super  REQUEST , ? super  RESPONSE >,
8991              ? extends  SpanStatusExtractor <? super  REQUEST , ? super  RESPONSE >>
@@ -98,7 +100,7 @@ public DefaultHttpServerTelemetryBuilder<REQUEST, RESPONSE> setStatusExtractor(
98100   * @param requestHeaders A list of HTTP header names. 
99101   */ 
100102  @ CanIgnoreReturnValue 
101-   public  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE > setCapturedRequestHeaders (
103+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > setCapturedRequestHeaders (
102104      List <String > requestHeaders ) {
103105    httpAttributesExtractorBuilder .setCapturedRequestHeaders (requestHeaders );
104106    return  this ;
@@ -110,7 +112,7 @@ public DefaultHttpServerTelemetryBuilder<REQUEST, RESPONSE> setCapturedRequestHe
110112   * @param responseHeaders A list of HTTP header names. 
111113   */ 
112114  @ CanIgnoreReturnValue 
113-   public  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE > setCapturedResponseHeaders (
115+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > setCapturedResponseHeaders (
114116      List <String > responseHeaders ) {
115117    httpAttributesExtractorBuilder .setCapturedResponseHeaders (responseHeaders );
116118    return  this ;
@@ -130,54 +132,60 @@ public DefaultHttpServerTelemetryBuilder<REQUEST, RESPONSE> setCapturedResponseH
130132   * @see HttpServerAttributesExtractorBuilder#setKnownMethods(Set) 
131133   */ 
132134  @ CanIgnoreReturnValue 
133-   public  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE > setKnownMethods (
135+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > setKnownMethods (
134136      Set <String > knownMethods ) {
135137    httpAttributesExtractorBuilder .setKnownMethods (knownMethods );
136138    httpSpanNameExtractorBuilder .setKnownMethods (knownMethods );
137139    httpServerRouteBuilder .setKnownMethods (knownMethods );
138140    return  this ;
139141  }
140142
143+   @ CanIgnoreReturnValue 
144+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > setHeaderGetter (
145+       @ Nullable  TextMapGetter <REQUEST > headerGetter ) {
146+     this .headerGetter  = headerGetter ;
147+     return  this ;
148+   }
149+ 
141150  /** 
142151   * Configures the instrumentation to emit experimental HTTP server metrics. 
143152   * 
144153   * @param emitExperimentalHttpServerMetrics {@code true} if the experimental HTTP server metrics 
145154   *     are to be emitted. 
146155   */ 
147156  @ CanIgnoreReturnValue 
148-   public  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE >  setEmitExperimentalHttpServerMetrics ( 
149-       boolean  emitExperimentalHttpServerMetrics ) {
157+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE >
158+       setEmitExperimentalHttpServerMetrics ( boolean  emitExperimentalHttpServerMetrics ) {
150159    this .emitExperimentalHttpServerMetrics  = emitExperimentalHttpServerMetrics ;
151160    return  this ;
152161  }
153162
154163  /** Sets custom {@link SpanNameExtractor} via transform function. */ 
155164  @ CanIgnoreReturnValue 
156-   public  DefaultHttpServerTelemetryBuilder <REQUEST , RESPONSE > setSpanNameExtractor (
165+   public  DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > setSpanNameExtractor (
157166      Function <SpanNameExtractor <REQUEST >, ? extends  SpanNameExtractor <? super  REQUEST >>
158167          spanNameExtractorTransformer ) {
159168    this .spanNameExtractorTransformer  = spanNameExtractorTransformer ;
160169    return  this ;
161170  }
162171
163-   public  Instrumenter <REQUEST , RESPONSE > instrumenter () {
164-     return  instrumenter (b  -> {});
172+   public  Instrumenter <REQUEST , RESPONSE > build () {
173+     return  build (b  -> {});
165174  }
166175
167-   public  Instrumenter <REQUEST , RESPONSE > instrumenter (
176+   public  Instrumenter <REQUEST , RESPONSE > build (
168177      Consumer <InstrumenterBuilder <REQUEST , RESPONSE >> instrumenterBuilderConsumer ) {
169178
170-     InstrumenterBuilder <REQUEST , RESPONSE > builder  =
171-          instrumenterBuilder ( instrumenterBuilderConsumer );
179+     InstrumenterBuilder <REQUEST , RESPONSE > builder  =  builder (); 
180+     instrumenterBuilderConsumer . accept ( builder );
172181
173-     if  (headerSetter . isPresent () ) {
174-       return  builder .buildServerInstrumenter (headerSetter . get () );
182+     if  (headerGetter  !=  null ) {
183+       return  builder .buildServerInstrumenter (headerGetter );
175184    }
176185    return  builder .buildInstrumenter (SpanKindExtractor .alwaysServer ());
177186  }
178187
179-   public  InstrumenterBuilder <REQUEST , RESPONSE > instrumenterBuilder (
180-       Consumer <InstrumenterBuilder <REQUEST , RESPONSE >> instrumenterBuilderConsumer ) {
188+   public  InstrumenterBuilder <REQUEST , RESPONSE > builder () {
181189    SpanNameExtractor <? super  REQUEST > spanNameExtractor  =
182190        spanNameExtractorTransformer .apply (httpSpanNameExtractorBuilder .build ());
183191
@@ -196,11 +204,51 @@ public InstrumenterBuilder<REQUEST, RESPONSE> instrumenterBuilder(
196204          .addOperationMetrics (HttpServerExperimentalMetrics .get ());
197205    }
198206
199-     instrumenterBuilderConsumer .accept (builder );
200207    return  builder ;
201208  }
202209
203210  public  OpenTelemetry  getOpenTelemetry () {
204211    return  openTelemetry ;
205212  }
213+ 
214+   @ CanIgnoreReturnValue 
215+   public  static  <REQUEST , RESPONSE >
216+       DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > unwrapAndConfigure (
217+           CoreCommonConfig  config , Object  builder ) {
218+     DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > defaultBuilder  = unwrapBuilder (builder );
219+     set (config ::getKnownHttpRequestMethods , defaultBuilder ::setKnownMethods );
220+     set (config ::getServerRequestHeaders , defaultBuilder ::setCapturedRequestHeaders );
221+     set (config ::getServerResponseHeaders , defaultBuilder ::setCapturedResponseHeaders );
222+     set (
223+         config ::shouldEmitExperimentalHttpServerTelemetry ,
224+         defaultBuilder ::setEmitExperimentalHttpServerMetrics );
225+     return  defaultBuilder ;
226+   }
227+ 
228+   private  static  <T > void  set (Supplier <T > supplier , Consumer <T > consumer ) {
229+     T  t  = supplier .get ();
230+     if  (t  != null ) {
231+       consumer .accept (t );
232+     }
233+   }
234+ 
235+   /** 
236+    * This method is used to access the builder field of the builder object. 
237+    * 
238+    * <p>This approach allows us to re-use the existing builder classes from the library modules 
239+    */ 
240+   @ SuppressWarnings ("unchecked" )
241+   private  static  <REQUEST , RESPONSE >
242+       DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE > unwrapBuilder (Object  builder ) {
243+     if  (builder  instanceof  DefaultHttpServerInstrumenterBuilder <?, ?>) {
244+       return  (DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE >) builder ;
245+     }
246+     try  {
247+       Field  field  = builder .getClass ().getDeclaredField ("serverBuilder" );
248+       field .setAccessible (true );
249+       return  (DefaultHttpServerInstrumenterBuilder <REQUEST , RESPONSE >) field .get (builder );
250+     } catch  (Exception  e ) {
251+       throw  new  IllegalStateException ("Could not access builder field" , e );
252+     }
253+   }
206254}
0 commit comments