diff --git a/build.gradle b/build.gradle index 6f984c16..65e6f777 100644 --- a/build.gradle +++ b/build.gradle @@ -64,7 +64,7 @@ javadocJar.enabled = false ext { slf4jVersion = '1.7.7' servletApiVersion = '3.1.0' - zipkinVersion = '1.8.4' + zipkinVersion = '1.11.1' junitVersion = '4.11' mockitoVersion = '1.9.5' diff --git a/wingtips-core/src/main/java/com/nike/wingtips/TraceAndSpanIdGenerator.java b/wingtips-core/src/main/java/com/nike/wingtips/TraceAndSpanIdGenerator.java index 1b5cc291..7810f3d8 100644 --- a/wingtips-core/src/main/java/com/nike/wingtips/TraceAndSpanIdGenerator.java +++ b/wingtips-core/src/main/java/com/nike/wingtips/TraceAndSpanIdGenerator.java @@ -116,8 +116,8 @@ protected static Random getRandomInstance(String desiredSecureRandomImplementati /** *
- * The code in this class came from the Zipkin repository v1.7.0 - * (https://github.com/openzipkin/zipkin/blob/master/zipkin/src/main/java/zipkin/internal/Util.java) + * The code in this class came from the Zipkin repository v1.11.1 + * (https://github.com/openzipkin/zipkin/blob/1.11.1/zipkin/src/main/java/zipkin/internal/Util.java) * and licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0). *
*/ @@ -127,14 +127,20 @@ private ZipkinHexHelpers() { // Do nothing } - /** Parses a 1 to 16 character lower-hex string with no prefix int an unsigned long. */ - static long lowerHexToUnsignedLong(String lowerHex) { - char[] array = lowerHex.toCharArray(); - if (array.length < 1 || array.length > 16) { - throw isntLowerHexLong(lowerHex); - } + /** + * Parses a 1 to 32 character lower-hex string with no prefix into an unsigned long, tossing any + * bits higher than 64. + */ + public static long lowerHexToUnsignedLong(String lowerHex) { + int length = lowerHex.length(); + if (length < 1 || length > 32) throw isntLowerHexLong(lowerHex); + + // trim off any high bits + int i = length > 16 ? length - 16 : 0; + long result = 0; - for (char c : array) { + for (; i < length; i++) { + char c = lowerHex.charAt(i); result <<= 4; if (c >= '0' && c <= '9') { result |= c - '0'; @@ -149,7 +155,7 @@ static long lowerHexToUnsignedLong(String lowerHex) { static NumberFormatException isntLowerHexLong(String lowerHex) { return new NumberFormatException( - lowerHex + " should be a 1 to 16 character lower-hex string with no prefix"); + lowerHex + " should be a 1 to 32 character lower-hex string with no prefix"); } /** Inspired by {@code okio.Buffer.writeLong} */ diff --git a/wingtips-core/src/test/java/com/nike/wingtips/TraceAndSpanIdGeneratorTest.java b/wingtips-core/src/test/java/com/nike/wingtips/TraceAndSpanIdGeneratorTest.java index b50da952..ef08a5a7 100644 --- a/wingtips-core/src/test/java/com/nike/wingtips/TraceAndSpanIdGeneratorTest.java +++ b/wingtips-core/src/test/java/com/nike/wingtips/TraceAndSpanIdGeneratorTest.java @@ -230,13 +230,13 @@ public void longToUnsignedLowerHexString_and_unsignedLowerHexStringToLong_work_a } @DataProvider(value = { - " ", // less than 16 chars - "12345678901234567 ", // longer than 16 chars - "/ ", // before '0' char - ": ", // after '9' char - "` ", // before 'a' char - "g ", // after 'f' char - "ABCDEF " // uppercase hex chars + " ", // less than 16 chars + "123e4567-e89b-12d3-a456-426655440000 ", // longer than 32 chars + "/ ", // before '0' char + ": ", // after '9' char + "` ", // before 'a' char + "g ", // after 'f' char + "ABCDEF " // uppercase hex chars }, splitBy = "\\|") @Test public void unsignedLowerHexStringToLong_throws_NumberFormatException_for_illegal_args(final String badHexString) { diff --git a/wingtips-zipkin/src/test/java/com/nike/wingtips/zipkin/util/WingtipsToZipkinSpanConverterDefaultImplTest.java b/wingtips-zipkin/src/test/java/com/nike/wingtips/zipkin/util/WingtipsToZipkinSpanConverterDefaultImplTest.java index 483e89e3..8598d252 100644 --- a/wingtips-zipkin/src/test/java/com/nike/wingtips/zipkin/util/WingtipsToZipkinSpanConverterDefaultImplTest.java +++ b/wingtips-zipkin/src/test/java/com/nike/wingtips/zipkin/util/WingtipsToZipkinSpanConverterDefaultImplTest.java @@ -135,4 +135,25 @@ public void convertWingtipsSpanToZipkinSpan_works_as_expected_for_all_nullable_i verifySpanPurposeRelatedStuff(zipkinSpan, wingtipsSpan, zipkinEndpoint, localComponentNamespace); } -} \ No newline at end of file + @Test + public void convertWingtipsSpanToZipkinSpan_works_as_expected_for_128_bit_trace_id() { + // given + String hex128Bits = "463ac35c9f6413ad48485a3953bb6124"; + String lower64Bits = "48485a3953bb6124"; + + String spanName = UUID.randomUUID().toString(); + String traceId = hex128Bits; + String spanId = lower64Bits; + long startTimeEpochMicros = Math.abs(random.nextLong()); + long durationNanos = Math.abs(random.nextLong()); + Endpoint zipkinEndpoint = Endpoint.create(UUID.randomUUID().toString(), 42); + String localComponentNamespace = UUID.randomUUID().toString(); + Span wingtipsSpan = new Span(traceId, null, spanId, spanName, true, null, Span.SpanPurpose.CLIENT, startTimeEpochMicros, null, durationNanos); + + // when + zipkin.Span zipkinSpan = impl.convertWingtipsSpanToZipkinSpan(wingtipsSpan, zipkinEndpoint, localComponentNamespace); + + // then + assertThat(zipkinSpan.traceId).isEqualTo(unsignedLowerHexStringToLong(lower64Bits)); + } +}