From 4c466f7eb964227ad7b661ec5895dbcd92ba217c Mon Sep 17 00:00:00 2001 From: way zheng Date: Fri, 5 Dec 2025 18:58:37 -0800 Subject: [PATCH 1/4] add debugging messges --- src/test/java/app/component/Operator.java | 74 +++++++++++++++++- src/test/java/common/HttpClient.java | 95 ++++++++++++++++++++++- 2 files changed, 164 insertions(+), 5 deletions(-) diff --git a/src/test/java/app/component/Operator.java b/src/test/java/app/component/Operator.java index 493a123..b6b59a3 100644 --- a/src/test/java/app/component/Operator.java +++ b/src/test/java/app/component/Operator.java @@ -11,6 +11,8 @@ import lombok.Getter; import okhttp3.Request; import okhttp3.RequestBody; +import org.junit.platform.commons.logging.Logger; +import org.junit.platform.commons.logging.LoggerFactory; import javax.crypto.*; import javax.crypto.spec.GCMParameterSpec; @@ -68,6 +70,7 @@ private record V2Envelope(String envelope, byte[] nonce) { // When running via IntelliJ, environment variables are defined in the uid2-dev-workspace repo under .idea/runConfigurations. // Test data is defined in the uid2-admin repo. + private static final Logger LOGGER = LoggerFactory.getLogger(Operator.class); private static final ObjectMapper OBJECT_MAPPER = Mapper.getInstance(); private static final SecureRandom SECURE_RANDOM = new SecureRandom(); private static final int TIMESTAMP_LENGTH = 8; @@ -78,6 +81,27 @@ private record V2Envelope(String envelope, byte[] nonce) { public static final String CLIENT_API_KEY = EnvUtil.getEnv(Const.Config.Operator.CLIENT_API_KEY); public static final String CLIENT_API_SECRET = EnvUtil.getEnv(Const.Config.Operator.CLIENT_API_SECRET); + + static { + // Log operator configuration at class initialization + String maskedKey = CLIENT_API_KEY != null && CLIENT_API_KEY.length() > 20 + ? CLIENT_API_KEY.substring(0, 10) + "..." + CLIENT_API_KEY.substring(CLIENT_API_KEY.length() - 10) + : "[null or too short]"; + String maskedSecret = CLIENT_API_SECRET != null && CLIENT_API_SECRET.length() > 20 + ? CLIENT_API_SECRET.substring(0, 10) + "..." + CLIENT_API_SECRET.substring(CLIENT_API_SECRET.length() - 10) + : "[null or too short]"; + LOGGER.info(() -> String.format( + "[OPERATOR CONFIG] Initialized with:%n" + + " CLIENT_API_KEY: %s (length: %d)%n" + + " CLIENT_API_SECRET: %s (length: %d)%n" + + " E2E_ENV: %s%n" + + " IDENTITY_SCOPE: %s", + maskedKey, CLIENT_API_KEY != null ? CLIENT_API_KEY.length() : 0, + maskedSecret, CLIENT_API_SECRET != null ? CLIENT_API_SECRET.length() : 0, + EnvUtil.getEnv(Const.Config.ENV, false), + EnvUtil.getEnv(Const.Config.IDENTITY_SCOPE, false) + )); + } // Local only - Sharing public static final String CLIENT_API_KEY_SHARING_RECIPIENT = EnvUtil.getEnv(Const.Config.Operator.CLIENT_API_KEY_SHARING_RECIPIENT, EnabledCondition.isLocal()); @@ -274,9 +298,55 @@ public IdentityMapResponse v2IdentityMap(IdentityMapInput input) { // Need to use the manual mapping for error cases - SDK won't allow creating input with bad emails public JsonNode v3IdentityMap(String payload) throws Exception { + String baseUrl = getBaseUrl(); + String endpoint = baseUrl + "/v3/identity/map"; + + LOGGER.info(() -> String.format( + "[v3IdentityMap] Preparing request:%n" + + " Operator Name: %s%n" + + " Operator Type: %s%n" + + " Base URL: %s%n" + + " Full Endpoint: %s%n" + + " CLIENT_API_KEY: %s (length: %d)%n" + + " CLIENT_API_SECRET: %s (length: %d)%n" + + " Payload (raw): %s", + getName(), type, baseUrl, endpoint, + CLIENT_API_KEY != null ? CLIENT_API_KEY.substring(0, Math.min(20, CLIENT_API_KEY.length())) + "..." : "[null]", + CLIENT_API_KEY != null ? CLIENT_API_KEY.length() : 0, + CLIENT_API_SECRET != null ? CLIENT_API_SECRET.substring(0, Math.min(20, CLIENT_API_SECRET.length())) + "..." : "[null]", + CLIENT_API_SECRET != null ? CLIENT_API_SECRET.length() : 0, + payload != null && payload.length() > 200 ? payload.substring(0, 200) + "..." : payload + )); + V2Envelope envelope = v2CreateEnvelope(payload, CLIENT_API_SECRET); - String encryptedResponse = HttpClient.post(getBaseUrl() + "/v3/identity/map", envelope.envelope(), CLIENT_API_KEY); - return v2DecryptEncryptedResponse(encryptedResponse, envelope.nonce(), CLIENT_API_SECRET); + + LOGGER.info(() -> String.format( + "[v3IdentityMap] Created envelope:%n" + + " Envelope length: %d%n" + + " Nonce length: %d", + envelope.envelope().length(), + envelope.nonce().length + )); + + try { + String encryptedResponse = HttpClient.post(endpoint, envelope.envelope(), CLIENT_API_KEY); + LOGGER.info(() -> String.format( + "[v3IdentityMap] Request successful, response length: %d", + encryptedResponse != null ? encryptedResponse.length() : 0 + )); + return v2DecryptEncryptedResponse(encryptedResponse, envelope.nonce(), CLIENT_API_SECRET); + } catch (Exception e) { + final String errorMsg = e.getMessage(); + final String errorType = e.getClass().getName(); + LOGGER.error(() -> String.format( + "[v3IdentityMap] Request failed:%n" + + " Endpoint: %s%n" + + " Error: %s%n" + + " Error Type: %s", + endpoint, errorMsg, errorType + )); + throw e; + } } public IdentityMapV3Response v3IdentityMap(IdentityMapV3Input input) { diff --git a/src/test/java/common/HttpClient.java b/src/test/java/common/HttpClient.java index 47ab050..48cb40a 100644 --- a/src/test/java/common/HttpClient.java +++ b/src/test/java/common/HttpClient.java @@ -5,11 +5,13 @@ import com.uid2.shared.util.Mapper; import lombok.Getter; import okhttp3.*; +import org.junit.platform.commons.logging.Logger; +import org.junit.platform.commons.logging.LoggerFactory; import java.util.Map; -import java.util.Objects; public final class HttpClient { + private static final Logger LOGGER = LoggerFactory.getLogger(HttpClient.class); private static final ObjectMapper OBJECT_MAPPER = Mapper.getInstance(); public static final OkHttpClient RAW_CLIENT = new OkHttpClient(); @@ -71,11 +73,98 @@ public static String post(String url, String body, String bearerToken) throws Ex } public static String execute(Request request, HttpMethod method) throws Exception { + final String url = request.url().toString(); + final String requestBody = extractRequestBody(request); + final String authHeader = extractAuthHeader(request); + final Headers headers = request.headers(); + + LOGGER.info(() -> String.format( + "[HTTP REQUEST] %s %s%n" + + " Authorization: %s%n" + + " Request Body: %s%n" + + " Headers: %s", + method, url, + authHeader, + requestBody, + headers.toString() + )); + try (Response response = RAW_CLIENT.newCall(request).execute()) { + final ResponseBody body = response.body(); + final String responseBody = extractResponseBody(body); + final int statusCode = response.code(); + final String statusMessage = response.message(); + final Headers responseHeaders = response.headers(); + + LOGGER.info(() -> String.format( + "[HTTP RESPONSE] %s %s%n" + + " Status: %d %s%n" + + " Response Headers: %s%n" + + " Response Body: %s", + method, url, + statusCode, statusMessage, + responseHeaders.toString(), + responseBody + )); + if (!response.isSuccessful()) { - throw new HttpException(method, request.url().toString(), response.code(), response.message(), Objects.requireNonNull(response.body()).string()); + LOGGER.error(() -> String.format( + "[HTTP ERROR] Request failed: %s %s - Status: %d %s - Response: %s", + method, url, statusCode, statusMessage, responseBody + )); + throw new HttpException(method, url, statusCode, statusMessage, responseBody); } - return Objects.requireNonNull(response.body()).string(); + return responseBody; + } + } + + private static String extractRequestBody(Request request) { + if (request.body() == null) { + return "[empty]"; + } + try { + okio.Buffer buffer = new okio.Buffer(); + request.body().writeTo(buffer); + String body = buffer.readUtf8(); + // Truncate very long bodies for readability + if (body.length() > 500) { + return body.substring(0, 500) + "... [truncated, length=" + body.length() + "]"; + } + return body; + } catch (Exception e) { + return "[unable to read request body: " + e.getMessage() + "]"; + } + } + + private static String extractAuthHeader(Request request) { + Headers headers = request.headers(); + for (int i = 0; i < headers.size(); i++) { + if ("Authorization".equalsIgnoreCase(headers.name(i))) { + String authValue = headers.value(i); + // Mask the token for security, but show first/last few chars + if (authValue.length() > 20) { + return authValue.substring(0, 10) + "..." + authValue.substring(authValue.length() - 10); + } else { + return "[masked]"; + } + } + } + return "[none]"; + } + + private static String extractResponseBody(ResponseBody body) { + if (body == null) { + return "[empty]"; + } + try { + String bodyString = body.string(); + // Truncate very long responses + if (bodyString.length() > 1000) { + return bodyString.substring(0, 1000) + "... [truncated, length=" + bodyString.length() + "]"; + } + return bodyString; + } catch (Exception e) { + return "[unable to read response body: " + e.getMessage() + "]"; } } From 3bcb705431006e6c07a1f7071af6f07fa2c3fd21 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sat, 6 Dec 2025 03:15:57 +0000 Subject: [PATCH 2/4] [CI Pipeline] Released Snapshot version: 4.1.1-alpha-71-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fc897e2..f3cf7c1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-e2e - 4.1.0 + 4.1.1-alpha-71-SNAPSHOT 21 From bb5703c3d2b546f93874cab944f28a4a322baecb Mon Sep 17 00:00:00 2001 From: way zheng Date: Fri, 5 Dec 2025 20:10:35 -0800 Subject: [PATCH 3/4] add debugging messges --- src/test/java/common/HttpClient.java | 53 +++++++++++++--------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/src/test/java/common/HttpClient.java b/src/test/java/common/HttpClient.java index 48cb40a..94c29d3 100644 --- a/src/test/java/common/HttpClient.java +++ b/src/test/java/common/HttpClient.java @@ -74,7 +74,7 @@ public static String post(String url, String body, String bearerToken) throws Ex public static String execute(Request request, HttpMethod method) throws Exception { final String url = request.url().toString(); - final String requestBody = extractRequestBody(request); + final String requestBodyForLog = extractRequestBodyForLog(request); final String authHeader = extractAuthHeader(request); final Headers headers = request.headers(); @@ -85,17 +85,21 @@ public static String execute(Request request, HttpMethod method) throws Exceptio " Headers: %s", method, url, authHeader, - requestBody, + requestBodyForLog, headers.toString() )); try (Response response = RAW_CLIENT.newCall(request).execute()) { final ResponseBody body = response.body(); - final String responseBody = extractResponseBody(body); + // Read the FULL response body - don't truncate the actual data! + final String fullResponseBody = (body != null) ? body.string() : ""; final int statusCode = response.code(); final String statusMessage = response.message(); final Headers responseHeaders = response.headers(); + // Only truncate for logging display + final String responseBodyForLog = truncateForLog(fullResponseBody, 1000); + LOGGER.info(() -> String.format( "[HTTP RESPONSE] %s %s%n" + " Status: %d %s%n" + @@ -104,21 +108,32 @@ public static String execute(Request request, HttpMethod method) throws Exceptio method, url, statusCode, statusMessage, responseHeaders.toString(), - responseBody + responseBodyForLog )); if (!response.isSuccessful()) { LOGGER.error(() -> String.format( "[HTTP ERROR] Request failed: %s %s - Status: %d %s - Response: %s", - method, url, statusCode, statusMessage, responseBody + method, url, statusCode, statusMessage, responseBodyForLog )); - throw new HttpException(method, url, statusCode, statusMessage, responseBody); + throw new HttpException(method, url, statusCode, statusMessage, fullResponseBody); } - return responseBody; + // Return the FULL response body, not truncated + return fullResponseBody; + } + } + + private static String truncateForLog(String text, int maxLength) { + if (text == null || text.isEmpty()) { + return "[empty]"; + } + if (text.length() > maxLength) { + return text.substring(0, maxLength) + "... [truncated, total length=" + text.length() + "]"; } + return text; } - private static String extractRequestBody(Request request) { + private static String extractRequestBodyForLog(Request request) { if (request.body() == null) { return "[empty]"; } @@ -126,11 +141,7 @@ private static String extractRequestBody(Request request) { okio.Buffer buffer = new okio.Buffer(); request.body().writeTo(buffer); String body = buffer.readUtf8(); - // Truncate very long bodies for readability - if (body.length() > 500) { - return body.substring(0, 500) + "... [truncated, length=" + body.length() + "]"; - } - return body; + return truncateForLog(body, 500); } catch (Exception e) { return "[unable to read request body: " + e.getMessage() + "]"; } @@ -151,22 +162,6 @@ private static String extractAuthHeader(Request request) { } return "[none]"; } - - private static String extractResponseBody(ResponseBody body) { - if (body == null) { - return "[empty]"; - } - try { - String bodyString = body.string(); - // Truncate very long responses - if (bodyString.length() > 1000) { - return bodyString.substring(0, 1000) + "... [truncated, length=" + bodyString.length() + "]"; - } - return bodyString; - } catch (Exception e) { - return "[unable to read response body: " + e.getMessage() + "]"; - } - } private static Request buildRequest(HttpMethod method, String url, String body, String bearerToken) { return buildRequest(method, url, body, bearerToken, null); From f2c0af867d9d93a0e67755deca2414bfe45adad7 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sat, 6 Dec 2025 04:12:39 +0000 Subject: [PATCH 4/4] [CI Pipeline] Released Snapshot version: 4.1.2-alpha-72-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f3cf7c1..aa8a8f1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-e2e - 4.1.1-alpha-71-SNAPSHOT + 4.1.2-alpha-72-SNAPSHOT 21