优化
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HexFormat;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Strict W3C {@code traceparent} version 00 value.
|
||||
*
|
||||
* <p>This type deliberately accepts only the currently frozen version-00 shape. Unsupported,
|
||||
* ambiguous or malformed input must start a new trace instead of being partially trusted.</p>
|
||||
*/
|
||||
public record TraceParent(String traceId, String parentId, String traceFlags) {
|
||||
public static final String HEADER = "traceparent";
|
||||
public static final int HEADER_LENGTH = 55;
|
||||
|
||||
private static final Pattern VERSION_00 = Pattern.compile(
|
||||
"00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})");
|
||||
private static final Pattern LEGACY_TRACE_ID = Pattern.compile("[0-9A-Fa-f]{32}");
|
||||
private static final String ZERO_TRACE_ID = "0".repeat(32);
|
||||
private static final String ZERO_PARENT_ID = "0".repeat(16);
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
private static final HexFormat HEX = HexFormat.of();
|
||||
|
||||
public TraceParent {
|
||||
if (!validTraceId(traceId) || !validParentId(parentId)
|
||||
|| traceFlags == null || !traceFlags.matches("[0-9a-f]{2}")) {
|
||||
throw new IllegalArgumentException("Invalid W3C traceparent components");
|
||||
}
|
||||
}
|
||||
|
||||
/** Parses one exact, lowercase W3C version-00 header value. */
|
||||
public static Optional<TraceParent> parse(String value) {
|
||||
if (value == null || value.length() != HEADER_LENGTH) {
|
||||
return Optional.empty();
|
||||
}
|
||||
Matcher matcher = VERSION_00.matcher(value);
|
||||
if (!matcher.matches() || !validTraceId(matcher.group(1)) || !validParentId(matcher.group(2))) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(new TraceParent(matcher.group(1), matcher.group(2), matcher.group(3)));
|
||||
}
|
||||
|
||||
/** Creates the local inbound context for a valid remote parent. */
|
||||
public static TraceParent childOf(TraceParent remoteParent) {
|
||||
return new TraceParent(remoteParent.traceId(), randomNonZero(8), remoteParent.traceFlags());
|
||||
}
|
||||
|
||||
/** Creates a new root context, optionally reusing a valid legacy trace ID. */
|
||||
public static TraceParent newRoot(String legacyTraceId) {
|
||||
String traceId = validLegacyTraceId(legacyTraceId)
|
||||
? legacyTraceId.toLowerCase(java.util.Locale.ROOT) : randomNonZero(16);
|
||||
return new TraceParent(traceId, randomNonZero(8), "00");
|
||||
}
|
||||
|
||||
public static boolean validLegacyTraceId(String value) {
|
||||
return value != null && LEGACY_TRACE_ID.matcher(value).matches()
|
||||
&& !ZERO_TRACE_ID.equalsIgnoreCase(value);
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return "00-" + traceId + '-' + parentId + '-' + traceFlags;
|
||||
}
|
||||
|
||||
private static boolean validTraceId(String value) {
|
||||
return value != null && value.matches("[0-9a-f]{32}") && !ZERO_TRACE_ID.equals(value);
|
||||
}
|
||||
|
||||
private static boolean validParentId(String value) {
|
||||
return value != null && value.matches("[0-9a-f]{16}") && !ZERO_PARENT_ID.equals(value);
|
||||
}
|
||||
|
||||
private static String randomNonZero(int byteCount) {
|
||||
byte[] bytes = new byte[byteCount];
|
||||
String value;
|
||||
do {
|
||||
RANDOM.nextBytes(bytes);
|
||||
value = HEX.formatHex(bytes);
|
||||
} while (value.chars().allMatch(character -> character == '0'));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user