@Test public void doFilterInternal_should_not_complete_span_or_response_tags_until_after_filter_chain_runs( ) throws ServletException, IOException { RequestTracingFilter filter = getBasicFilter(); AtomicBoolean spanCompletedHolder = new AtomicBoolean(false); AtomicReference<Span> spanHolder = new AtomicReference<>(); AtomicReference<Boolean> requestTagsExecutedAtTimeOfFilterChain = new AtomicReference<>(); AtomicReference<Boolean> responseTagsExecutedAtTimeOfFilterChain = new AtomicReference<>(); FilterChain smartFilterChain = (request, response) -> { Span span = Tracer.getInstance().getCurrentSpan(); spanHolder.set(span); if (span != null) { spanCompletedHolder.set(span.isCompleted()); } requestTagsExecutedAtTimeOfFilterChain.set(strategyRequestTaggingMethodCalled.get()); responseTagsExecutedAtTimeOfFilterChain.set(strategyResponseTaggingAndFinalSpanNameMethodCalled.get()); }; filter.doFilterInternal(requestMock, responseMock, smartFilterChain); assertThat(spanHolder.get()).isNotNull(); assertThat(spanCompletedHolder.get()).isFalse(); assertThat(spanHolder.get().isCompleted()).isTrue(); assertThat(requestTagsExecutedAtTimeOfFilterChain.get()).isTrue(); assertThat(responseTagsExecutedAtTimeOfFilterChain.get()).isFalse(); }
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { TracingState originalThreadInfo = TracingState.getCurrentThreadTracingState(); try { Span overallRequestSpan = createNewSpanForRequest(request); addTracingInfoToRequestAttributes(overallRequestSpan, request); response.setHeader(TraceHeaders.TRACE_ID, overallRequestSpan.getTraceId()); TracingState originalRequestTracingState = TracingState.getCurrentThreadTracingState(); Throwable errorForTagging = null; try { tagAndNamingStrategy.handleRequestTagging(overallRequestSpan, request, tagAndNamingAdapter); filterChain.doFilter(request, response); } catch(Throwable t) { errorForTagging = t; throw t; } finally { if (isAsyncRequest(request)) { setupTracingCompletionWhenAsyncRequestCompletes( request, response, originalRequestTracingState, tagAndNamingStrategy, tagAndNamingAdapter ); } else { try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( overallRequestSpan, request, response, errorForTagging, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } } } finally { unlinkTracingFromCurrentThread(originalThreadInfo); } }
RequestTracingFilter implements Filter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { TracingState originalThreadInfo = TracingState.getCurrentThreadTracingState(); try { Span overallRequestSpan = createNewSpanForRequest(request); addTracingInfoToRequestAttributes(overallRequestSpan, request); response.setHeader(TraceHeaders.TRACE_ID, overallRequestSpan.getTraceId()); TracingState originalRequestTracingState = TracingState.getCurrentThreadTracingState(); Throwable errorForTagging = null; try { tagAndNamingStrategy.handleRequestTagging(overallRequestSpan, request, tagAndNamingAdapter); filterChain.doFilter(request, response); } catch(Throwable t) { errorForTagging = t; throw t; } finally { if (isAsyncRequest(request)) { setupTracingCompletionWhenAsyncRequestCompletes( request, response, originalRequestTracingState, tagAndNamingStrategy, tagAndNamingAdapter ); } else { try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( overallRequestSpan, request, response, errorForTagging, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } } } finally { unlinkTracingFromCurrentThread(originalThreadInfo); } } }
RequestTracingFilter implements Filter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { TracingState originalThreadInfo = TracingState.getCurrentThreadTracingState(); try { Span overallRequestSpan = createNewSpanForRequest(request); addTracingInfoToRequestAttributes(overallRequestSpan, request); response.setHeader(TraceHeaders.TRACE_ID, overallRequestSpan.getTraceId()); TracingState originalRequestTracingState = TracingState.getCurrentThreadTracingState(); Throwable errorForTagging = null; try { tagAndNamingStrategy.handleRequestTagging(overallRequestSpan, request, tagAndNamingAdapter); filterChain.doFilter(request, response); } catch(Throwable t) { errorForTagging = t; throw t; } finally { if (isAsyncRequest(request)) { setupTracingCompletionWhenAsyncRequestCompletes( request, response, originalRequestTracingState, tagAndNamingStrategy, tagAndNamingAdapter ); } else { try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( overallRequestSpan, request, response, errorForTagging, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } } } finally { unlinkTracingFromCurrentThread(originalThreadInfo); } }  }
RequestTracingFilter implements Filter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { TracingState originalThreadInfo = TracingState.getCurrentThreadTracingState(); try { Span overallRequestSpan = createNewSpanForRequest(request); addTracingInfoToRequestAttributes(overallRequestSpan, request); response.setHeader(TraceHeaders.TRACE_ID, overallRequestSpan.getTraceId()); TracingState originalRequestTracingState = TracingState.getCurrentThreadTracingState(); Throwable errorForTagging = null; try { tagAndNamingStrategy.handleRequestTagging(overallRequestSpan, request, tagAndNamingAdapter); filterChain.doFilter(request, response); } catch(Throwable t) { errorForTagging = t; throw t; } finally { if (isAsyncRequest(request)) { setupTracingCompletionWhenAsyncRequestCompletes( request, response, originalRequestTracingState, tagAndNamingStrategy, tagAndNamingAdapter ); } else { try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( overallRequestSpan, request, response, errorForTagging, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } } } finally { unlinkTracingFromCurrentThread(originalThreadInfo); } }  @Override @SuppressWarnings("RedundantThrows") void init(FilterConfig filterConfig); @Override void destroy(); @Override void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain filterChain); }
RequestTracingFilter implements Filter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { TracingState originalThreadInfo = TracingState.getCurrentThreadTracingState(); try { Span overallRequestSpan = createNewSpanForRequest(request); addTracingInfoToRequestAttributes(overallRequestSpan, request); response.setHeader(TraceHeaders.TRACE_ID, overallRequestSpan.getTraceId()); TracingState originalRequestTracingState = TracingState.getCurrentThreadTracingState(); Throwable errorForTagging = null; try { tagAndNamingStrategy.handleRequestTagging(overallRequestSpan, request, tagAndNamingAdapter); filterChain.doFilter(request, response); } catch(Throwable t) { errorForTagging = t; throw t; } finally { if (isAsyncRequest(request)) { setupTracingCompletionWhenAsyncRequestCompletes( request, response, originalRequestTracingState, tagAndNamingStrategy, tagAndNamingAdapter ); } else { try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( overallRequestSpan, request, response, errorForTagging, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } } } finally { unlinkTracingFromCurrentThread(originalThreadInfo); } }  @Override @SuppressWarnings("RedundantThrows") void init(FilterConfig filterConfig); @Override void destroy(); @Override void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain filterChain); static final String FILTER_HAS_ALREADY_EXECUTED_ATTRIBUTE; @Deprecated
    static final String ERROR_REQUEST_URI_ATTRIBUTE; static final String USER_ID_HEADER_KEYS_LIST_INIT_PARAM_NAME; static final String TAG_AND_SPAN_NAMING_STRATEGY_INIT_PARAM_NAME; static final String TAG_AND_SPAN_NAMING_ADAPTER_INIT_PARAM_NAME; }