diff --git a/dd-trace-api/src/main/java/datadog/trace/api/DD128bTraceId.java b/dd-trace-api/src/main/java/datadog/trace/api/DD128bTraceId.java index a3046e98e9d..63852429871 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/DD128bTraceId.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/DD128bTraceId.java @@ -14,7 +14,7 @@ * #highOrderBits} is set to 0 and {@link #lowOrderBits} contains a unique and random * 63-bit id. */ -public class DD128bTraceId implements DDTraceId { +public class DD128bTraceId extends DDTraceId { public static final DD128bTraceId ZERO = new DD128bTraceId(0, 0, "00000000000000000000000000000000"); /** Represents the high-order 64 bits of the 128-bit trace id. */ diff --git a/dd-trace-api/src/main/java/datadog/trace/api/DD64bTraceId.java b/dd-trace-api/src/main/java/datadog/trace/api/DD64bTraceId.java index e3a4e7cf258..f40b47a89d4 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/DD64bTraceId.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/DD64bTraceId.java @@ -9,9 +9,7 @@ * representations. The decimal string representation is either kept from parsing, or generated on * demand and cached. */ -public class DD64bTraceId implements DDTraceId { - - public static final DD64bTraceId ZERO = new DD64bTraceId(0, "0"); +public class DD64bTraceId extends DDTraceId { public static final DD64bTraceId MAX = new DD64bTraceId(-1, "18446744073709551615"); // All bits set @@ -61,9 +59,15 @@ public static DD64bTraceId fromHex(String s) throws NumberFormatException { } static DD64bTraceId create(long id, String str) { - if (id == 0) return ZERO; - if (id == -1) return MAX; - return new DD64bTraceId(id, str); + // ZERO constant is created and stored by the parent class as part of its API contract + // But initialized by this 64-bit child class. Ensures uniqueness of ZERO once created. + if (id == 0 && ZERO != null) { + return (DD64bTraceId) ZERO; + } else if (id == -1) { + return MAX; + } else { + return new DD64bTraceId(id, str); + } } @Override diff --git a/dd-trace-api/src/main/java/datadog/trace/api/DDTraceId.java b/dd-trace-api/src/main/java/datadog/trace/api/DDTraceId.java index 5eee55a98ec..cc10e7493ee 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/DDTraceId.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/DDTraceId.java @@ -8,11 +8,11 @@ *

It contains parsing and formatting to string for both decimal and hexadecimal representations. * The string representations are either kept from parsing, or generated on demand and cached. */ -public interface DDTraceId { +public abstract class DDTraceId { /** Invalid TraceId value used to denote no TraceId. */ - DDTraceId ZERO = from(0); + public static final DDTraceId ZERO = from(0); /** Convenience constant used from tests */ - DDTraceId ONE = from(1); + public static final DDTraceId ONE = from(1); /** * Creates a new {@link DD64bTraceId 64-bit TraceId} from the given {@code long} interpreted as @@ -22,7 +22,7 @@ public interface DDTraceId { * @param id The {@code long} representing the bits of the unsigned 64-bit id. * @return A new {@link DDTraceId} instance. */ - static DDTraceId from(long id) { + public static DDTraceId from(long id) { return DD64bTraceId.from(id); } @@ -34,7 +34,7 @@ static DDTraceId from(long id) { * @return A new {@link DDTraceId} instance. * @throws NumberFormatException If the given {@link String} does not represent a valid number. */ - static DDTraceId from(String s) throws NumberFormatException { + public static DDTraceId from(String s) throws NumberFormatException { return DD64bTraceId.create(LongStringUtils.parseUnsignedLong(s), s); } @@ -47,7 +47,7 @@ static DDTraceId from(String s) throws NumberFormatException { * @throws NumberFormatException If the given {@link #toHexString() hexadecimal String} does not * represent a valid number. */ - static DDTraceId fromHex(String s) throws NumberFormatException { + public static DDTraceId fromHex(String s) throws NumberFormatException { if (s == null) { throw new NumberFormatException("s cannot be null"); } @@ -62,7 +62,7 @@ static DDTraceId fromHex(String s) throws NumberFormatException { * instance. */ @Override - String toString(); + public abstract String toString(); /** * Returns the lower-case zero-padded 32 hexadecimal characters {@link String} representation of @@ -71,7 +71,7 @@ static DDTraceId fromHex(String s) throws NumberFormatException { * @return A cached lower-case zero-padded 32 hexadecimal characters {@link String} representation * of the {@link DDTraceId} instance. */ - String toHexString(); + public abstract String toHexString(); /** * Returns the lower-case zero-padded {@link #toHexString() hexadecimal String} representation of @@ -83,7 +83,7 @@ static DDTraceId fromHex(String s) throws NumberFormatException { * @return A lower-case zero-padded {@link #toHexString() String representation} representation of * the {@link DDTraceId} instance. */ - String toHexStringPadded(int size); + public abstract String toHexStringPadded(int size); /** * Returns the low-order 64 bits of the {@link DDTraceId} as an unsigned {@code long}. This means @@ -91,7 +91,7 @@ static DDTraceId fromHex(String s) throws NumberFormatException { * * @return The low-order 64 bits of the {@link DDTraceId} as an unsigned {@code long}. */ - long toLong(); + public abstract long toLong(); /** * Returns the high-order 64 bits of 128-bit {@link DDTraceId} as un unsigned {@code long}. This @@ -100,5 +100,5 @@ static DDTraceId fromHex(String s) throws NumberFormatException { * @return The high-order 64 bits of the 128-bit {@link DDTraceId} as an unsigned {@code long}, * 0 for 64-bit {@link DDTraceId} only. */ - long toHighOrderLong(); + public abstract long toHighOrderLong(); } diff --git a/dd-trace-api/src/test/groovy/datadog/trace/api/DDTraceIdTest.groovy b/dd-trace-api/src/test/groovy/datadog/trace/api/DDTraceIdTest.groovy index b236ce84bab..f8d1d70ae17 100644 --- a/dd-trace-api/src/test/groovy/datadog/trace/api/DDTraceIdTest.groovy +++ b/dd-trace-api/src/test/groovy/datadog/trace/api/DDTraceIdTest.groovy @@ -189,4 +189,14 @@ class DDTraceIdTest extends DDSpecification { // Too long id "1" * 33 | 0 | 33 | true } + + def "check ZERO constant initialization"() { + when: + def zero = DDTraceId.ZERO + def fromZero = DDTraceId.from(0) + + then: + zero != null + zero.is(fromZero) + } } diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/B3TraceId.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/B3TraceId.java index 875e6220605..a9376cd6597 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/B3TraceId.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/B3TraceId.java @@ -4,7 +4,7 @@ import datadog.trace.api.DDTraceId; /** A B3 {@link DDTraceId} along with its original {@link String} representation. */ -public class B3TraceId implements DDTraceId { +public class B3TraceId extends DDTraceId { /** The original {@link String} representation. */ protected final String original;