/** * Gets AppId prefixed with key to append to Request-Context header * @return */ private static String getAppIdWithKey() { return REQUEST_CONTEXT_HEADER_APPID_KEY + "=" + getAppId(); }
/** * This adds the Request-Context in response header so that the Callee can know what is the caller's AppId. * @param response HttpResponse object */ private static void addTargetAppIdInResponseHeaderViaRequestContext(HttpServletResponse response) { if (response.containsHeader(REQUEST_CONTEXT_HEADER_NAME)) { return; } String appId = getAppIdWithKey(); if (appId.isEmpty()) { return; } // W3C protocol doesn't define any behavior for response headers. // This is purely AI concept and hence we use RequestContextHeader here. response.addHeader(REQUEST_CONTEXT_HEADER_NAME,appId); }
/** * Helper method to create extract Incoming Traceparent header. This method can return null. * @param request * @return Incoming Traceparent */ private static Traceparent extractIncomingTraceparent(HttpServletRequest request) { Traceparent incomingTraceparent = null; Enumeration<String> traceparents = request.getHeaders(TRACEPARENT_HEADER_NAME); List<String> traceparentList = getEnumerationAsCollection(traceparents); // W3C spec mandates a request should exactly have 1 Traceparent header if (traceparentList.size() != 1) { return null; } try { incomingTraceparent = Traceparent.fromString(traceparentList.get(0)); } catch (Exception e) { InternalLogger.INSTANCE.error(String.format("Received invalid traceparent header with exception %s, " + "distributed trace might be broken", ExceptionUtils.getStackTrace(e))); } return incomingTraceparent; }
Traceparent incomingTraceparent = extractIncomingTraceparent(request); Traceparent processedTraceParent = processIncomingTraceparent(incomingTraceparent, request); String appId = getAppId(); Tracestate tracestate = getTracestate(request, incomingTraceparent, appId); addTargetAppIdInResponseHeaderViaRequestContext(response);
TraceContextCorrelation.resolveRequestSource((HttpServletRequest) req, telemetry, instrumentationKey); } else { TelemetryCorrelationUtils.resolveRequestSource((HttpServletRequest) req, telemetry, instrumentationKey);
TraceContextCorrelation.resolveCorrelation(request, response, telemetry); } else {
String source = generateSourceTargetCorrelation(instrumentationKey, incomingTracestate.get(AZURE_TRACEPARENT_COMPONENT_INITIAL));
Traceparent incomingTraceparent = extractIncomingTraceparent(request); Traceparent processedTraceParent = processIncomingTraceparent(incomingTraceparent, request); String appId = getAppId(); Tracestate tracestate = getTracestate(request, incomingTraceparent, appId); addTargetAppIdInResponseHeaderViaRequestContext(response);
TraceContextCorrelation.resolveRequestSource((HttpServletRequest) req, telemetry, instrumentationKey); } else { TelemetryCorrelationUtils.resolveRequestSource((HttpServletRequest) req, telemetry, instrumentationKey);
TraceContextCorrelation.resolveCorrelation(request, response, telemetry); } else {
String source = generateSourceTargetCorrelation(instrumentationKey, incomingTracestate.get(AZURE_TRACEPARENT_COMPONENT_INITIAL));
@Test public void testTracestateIsNotResolvedWithNullRequest() { Map<String, String> headers = new HashMap<>(); String incomingTracestate = getTracestateHeaderValue("id1"); headers.put(TraceContextCorrelation.TRACESTATE_HEADER_NAME, incomingTracestate); RequestTelemetry requestTelemetry = new RequestTelemetry(); mockProfileFetcher.setResultStatus(ProfileFetcherResultTaskStatus.COMPLETE); mockProfileFetcher.setAppIdToReturn("id2"); TraceContextCorrelation.resolveRequestSource(null, requestTelemetry, "ikey1"); Assert.assertNull(requestTelemetry.getSource()); }
@Test public void testCorrelationIdsAreResolvedIfTraceparentEmpty() { //setup - empty RequestId Map<String, String> headers = new HashMap<>(); headers.put(TraceContextCorrelation.TRACEPARENT_HEADER_NAME, ""); HttpServletRequest request = ServletUtils.createServletRequestWithHeaders(headers); HttpServletResponse response = (HttpServletResponse)ServletUtils.generateDummyServletResponse(); RequestTelemetry requestTelemetry = new RequestTelemetry(); //run TraceContextCorrelation.resolveCorrelation(request, response, requestTelemetry); //validate operation context ID's - there is no parent, so parentId should be null, traceId // is newly generated and request.Id is based on new traceId-spanId OperationContext operation = requestTelemetry.getContext().getOperation(); Assert.assertNotNull(requestTelemetry.getId()); // First trace will have it's own spanId also. Assert.assertTrue(requestTelemetry.getId().startsWith("|" + operation.getId())); Assert.assertNull(operation.getParentId()); }
/** * Helper method to create extract Incoming Traceparent header. This method can return null. * @param request * @return Incoming Traceparent */ private static Traceparent extractIncomingTraceparent(HttpServletRequest request) { Traceparent incomingTraceparent = null; Enumeration<String> traceparents = request.getHeaders(TRACEPARENT_HEADER_NAME); List<String> traceparentList = getEnumerationAsCollection(traceparents); // W3C spec mandates a request should exactly have 1 Traceparent header if (traceparentList.size() != 1) { return null; } try { incomingTraceparent = Traceparent.fromString(traceparentList.get(0)); } catch (Exception e) { InternalLogger.INSTANCE.error(String.format("Received invalid traceparent header with exception %s, " + "distributed trace might be broken", ExceptionUtils.getStackTrace(e))); } return incomingTraceparent; }
/** * Gets AppId prefixed with key to append to Request-Context header * @return */ private static String getAppIdWithKey() { return REQUEST_CONTEXT_HEADER_APPID_KEY + "=" + getAppId(); }
/** * This adds the Request-Context in response header so that the Callee can know what is the caller's AppId. * @param response HttpResponse object */ private static void addTargetAppIdInResponseHeaderViaRequestContext(HttpServletResponse response) { if (response.containsHeader(REQUEST_CONTEXT_HEADER_NAME)) { return; } String appId = getAppIdWithKey(); if (appId.isEmpty()) { return; } // W3C protocol doesn't define any behavior for response headers. // This is purely AI concept and hence we use RequestContextHeader here. response.addHeader(REQUEST_CONTEXT_HEADER_NAME,appId); }
@Test public void testTracestateIsNotResolvedIfHeaderIsEmpty() { Map<String, String> headers = new HashMap<>(); headers.put(TraceContextCorrelation.TRACESTATE_HEADER_NAME, ""); HttpServletRequest request = ServletUtils.createServletRequestWithHeaders(headers); RequestTelemetry requestTelemetry = new RequestTelemetry(); mockProfileFetcher.setResultStatus(ProfileFetcherResultTaskStatus.COMPLETE); mockProfileFetcher.setAppIdToReturn("id1"); TraceContextCorrelation.resolveRequestSource(request, requestTelemetry, "ikey1"); Assert.assertNull(requestTelemetry.getSource()); }
@Test public void testCorrelationIdsAreResolvedIfNoTraceparentHeader() { //setup - no headers Map<String, String> headers = new HashMap<>(); HttpServletRequest request = ServletUtils.createServletRequestWithHeaders(headers); HttpServletResponse response = (HttpServletResponse)ServletUtils.generateDummyServletResponse(); RequestTelemetry requestTelemetry = new RequestTelemetry(); //run TraceContextCorrelation.resolveCorrelation(request, response, requestTelemetry); //validate operation context ID's - there is no parent, so parentId should be null, traceId // is newly generated and request.Id is based on new traceId-spanId OperationContext operation = requestTelemetry.getContext().getOperation(); Assert.assertNotNull(requestTelemetry.getId()); // First trace will have it's own spanId also. Assert.assertTrue(requestTelemetry.getId().startsWith(formatedID(operation.getId()))); Assert.assertNull(operation.getParentId()); }
List<String> tracestateList = getEnumerationAsCollection(tracestates); try {
@Test public void testTracestateIsNotResolvedWithNullIkey() { Map<String, String> headers = new HashMap<>(); String incomingTracestate = getTracestateHeaderValue("id1"); headers.put(TraceContextCorrelation.TRACESTATE_HEADER_NAME, incomingTracestate); HttpServletRequest request = ServletUtils.createServletRequestWithHeaders(headers); RequestTelemetry requestTelemetry = new RequestTelemetry(); mockProfileFetcher.setResultStatus(ProfileFetcherResultTaskStatus.COMPLETE); mockProfileFetcher.setAppIdToReturn("id2"); TraceContextCorrelation.resolveRequestSource(request, requestTelemetry, null); Assert.assertNull(requestTelemetry.getSource()); }