/** * A helper method that can be used by subclasses for putting a tag value on the given span (via {@link * Span#putTag(String, String)}) if and only if the tag value is not null and its {@link Object#toString()} is not * blank (according to {@link StringUtils#isBlank(CharSequence)}). * * @param span The span to tag - should never be null. * @param tagKey The key to use when calling {@link Span#putTag(String, String)} - should never be null. * @param tagValue The tag value to use if and only if it is not null and its {@link Object#toString()} is not * blank. */ protected void putTagIfValueIsNotBlank( @NotNull Span span, @NotNull String tagKey, @Nullable Object tagValue ) { //noinspection ConstantConditions if (tagValue == null || span == null || tagKey == null) { return; } // tagValue is not null. Convert to string and check for blank. String tagValueString = tagValue.toString(); if (StringUtils.isBlank(tagValueString)) { return; } // tagValue is not blank. Add it to the given span. span.putTag(tagKey, tagValueString); }
@Override protected void doHandleResponseAndErrorTagging( @NotNull Span span, @Nullable REQ request, @Nullable RES response, @Nullable Throwable error, @NotNull HttpTagAndSpanNamingAdapter<REQ, RES> adapter ) { putTagIfValueIsNotBlank(span, KnownOpenTracingTags.HTTP_STATUS, adapter.getResponseHttpStatus(response)); if (error != null || StringUtils.isNotBlank(adapter.getErrorResponseTagValue(response))) { // OpenTracing doesn't expect you to pass messages with the error tag, just error=true. // So we don't need to do anything with the given error Throwable or returned // getErrorResponseTagValue(), other than have them trigger adding the error=true tag. span.putTag(KnownOpenTracingTags.ERROR, "true"); } } }
@Test public void putTagIfValueIsNotBlank_calls_span_putTag_as_expected_for_tagValue_toString_when_result_is_not_blank() { // given Object tagValueMock = mock(Object.class); String tagValueToStringResult = "tag_value-" + UUID.randomUUID().toString(); doReturn(tagValueToStringResult).when(tagValueMock).toString(); String tagKey = "tag_key-" + UUID.randomUUID().toString(); // when implSpy.putTagIfValueIsNotBlank(spanMock, tagKey, tagValueMock); // then verify(spanMock).putTag(tagKey, tagValueToStringResult); }
@DataProvider(value = { "null", "", "[whitespace]" }, splitBy = "\\|") @Test public void putTagIfValueIsNotBlank_does_nothing_when_tagValue_toString_IS_blank( String blankTagValueToStringResult ) { // given if ("[whitespace]".equals(blankTagValueToStringResult)) { blankTagValueToStringResult = " \n\r\t "; } Object tagValueMock = mock(Object.class); doReturn(blankTagValueToStringResult).when(tagValueMock).toString(); String tagKey = "tag_key-" + UUID.randomUUID().toString(); // when implSpy.putTagIfValueIsNotBlank(spanMock, tagKey, tagValueMock); // then verify(spanMock, never()).putTag(anyString(), anyString()); }
@DataProvider(value = { "true | false | false", "false | true | false", "false | false | true" }, splitBy = "\\|") @Test public void putTagIfValueIsNotBlank_does_nothing_when_any_arg_is_null( boolean spanIsNull, boolean tagKeyIsNull, boolean tagValueIsNull ) { // given Span span = (spanIsNull) ? null : spanMock; String tagKey = (tagKeyIsNull) ? null : UUID.randomUUID().toString(); String tagValue = (tagValueIsNull) ? null : UUID.randomUUID().toString(); // when implSpy.putTagIfValueIsNotBlank(span, tagKey, tagValue); // then verify(spanMock, never()).putTag(anyString(), anyString()); }
@Test public void doExtraWingtipsTagging_adds_SPAN_HANDLER_tag_if_adapter_getSpanHandlerTagValue_is_not_blank() { // given String adapterSpanHandlerTagValue = UUID.randomUUID().toString(); doReturn(adapterSpanHandlerTagValue).when(adapterMock).getSpanHandlerTagValue(anyObject(), anyObject()); // when implSpy.doExtraWingtipsTagging(spanMock, requestObjectMock, responseObjectMock, errorMock, adapterMock); // then verify(implSpy).putTagIfValueIsNotBlank(spanMock, WingtipsTags.SPAN_HANDLER, adapterSpanHandlerTagValue); verify(spanMock).putTag(WingtipsTags.SPAN_HANDLER, adapterSpanHandlerTagValue); verifyNoMoreInteractions(spanMock); }
@Test public void equals_returns_false_and_hashCode_different_if_tags_are_different() { // given Span fullSpan1 = createFilledOutSpan(true); Span fullSpan2 = createFilledOutSpan(true); fullSpan1.putTag("key-" + UUID.randomUUID().toString(), UUID.randomUUID().toString()); // expect assertThat(fullSpan1.equals(fullSpan2)).isFalse(); assertThat(fullSpan1.hashCode()).isNotEqualTo(fullSpan2.hashCode()); }
@Test public void putTag_works_as_expected() { // given Span span = Span.newBuilder("foo", SpanPurpose.CLIENT).build(); assertThat(span.getTags()).isEmpty(); String tagKey = "key-" + UUID.randomUUID().toString(); String tagValue = "value-" + UUID.randomUUID().toString(); String otherValue = "othervalue-" + UUID.randomUUID().toString(); // when span.putTag(tagKey, tagValue); // then assertThat(span.getTags()).hasSize(1); assertThat(span.getTags().get(tagKey)).isEqualTo(tagValue); // and when span.putTag(tagKey, otherValue); // then assertThat(span.getTags()).hasSize(1); assertThat(span.getTags().get(tagKey)).isEqualTo(otherValue); }
verify(spanMock).putTag(KnownOpenTracingTags.ERROR, "true");
subspan.putTag(KnownZipkinTags.HTTP_HOST, downstreamHost + ":" + downstreamPort);
subspan.putTag(KnownZipkinTags.HTTP_HOST, downstreamHost + ":" + downstreamPort);