private HttpEntity getHttpEntityWithUserIdHeader() { HttpHeaders headers = new HttpHeaders(); String userId = Tracer.getInstance().getCurrentSpan().getUserId(); if (userIdHeaderKeys == null || userIdHeaderKeys.isEmpty() || userId == null) { return new HttpEntity(headers); } headers.set(userIdHeaderKeys.get(0), userId); return new HttpEntity(headers); }
private HttpEntity getHttpEntityWithUserIdHeader() { HttpHeaders headers = new HttpHeaders(); String userId = Tracer.getInstance().getCurrentSpan().getUserId(); if (userIdHeaderKeys.isEmpty() || userId == null) { return new HttpEntity(headers); } headers.set(userIdHeaderKeys.get(0), userId); return new HttpEntity(headers); }
public EndpointSpanInfoDto(HttpServletRequest request, Span endpoint_execution_span, List<String> userIdHeaderKeys) { this.parent_span_info = new SpanInfoDto( request.getHeader(TraceHeaders.TRACE_ID), request.getHeader(TraceHeaders.SPAN_ID), request.getHeader(TraceHeaders.PARENT_SPAN_ID), request.getHeader(TraceHeaders.TRACE_SAMPLED), HttpSpanFactory.getUserIdFromHttpServletRequest(request, userIdHeaderKeys) ); this.endpoint_execution_span_info = new SpanInfoDto( endpoint_execution_span.getTraceId(), endpoint_execution_span.getSpanId(), endpoint_execution_span.getParentSpanId(), String.valueOf(endpoint_execution_span.isSampleable()), endpoint_execution_span.getUserId() ); }
public EndpointSpanInfoDto(HttpServletRequest request, Span endpoint_execution_span, List<String> userIdHeaderKeys) { this.parent_span_info = new SpanInfoDto( request.getHeader(TraceHeaders.TRACE_ID), request.getHeader(TraceHeaders.SPAN_ID), request.getHeader(TraceHeaders.PARENT_SPAN_ID), request.getHeader(TraceHeaders.TRACE_SAMPLED), HttpSpanFactory.getUserIdFromHttpServletRequest(request, userIdHeaderKeys) ); this.endpoint_execution_span_info = new SpanInfoDto( endpoint_execution_span.getTraceId(), endpoint_execution_span.getSpanId(), endpoint_execution_span.getParentSpanId(), String.valueOf(endpoint_execution_span.isSampleable()), endpoint_execution_span.getUserId() ); }
@Test public void doFilterInternal_should_set_request_attributes_to_new_span_info_with_alt_user_id( ) throws ServletException, IOException { // given: filter RequestTracingFilter spyFilter = spy(getBasicFilter()); given(requestMock.getHeader(ALT_USER_ID_HEADER_KEY)).willReturn("testUserId"); // when: doFilterInternal is called spyFilter.doFilterInternal(requestMock, responseMock, spanCapturingFilterChain); // then: request attributes should be set with the new span's info assertThat(spanCapturingFilterChain.capturedSpan).isNotNull(); Span newSpan = spanCapturingFilterChain.capturedSpan; assertThat(newSpan.getUserId()).isEqualTo("testUserId"); }
@Test public void doFilterInternal_should_set_request_attributes_to_new_span_info_with_user_id( ) throws ServletException, IOException { // given: filter RequestTracingFilter spyFilter = spy(getBasicFilter()); given(requestMock.getHeader(USER_ID_HEADER_KEY)).willReturn("testUserId"); // when: doFilterInternal is called spyFilter.doFilterInternal(requestMock, responseMock, spanCapturingFilterChain); // then: request attributes should be set with the new span's info assertThat(spanCapturingFilterChain.capturedSpan).isNotNull(); Span newSpan = spanCapturingFilterChain.capturedSpan; assertThat(newSpan.getUserId()).isEqualTo("testUserId"); }
@Test public void fromRequestWithHeaders_sets_user_id_to_null_if_passed_null_or_empty_userIdHeaderKeys_list() { // given String traceId = UUID.randomUUID().toString(); given(request.getHeader(TraceHeaders.TRACE_ID)).willReturn(traceId); List<List<String>> badLists = Arrays.asList(null, Collections.<String>emptyList()); for (List<String> badList : badLists) { // when Span result = HttpRequestTracingUtils.fromRequestWithHeaders(request, badList); // expect assertThat(result.getTraceId()).isEqualTo(traceId); assertThat(result.getUserId()).isNull(); } }
@Test public void fromHttpServletRequestOrCreateRootSpan_returns_new_root_span_if_traceId_is_missing_from_headers() { // given: no trace ID in headers, but user ID exists given(request.getHeader(ALT_USER_ID_HEADER_KEY)).willReturn(altUserId); // when: creating Span object from HTTP request using fromHttpServletRequestOrCreateRootSpan long beforeCallNanos = System.nanoTime(); Span newSpan = HttpSpanFactory.fromHttpServletRequestOrCreateRootSpan(request, USER_ID_HEADER_KEYS); long afterCallNanos = System.nanoTime(); // then: ensure root span object is created even though there was no trace ID header, and the returned span contains the expected user ID assertThat(newSpan).isNotNull(); assertThat(newSpan.getParentSpanId()).isNull(); assertThat(newSpan.getUserId()).isEqualTo(altUserId); assertThat(newSpan.getSpanStartTimeNanos()).isBetween(beforeCallNanos, afterCallNanos); assertThat(newSpan.isCompleted()).isFalse(); assertThat(newSpan.getSpanPurpose()).isEqualTo(SpanPurpose.SERVER); }
@Test public void equals_returns_false_and_hashCode_different_if_userId_is_different() { // given Span fullSpan1 = createFilledOutSpan(true); Span fullSpan2 = createFilledOutSpan(true); List<String> badDataList = Arrays.asList(fullSpan1.getUserId() + "_nope", null); for (String badData : badDataList) { Whitebox.setInternalState(fullSpan2, "userId", badData); // expect assertThat(fullSpan1.equals(fullSpan2)).isFalse(); assertThat(fullSpan2.equals(fullSpan1)).isFalse(); assertThat(fullSpan1.hashCode()).isNotEqualTo(fullSpan2.hashCode()); } }
@Test public void fromHttpServletRequestOrCreateRootSpan_pulls_from_headers_if_available() { // given: a set of standard Span header values given(request.getHeader(TraceHeaders.TRACE_ID)).willReturn(sampleTraceID); given(request.getHeader(TraceHeaders.TRACE_SAMPLED)).willReturn(Boolean.TRUE.toString()); given(request.getHeader(TraceHeaders.SPAN_ID)).willReturn(sampleSpanID); given(request.getHeader(TraceHeaders.PARENT_SPAN_ID)).willReturn(sampleParentSpanID); given(request.getHeader(USER_ID_HEADER_KEY)).willReturn(userId); // when: creating Span object from HTTP request using fromHttpServletRequestOrCreateRootSpan long beforeCallNanos = System.nanoTime(); Span goodSpan = HttpSpanFactory.fromHttpServletRequestOrCreateRootSpan(request, USER_ID_HEADER_KEYS); long afterCallNanos = System.nanoTime(); // then: ensure Span object gets identical values from corresponding headers assertThat(goodSpan.getTraceId()).isEqualTo(sampleTraceID); assertThat(goodSpan.isSampleable()).isTrue(); assertThat(goodSpan.getSpanId()).isEqualTo(sampleSpanID); assertThat(goodSpan.getParentSpanId()).isEqualTo(sampleParentSpanID); assertThat(goodSpan.getUserId()).isEqualTo(userId); assertThat(goodSpan.getSpanStartTimeNanos()).isBetween(beforeCallNanos, afterCallNanos); assertThat(goodSpan.isCompleted()).isFalse(); assertThat(goodSpan.getSpanPurpose()).isEqualTo(SpanPurpose.SERVER); }
private SpanInfoDto spanInfoDtoFromSpan(Span span) { return new SpanInfoDto( span.getTraceId(), span.getSpanId(), span.getParentSpanId(), String.valueOf(span.isSampleable()), span.getUserId() ); }
private SpanInfoDto spanInfoDtoFromSpan(Span span) { return new SpanInfoDto( span.getTraceId(), span.getSpanId(), span.getParentSpanId(), String.valueOf(span.isSampleable()), span.getUserId() ); }
@Test public void convertSpanToJSON_should_function_properly_when_there_are_null_values() throws IOException { // given: valid span with null values and JSON string from SpanParser.convertSpanToJSON() Span validSpan = Span.generateRootSpanForNewTrace(spanName, null).build(); assertThat(validSpan.getParentSpanId()).isNull(); assertThat(validSpan.getUserId()).isNull(); assertThat(validSpan.getDurationNanos()).isNull(); String json = SpanParser.convertSpanToJSON(validSpan); // when: jackson is used to deserialize that JSON Map<String, Object> spanValuesFromJackson = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {}); // then: the original span context and jackson's span context values should be exactly the same verifySpanEqualsDeserializedValues(validSpan, spanValuesFromJackson); }
@Test public void fromRequestWithHeaders_generates_span_from_headers_in_request() { // given: a set of standard span header values given(request.getHeader(TraceHeaders.TRACE_ID)).willReturn(sampleTraceID); given(request.getHeader(TraceHeaders.TRACE_SAMPLED)).willReturn(Boolean.TRUE.toString()); given(request.getHeader(TraceHeaders.SPAN_ID)).willReturn(sampleSpanID); given(request.getHeader(TraceHeaders.PARENT_SPAN_ID)).willReturn(sampleParentSpanID); given(request.getHeader(USER_ID_HEADER_KEY)).willReturn(userId); // when: creating span object from HTTP request Span goodSpan = HttpRequestTracingUtils.fromRequestWithHeaders(request, USER_ID_HEADER_KEYS); // then: ensure span object gets identical values from corresponding headers, and the span purpose is set to SERVER assertThat(goodSpan.getTraceId()).isEqualTo(sampleTraceID); assertThat(goodSpan.isSampleable()).isTrue(); assertThat(goodSpan.getSpanId()).isEqualTo(sampleSpanID); assertThat(goodSpan.getParentSpanId()).isEqualTo(sampleParentSpanID); assertThat(goodSpan.getUserId()).isEqualTo(userId); assertThat(goodSpan.getSpanPurpose()).isEqualTo(SpanPurpose.SERVER); }
@Test @UseDataProvider("nullAndEmptyStrings") public void fromRequestWithHeaders_sets_user_id_to_null_if_request_returns_null_or_empty_for_user_id(String nullOrEmptyUserId) { // given String traceId = UUID.randomUUID().toString(); given(request.getHeader(TraceHeaders.TRACE_ID)).willReturn(traceId); given(request.getHeader(USER_ID_HEADER_KEY)).willReturn(nullOrEmptyUserId); given(request.getAttribute(USER_ID_HEADER_KEY)).willReturn(nullOrEmptyUserId); // when Span result = HttpRequestTracingUtils.fromRequestWithHeaders(request, USER_ID_HEADER_KEYS); // expect assertThat(result.getTraceId()).isEqualTo(traceId); assertThat(result.getUserId()).isNull(); }
@Test public void fromJson_should_function_properly_when_there_are_null_values() { // given: valid span with null values and JSON string from SpanParser.convertSpanToJSON() Span validSpan = Span.generateRootSpanForNewTrace(spanName, null).build(); assertThat(validSpan.getParentSpanId()).isNull(); assertThat(validSpan.getUserId()).isNull(); assertThat(validSpan.getDurationNanos()).isNull(); String json = SpanParser.convertSpanToJSON(validSpan); // when: fromJson is called Span spanFromJson = SpanParser.fromJSON(json); // then: the original span and the fromJson() span values should be exactly the same verifySpanDeepEquals(spanFromJson, validSpan, true); }
private Pair<Span, Map<String, String>> generateUpstreamSpanHeaders(boolean includeUserId) { Span.Builder spanBuilder = Span.newBuilder("upstreamSpan", Span.SpanPurpose.CLIENT); if (includeUserId) { spanBuilder.withUserId("user-" + UUID.randomUUID().toString()); } Span span = spanBuilder.build(); MapBuilder<String, String> headersBuilder = MapBuilder .builder(TraceHeaders.TRACE_ID, span.getTraceId()) .put(TraceHeaders.SPAN_ID, span.getSpanId()) .put(TraceHeaders.SPAN_NAME, span.getSpanName()) .put(TraceHeaders.TRACE_SAMPLED, String.valueOf(span.isSampleable())); if (span.getUserId() != null) { headersBuilder.put(USER_ID_HEADER_KEY, span.getUserId()); } return Pair.of(span, headersBuilder.build()); }
private Pair<Span, Map<String, String>> generateUpstreamSpanHeaders(boolean includeUserId) { Span.Builder spanBuilder = Span.newBuilder("upstreamSpan", Span.SpanPurpose.CLIENT); if (includeUserId) { spanBuilder.withUserId("user-" + UUID.randomUUID().toString()); } Span span = spanBuilder.build(); MapBuilder<String, String> headersBuilder = MapBuilder .builder(TraceHeaders.TRACE_ID, span.getTraceId()) .put(TraceHeaders.SPAN_ID, span.getSpanId()) .put(TraceHeaders.SPAN_NAME, span.getSpanName()) .put(TraceHeaders.TRACE_SAMPLED, String.valueOf(span.isSampleable())); if (span.getUserId() != null) { headersBuilder.put(USER_ID_HEADER_KEY, span.getUserId()); } return Pair.of(span, headersBuilder.build()); }
@Test public void convertSpanToKeyValueFormat_should_function_properly_when_there_are_null_values() { // given: valid span with null values and key/value string from SpanParser.convertSpanToKeyValueFormat() Span validSpan = Span.generateRootSpanForNewTrace(spanName, null).build(); assertThat(validSpan.getParentSpanId()).isNull(); assertThat(validSpan.getUserId()).isNull(); assertThat(validSpan.getDurationNanos()).isNull(); String keyValueStr = SpanParser.convertSpanToKeyValueFormat(validSpan); // when: the string is deserialized into a map Map<String, Object> deserializedValues = deserializeKeyValueSpanString(keyValueStr); // then: the original span and deserialized map values should be exactly the same verifySpanEqualsDeserializedValues(validSpan, deserializedValues); }
@Test public void fromKeyValueString_should_function_properly_when_there_are_null_values() { // given: valid span with null values and key/value string from Span.fromKeyValueString() Span validSpan = Span.generateRootSpanForNewTrace(spanName, null).build(); assertThat(validSpan.getParentSpanId()).isNull(); assertThat(validSpan.getUserId()).isNull(); assertThat(validSpan.getDurationNanos()).isNull(); String keyValStr = SpanParser.convertSpanToKeyValueFormat(validSpan); // when: fromKeyValueString is called Span spanFromKeyValStr = SpanParser.fromKeyValueString(keyValStr); // then: the original span and the fromKeyValueString() span values should be exactly the same verifySpanDeepEquals(spanFromKeyValStr, validSpan, true); }