From 84cb6dfdfe5564d62605ef15666c83a8aafd889c Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Mon, 2 Feb 2026 15:12:36 +0530 Subject: [PATCH 1/9] aadarsh-st/SK-2521-Enhance content-type handling and add validation tests for request bodies --- src/main/java/com/skyflow/logs/InfoLogs.java | 2 +- .../java/com/skyflow/utils/HttpUtility.java | 23 ++- src/main/java/com/skyflow/utils/Utils.java | 17 ++- .../utils/validations/Validations.java | 28 +++- .../controller/ConnectionController.java | 46 ++++-- .../com/skyflow/utils/HttpUtilityTests.java | 67 +++++++++ .../connection/InvokeConnectionTests.java | 141 ++++++++++++++++++ .../controller/ConnectionControllerTests.java | 89 +++++++++++ 8 files changed, 391 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/skyflow/logs/InfoLogs.java b/src/main/java/com/skyflow/logs/InfoLogs.java index f71fc416..18363670 100644 --- a/src/main/java/com/skyflow/logs/InfoLogs.java +++ b/src/main/java/com/skyflow/logs/InfoLogs.java @@ -14,7 +14,7 @@ public enum InfoLogs { // Bearer token generation EMPTY_BEARER_TOKEN("Bearer token is empty."), - BEARER_TOKEN_EXPIRED("Bearer token is expired."), + BEARER_TOKEN_EXPIRED("Bearer token is invalid or expired."), GET_BEARER_TOKEN_TRIGGERED("getBearerToken method triggered."), GET_BEARER_TOKEN_SUCCESS("Bearer token generated."), GET_SIGNED_DATA_TOKENS_TRIGGERED("getSignedDataTokens method triggered."), diff --git a/src/main/java/com/skyflow/utils/HttpUtility.java b/src/main/java/com/skyflow/utils/HttpUtility.java index b8e9283b..93269993 100644 --- a/src/main/java/com/skyflow/utils/HttpUtility.java +++ b/src/main/java/com/skyflow/utils/HttpUtility.java @@ -7,6 +7,7 @@ import java.io.*; import java.net.HttpURLConnection; import java.net.URL; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; @@ -32,9 +33,14 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< try { connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod(method); - connection.setRequestProperty("content-type", "application/json"); connection.setRequestProperty("Accept", "*/*"); + // Set default content-type if not provided in headers + boolean hasContentType = headers != null && headers.containsKey("content-type"); + if (!hasContentType && params != null && !params.isEmpty()) { + connection.setRequestProperty("content-type", "application/json"); + } + if (headers != null && !headers.isEmpty()) { for (Map.Entry entry : headers.entrySet()) connection.setRequestProperty(entry.getKey(), entry.getValue()); @@ -52,9 +58,12 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< byte[] input = null; String requestContentType = connection.getRequestProperty("content-type"); - if (requestContentType.contains("application/x-www-form-urlencoded")) { + // Check if this is a raw body (XML, plain text, etc.) + if (params.has("__raw_body__") && params.size() == 1) { + input = params.get("__raw_body__").getAsString().getBytes(StandardCharsets.UTF_8); + } else if (requestContentType != null && requestContentType.contains("application/x-www-form-urlencoded")) { input = formatJsonToFormEncodedString(params).getBytes(StandardCharsets.UTF_8); - } else if (requestContentType.contains("multipart/form-data")) { + } else if (requestContentType != null && requestContentType.contains("multipart/form-data")) { input = formatJsonToMultiPartFormDataString(params, boundary).getBytes(StandardCharsets.UTF_8); } else { input = params.toString().getBytes(StandardCharsets.UTF_8); @@ -159,7 +168,13 @@ public static String appendRequestId(String message, String requestId) { } private static String makeFormEncodeKeyValuePair(String key, String value) { - return key + "=" + value + "&"; + try { + String encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.toString()); + String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); + return encodedKey + "=" + encodedValue + "&"; + } catch (Exception e) { + return key + "=" + value + "&"; + } } } diff --git a/src/main/java/com/skyflow/utils/Utils.java b/src/main/java/com/skyflow/utils/Utils.java index 165c6a80..d6456466 100644 --- a/src/main/java/com/skyflow/utils/Utils.java +++ b/src/main/java/com/skyflow/utils/Utils.java @@ -17,6 +17,8 @@ import java.io.File; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; @@ -110,7 +112,12 @@ public static String constructConnectionURL(ConnectionConfig config, InvokeConne for (Map.Entry entry : invokeConnectionRequest.getPathParams().entrySet()) { String key = entry.getKey(); String value = entry.getValue(); - filledURL = new StringBuilder(filledURL.toString().replace(String.format("{%s}", key), value)); + try { + String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); + filledURL = new StringBuilder(filledURL.toString().replace(String.format("{%s}", key), encodedValue)); + } catch (Exception e) { + filledURL = new StringBuilder(filledURL.toString().replace(String.format("{%s}", key), value)); + } } } @@ -119,7 +126,13 @@ public static String constructConnectionURL(ConnectionConfig config, InvokeConne for (Map.Entry entry : invokeConnectionRequest.getQueryParams().entrySet()) { String key = entry.getKey(); String value = entry.getValue(); - filledURL.append(key).append("=").append(value).append("&"); + try { + String encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.toString()); + String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); + filledURL.append(encodedKey).append("=").append(encodedValue).append("&"); + } catch (Exception e) { + filledURL.append(key).append("=").append(value).append("&"); + } } filledURL = new StringBuilder(filledURL.substring(0, filledURL.length() - 1)); } diff --git a/src/main/java/com/skyflow/utils/validations/Validations.java b/src/main/java/com/skyflow/utils/validations/Validations.java index 0372749a..4c403b3b 100644 --- a/src/main/java/com/skyflow/utils/validations/Validations.java +++ b/src/main/java/com/skyflow/utils/validations/Validations.java @@ -1,6 +1,7 @@ package com.skyflow.utils.validations; import com.google.gson.Gson; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.skyflow.config.ConnectionConfig; import com.skyflow.config.Credentials; @@ -137,12 +138,27 @@ public static void validateInvokeConnectionRequest(InvokeConnectionRequest invok } if (requestBody != null) { - Gson gson = new Gson(); - JsonObject bodyObject = gson.toJsonTree(requestBody).getAsJsonObject(); - if (bodyObject.isEmpty()) { - LogUtil.printErrorLog(Utils.parameterizedString( - ErrorLogs.EMPTY_REQUEST_BODY.getLog(), InterfaceName.INVOKE_CONNECTION.getName())); - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyRequestBody.getMessage()); + if (requestBody.getClass().equals(Object.class)) { + return; + } + if (requestBody instanceof String) { + String bodyStr = (String) requestBody; + if (bodyStr.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.EMPTY_REQUEST_BODY.getLog(), InterfaceName.INVOKE_CONNECTION.getName())); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyRequestBody.getMessage()); + } + } else { + Gson gson = new Gson(); + JsonElement bodyElement = gson.toJsonTree(requestBody); + if (bodyElement.isJsonObject()) { + JsonObject bodyObject = bodyElement.getAsJsonObject(); + if (bodyObject.isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.EMPTY_REQUEST_BODY.getLog(), InterfaceName.INVOKE_CONNECTION.getName())); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyRequestBody.getMessage()); + } + } } } } diff --git a/src/main/java/com/skyflow/vault/controller/ConnectionController.java b/src/main/java/com/skyflow/vault/controller/ConnectionController.java index 4a9334d4..3734aceb 100644 --- a/src/main/java/com/skyflow/vault/controller/ConnectionController.java +++ b/src/main/java/com/skyflow/vault/controller/ConnectionController.java @@ -51,20 +51,48 @@ public InvokeConnectionResponse invoke(InvokeConnectionRequest invokeConnectionR headers.put(Constants.SDK_METRICS_HEADER_KEY, Utils.getMetrics().toString()); RequestMethod requestMethod = invokeConnectionRequest.getMethod(); - JsonObject requestBody = null; Object requestBodyObject = invokeConnectionRequest.getRequestBody(); + String contentType = headers + .getOrDefault("content-type", "application/json") + .toLowerCase(); + boolean isJsonRequest = contentType.contains("application/json"); - if (requestBodyObject != null) { - try { - requestBody = convertObjectToJson(requestBodyObject); - } catch (Exception e) { - LogUtil.printErrorLog(ErrorLogs.INVALID_REQUEST_HEADERS.getLog()); - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidRequestBody.getMessage()); + Object finalPayload; + + try { + if (requestBodyObject instanceof String) { + if (isJsonRequest) { + JsonObject jsonWrapper = new JsonObject(); + jsonWrapper.addProperty( + "__raw_body__", + (String) requestBodyObject + ); + finalPayload = jsonWrapper; + } else { + finalPayload = requestBodyObject; + } + } else if (requestBodyObject instanceof JsonObject || requestBodyObject == null) { + finalPayload = requestBodyObject; + } else { + finalPayload = convertObjectToJson(requestBodyObject); } + } catch (Exception e) { + LogUtil.printErrorLog(ErrorLogs.INVALID_REQUEST_HEADERS.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidRequestBody.getMessage()); + } + JsonObject payloadToSend; + if (finalPayload instanceof JsonObject || finalPayload == null) { + payloadToSend = (JsonObject) finalPayload; + } else { + payloadToSend = new JsonObject(); + payloadToSend.addProperty("__raw_body__", finalPayload.toString()); } - String response = HttpUtility.sendRequest(requestMethod.name(), new URL(filledURL), requestBody, headers); - JsonObject data = JsonParser.parseString(response).getAsJsonObject(); + String response = HttpUtility.sendRequest(requestMethod.name(), new URL(filledURL), payloadToSend, headers); + Object data = response; + try { + data = JsonParser.parseString(response).getAsJsonObject(); + } catch (Exception ignored) {} HashMap metadata = new HashMap<>(); metadata.put("requestId", HttpUtility.getRequestID()); connectionResponse = new InvokeConnectionResponse(data, metadata, null); diff --git a/src/test/java/com/skyflow/utils/HttpUtilityTests.java b/src/test/java/com/skyflow/utils/HttpUtilityTests.java index f7214690..5f7271e1 100644 --- a/src/test/java/com/skyflow/utils/HttpUtilityTests.java +++ b/src/test/java/com/skyflow/utils/HttpUtilityTests.java @@ -124,4 +124,71 @@ public void testSendRequestError() { fail(INVALID_EXCEPTION_THROWN); } } + + // New test cases for content-type handling changes + + @Test + @PrepareForTest({URL.class, HttpURLConnection.class}) + public void testSendRequestWithRawBody() { + try { + given(mockConnection.getRequestProperty("content-type")).willReturn("application/xml"); + Map headers = new HashMap<>(); + headers.put("content-type", "application/xml"); + JsonObject params = new JsonObject(); + params.addProperty("__raw_body__", "test"); + String response = httpUtility.sendRequest("POST", url, params, headers); + Assert.assertEquals(expected, response); + } catch (Exception e) { + fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + @PrepareForTest({URL.class, HttpURLConnection.class}) + public void testSendRequestWithoutContentTypeHeader() { + try { + given(mockConnection.getRequestProperty("content-type")).willReturn("application/json"); + JsonObject params = new JsonObject(); + params.addProperty("key", "value"); + String response = httpUtility.sendRequest("POST", url, params, null); + Assert.assertEquals(expected, response); + } catch (Exception e) { + fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + @PrepareForTest({URL.class, HttpURLConnection.class}) + public void testSendRequestWithNullRequestId() { + try { + given(mockConnection.getHeaderField(anyString())).willReturn(null); + given(mockConnection.getRequestProperty("content-type")).willReturn("application/json"); + Map headers = new HashMap<>(); + headers.put("content-type", "application/json"); + JsonObject params = new JsonObject(); + params.addProperty("key", "value"); + String response = httpUtility.sendRequest("GET", url, params, headers); + Assert.assertEquals(expected, response); + Assert.assertNotNull(HttpUtility.getRequestID()); + } catch (Exception e) { + fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + @PrepareForTest({URL.class, HttpURLConnection.class}) + public void testSendRequestFormURLEncodedWithSpecialCharacters() { + try { + given(mockConnection.getRequestProperty("content-type")).willReturn("application/x-www-form-urlencoded"); + Map headers = new HashMap<>(); + headers.put("content-type", "application/x-www-form-urlencoded"); + JsonObject params = new JsonObject(); + params.addProperty("key", "value with spaces"); + params.addProperty("special", "test@email.com"); + String response = httpUtility.sendRequest("POST", url, params, headers); + Assert.assertEquals(expected, response); + } catch (Exception e) { + fail(INVALID_EXCEPTION_THROWN); + } + } } diff --git a/src/test/java/com/skyflow/vault/connection/InvokeConnectionTests.java b/src/test/java/com/skyflow/vault/connection/InvokeConnectionTests.java index 63717b5c..e87d7877 100644 --- a/src/test/java/com/skyflow/vault/connection/InvokeConnectionTests.java +++ b/src/test/java/com/skyflow/vault/connection/InvokeConnectionTests.java @@ -437,4 +437,145 @@ public void testInvokeConnectionResponse() { Assert.fail(INVALID_EXCEPTION_THROWN); } } + + // New test cases for content-type handling changes + + @Test + public void testValidStringRequestBodyInInvokeConnectionRequestValidations() { + try { + String xmlBody = "test"; + requestHeaders.put("Content-Type", "application/xml"); + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestHeaders(requestHeaders) + .requestBody(xmlBody) + .build(); + Validations.validateInvokeConnectionRequest(request); + Assert.assertTrue(request.getRequestBody() instanceof String); + Assert.assertEquals(xmlBody, request.getRequestBody()); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testEmptyStringRequestBodyInInvokeConnectionRequestValidations() { + try { + String emptyBody = ""; + requestHeaders.put("Content-Type", "application/xml"); + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestHeaders(requestHeaders) + .requestBody(emptyBody) + .build(); + Validations.validateInvokeConnectionRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals(ErrorMessage.EmptyRequestBody.getMessage(), e.getMessage()); + } + } + + @Test + public void testWhitespaceOnlyStringRequestBodyInInvokeConnectionRequestValidations() { + try { + String whitespaceBody = " \n\t "; + requestHeaders.put("Content-Type", "application/xml"); + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestHeaders(requestHeaders) + .requestBody(whitespaceBody) + .build(); + Validations.validateInvokeConnectionRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals(ErrorMessage.EmptyRequestBody.getMessage(), e.getMessage()); + } + } + + @Test + public void testXMLStringRequestBodyInInvokeConnectionRequestValidations() { + try { + String xmlBody = "4111111111111111"; + requestHeaders.put("Content-Type", "application/xml"); + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestHeaders(requestHeaders) + .requestBody(xmlBody) + .build(); + Validations.validateInvokeConnectionRequest(request); + Assert.assertTrue(request.getRequestBody() instanceof String); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testPlainTextRequestBodyInInvokeConnectionRequestValidations() { + try { + String plainText = "This is a plain text request body with some data"; + requestHeaders.put("Content-Type", "text/plain"); + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestHeaders(requestHeaders) + .requestBody(plainText) + .build(); + Validations.validateInvokeConnectionRequest(request); + Assert.assertTrue(request.getRequestBody() instanceof String); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testHTMLRequestBodyInInvokeConnectionRequestValidations() { + try { + String htmlBody = "

Processing Payment

"; + requestHeaders.put("Content-Type", "text/html"); + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestHeaders(requestHeaders) + .requestBody(htmlBody) + .build(); + Validations.validateInvokeConnectionRequest(request); + Assert.assertTrue(request.getRequestBody() instanceof String); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testInvokeConnectionResponseWithStringData() { + try { + String xmlData = "success"; + HashMap metadata = new HashMap<>(); + metadata.put("requestId", "xml-12345"); + InvokeConnectionResponse connectionResponse = new InvokeConnectionResponse(xmlData, metadata, null); + + Assert.assertNotNull(connectionResponse.getData()); + Assert.assertTrue(connectionResponse.getData() instanceof String); + Assert.assertEquals(xmlData, connectionResponse.getData()); + Assert.assertEquals("xml-12345", connectionResponse.getMetadata().get("requestId")); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testRequestBodyWithSpecialCharacters() { + try { + String bodyWithSpecialChars = "card_number=4111111111111111&exp_month=12&exp_year=2025&cvv=123"; + requestHeaders.put("Content-Type", "application/x-www-form-urlencoded"); + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestHeaders(requestHeaders) + .requestBody(bodyWithSpecialChars) + .build(); + Validations.validateInvokeConnectionRequest(request); + Assert.assertTrue(request.getRequestBody() instanceof String); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } } diff --git a/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java b/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java index b121280a..750b0ebe 100644 --- a/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java +++ b/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java @@ -49,4 +49,93 @@ public void testInvalidRequestInInvokeConnectionMethod() { Assert.assertEquals(ErrorMessage.EmptyRequestBody.getMessage(), e.getMessage()); } } + + // New test cases for content-type handling changes + + @Test + public void testInvokeConnectionWithStringRequestBody() { + try { + String xmlBody = "test"; + HashMap headers = new HashMap<>(); + headers.put("Content-Type", "application/xml"); + InvokeConnectionRequest connectionRequest = InvokeConnectionRequest.builder() + .requestBody(xmlBody) + .requestHeaders(headers) + .build(); + Assert.assertNotNull(connectionRequest.getRequestBody()); + Assert.assertTrue(connectionRequest.getRequestBody() instanceof String); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testInvokeConnectionWithEmptyStringRequestBody() { + try { + String emptyBody = ""; + HashMap headers = new HashMap<>(); + headers.put("Content-Type", "application/xml"); + InvokeConnectionRequest connectionRequest = InvokeConnectionRequest.builder() + .requestBody(emptyBody) + .requestHeaders(headers) + .build(); + Skyflow skyflowClient = Skyflow.builder().setLogLevel(LogLevel.DEBUG).addConnectionConfig(connectionConfig).build(); + skyflowClient.connection().invoke(connectionRequest); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals(ErrorMessage.EmptyRequestBody.getMessage(), e.getMessage()); + } + } + + @Test + public void testInvokeConnectionWithXMLContentType() { + try { + String xmlBody = "4111111111111111"; + HashMap headers = new HashMap<>(); + headers.put("Content-Type", "application/xml"); + InvokeConnectionRequest connectionRequest = InvokeConnectionRequest.builder() + .requestBody(xmlBody) + .requestHeaders(headers) + .build(); + Assert.assertEquals("application/xml", connectionRequest.getRequestHeaders().get("Content-Type")); + Assert.assertTrue(connectionRequest.getRequestBody() instanceof String); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testInvokeConnectionWithPlainTextContentType() { + try { + String plainTextBody = "This is a plain text request body"; + HashMap headers = new HashMap<>(); + headers.put("Content-Type", "text/plain"); + InvokeConnectionRequest connectionRequest = InvokeConnectionRequest.builder() + .requestBody(plainTextBody) + .requestHeaders(headers) + .build(); + Assert.assertEquals("text/plain", connectionRequest.getRequestHeaders().get("Content-Type")); + Assert.assertTrue(connectionRequest.getRequestBody() instanceof String); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testInvokeConnectionWithHTMLContentType() { + try { + String htmlBody = "

Test

"; + HashMap headers = new HashMap<>(); + headers.put("Content-Type", "text/html"); + InvokeConnectionRequest connectionRequest = InvokeConnectionRequest.builder() + .requestBody(htmlBody) + .requestHeaders(headers) + .build(); + Assert.assertEquals("text/html", connectionRequest.getRequestHeaders().get("Content-Type")); + Assert.assertTrue(connectionRequest.getRequestBody() instanceof String); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } } From 834b79ea33a186ff0a52f7f1e755342ea09dd1ab Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Mon, 2 Feb 2026 15:47:02 +0530 Subject: [PATCH 2/9] aadarsh-st/SK-2521:Fixed copilot comments --- src/main/java/com/skyflow/utils/HttpUtility.java | 8 ++++++-- src/main/java/com/skyflow/utils/Utils.java | 6 +++--- .../skyflow/vault/controller/ConnectionController.java | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/skyflow/utils/HttpUtility.java b/src/main/java/com/skyflow/utils/HttpUtility.java index 93269993..4cb98338 100644 --- a/src/main/java/com/skyflow/utils/HttpUtility.java +++ b/src/main/java/com/skyflow/utils/HttpUtility.java @@ -76,14 +76,18 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< int httpCode = connection.getResponseCode(); String requestID = connection.getHeaderField("x-request-id"); - HttpUtility.requestID = requestID.split(",")[0]; + if (requestID != null) { + HttpUtility.requestID = requestID.split(",")[0]; + } else { + HttpUtility.requestID = "Internal-SDK-" + UUID.randomUUID(); + } Map> responseHeaders = connection.getHeaderFields(); Reader streamReader; if (httpCode > 299) { if (connection.getErrorStream() != null) streamReader = new InputStreamReader(connection.getErrorStream()); else { - String description = appendRequestId("replace with description", requestID); + String description = appendRequestId("Server returned error", requestID); throw new SkyflowException(description); } } else { diff --git a/src/main/java/com/skyflow/utils/Utils.java b/src/main/java/com/skyflow/utils/Utils.java index d6456466..75ffb7ce 100644 --- a/src/main/java/com/skyflow/utils/Utils.java +++ b/src/main/java/com/skyflow/utils/Utils.java @@ -113,7 +113,7 @@ public static String constructConnectionURL(ConnectionConfig config, InvokeConne String key = entry.getKey(); String value = entry.getValue(); try { - String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); + String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name()); filledURL = new StringBuilder(filledURL.toString().replace(String.format("{%s}", key), encodedValue)); } catch (Exception e) { filledURL = new StringBuilder(filledURL.toString().replace(String.format("{%s}", key), value)); @@ -127,8 +127,8 @@ public static String constructConnectionURL(ConnectionConfig config, InvokeConne String key = entry.getKey(); String value = entry.getValue(); try { - String encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.toString()); - String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); + String encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.name()); + String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name()); filledURL.append(encodedKey).append("=").append(encodedValue).append("&"); } catch (Exception e) { filledURL.append(key).append("=").append(value).append("&"); diff --git a/src/main/java/com/skyflow/vault/controller/ConnectionController.java b/src/main/java/com/skyflow/vault/controller/ConnectionController.java index 3734aceb..0eb260ab 100644 --- a/src/main/java/com/skyflow/vault/controller/ConnectionController.java +++ b/src/main/java/com/skyflow/vault/controller/ConnectionController.java @@ -92,7 +92,9 @@ public InvokeConnectionResponse invoke(InvokeConnectionRequest invokeConnectionR Object data = response; try { data = JsonParser.parseString(response).getAsJsonObject(); - } catch (Exception ignored) {} + } catch (Exception e) { + LogUtil.printErrorLog(ErrorLogs.INVOKE_CONNECTION_REQUEST_REJECTED.getLog()); + } HashMap metadata = new HashMap<>(); metadata.put("requestId", HttpUtility.getRequestID()); connectionResponse = new InvokeConnectionResponse(data, metadata, null); From cdde0533ac75b73e9fd961b753532f62e87f906f Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Mon, 2 Feb 2026 16:07:31 +0530 Subject: [PATCH 3/9] aadarsh-st/SK-2521-Refactor request handling in ConnectionController and update request ID format in HttpUtility --- .../java/com/skyflow/utils/HttpUtility.java | 3 ++- .../controller/ConnectionController.java | 20 +++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/skyflow/utils/HttpUtility.java b/src/main/java/com/skyflow/utils/HttpUtility.java index 4cb98338..f0ce175c 100644 --- a/src/main/java/com/skyflow/utils/HttpUtility.java +++ b/src/main/java/com/skyflow/utils/HttpUtility.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.UUID; public final class HttpUtility { @@ -79,7 +80,7 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< if (requestID != null) { HttpUtility.requestID = requestID.split(",")[0]; } else { - HttpUtility.requestID = "Internal-SDK-" + UUID.randomUUID(); + HttpUtility.requestID = "SDK-Generated-" + UUID.randomUUID(); } Map> responseHeaders = connection.getHeaderFields(); Reader streamReader; diff --git a/src/main/java/com/skyflow/vault/controller/ConnectionController.java b/src/main/java/com/skyflow/vault/controller/ConnectionController.java index 0eb260ab..58a68230 100644 --- a/src/main/java/com/skyflow/vault/controller/ConnectionController.java +++ b/src/main/java/com/skyflow/vault/controller/ConnectionController.java @@ -52,12 +52,12 @@ public InvokeConnectionResponse invoke(InvokeConnectionRequest invokeConnectionR RequestMethod requestMethod = invokeConnectionRequest.getMethod(); Object requestBodyObject = invokeConnectionRequest.getRequestBody(); - String contentType = headers + String requestContentType = headers .getOrDefault("content-type", "application/json") .toLowerCase(); - boolean isJsonRequest = contentType.contains("application/json"); + boolean isJsonRequest = requestContentType.contains("application/json"); - Object finalPayload; + Object processedRequestBody; try { if (requestBodyObject instanceof String) { @@ -67,25 +67,25 @@ public InvokeConnectionResponse invoke(InvokeConnectionRequest invokeConnectionR "__raw_body__", (String) requestBodyObject ); - finalPayload = jsonWrapper; + processedRequestBody = jsonWrapper; } else { - finalPayload = requestBodyObject; + processedRequestBody = requestBodyObject; } } else if (requestBodyObject instanceof JsonObject || requestBodyObject == null) { - finalPayload = requestBodyObject; + processedRequestBody = requestBodyObject; } else { - finalPayload = convertObjectToJson(requestBodyObject); + processedRequestBody = convertObjectToJson(requestBodyObject); } } catch (Exception e) { LogUtil.printErrorLog(ErrorLogs.INVALID_REQUEST_HEADERS.getLog()); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidRequestBody.getMessage()); } JsonObject payloadToSend; - if (finalPayload instanceof JsonObject || finalPayload == null) { - payloadToSend = (JsonObject) finalPayload; + if (processedRequestBody instanceof JsonObject || processedRequestBody == null) { + payloadToSend = (JsonObject) processedRequestBody; } else { payloadToSend = new JsonObject(); - payloadToSend.addProperty("__raw_body__", finalPayload.toString()); + payloadToSend.addProperty("__raw_body__", processedRequestBody.toString()); } String response = HttpUtility.sendRequest(requestMethod.name(), new URL(filledURL), payloadToSend, headers); From e31e5900efe496e9ae2cf0a9dac4d53ef474dd66 Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Mon, 2 Feb 2026 16:41:35 +0530 Subject: [PATCH 4/9] aadarsh-st/SK-2521-Fixed test cases and coverage --- .../controller/ConnectionControllerTests.java | 299 ++++++++++++++++++ 1 file changed, 299 insertions(+) diff --git a/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java b/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java index 750b0ebe..5c884dcf 100644 --- a/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java +++ b/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java @@ -1,19 +1,36 @@ package com.skyflow.vault.controller; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.skyflow.Skyflow; import com.skyflow.config.ConnectionConfig; import com.skyflow.config.Credentials; import com.skyflow.enums.LogLevel; +import com.skyflow.enums.RequestMethod; import com.skyflow.errors.ErrorCode; import com.skyflow.errors.ErrorMessage; import com.skyflow.errors.SkyflowException; +import com.skyflow.utils.HttpUtility; import com.skyflow.vault.connection.InvokeConnectionRequest; +import com.skyflow.vault.connection.InvokeConnectionResponse; import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import java.net.URL; import java.util.HashMap; +import java.util.Map; +import static org.mockito.ArgumentMatchers.*; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({HttpUtility.class}) public class ConnectionControllerTests { private static final String INVALID_EXCEPTION_THROWN = "Should not have thrown any exception"; private static final String EXCEPTION_NOT_THROWN = "Should have thrown an exception"; @@ -36,6 +53,12 @@ public static void setup() { connectionConfig.setCredentials(credentials); } + @Before + public void setupMocks() throws Exception { + PowerMockito.mockStatic(HttpUtility.class); + when(HttpUtility.getRequestID()).thenReturn("test-request-id"); + } + @Test public void testInvalidRequestInInvokeConnectionMethod() { try { @@ -138,4 +161,280 @@ public void testInvokeConnectionWithHTMLContentType() { Assert.fail(INVALID_EXCEPTION_THROWN); } } + + // Tests for new content-type handling logic with actual controller invocation + + @Test + public void testInvokeConnectionWithStringBodyAndJsonContentType() throws Exception { + String jsonResponse = "{\"success\":true}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + String stringBody = "{\"key\":\"value\"}"; + Map headers = new HashMap<>(); + headers.put("content-type", "application/json"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(stringBody) + .requestHeaders(headers) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof JsonObject); + } + + @Test + public void testInvokeConnectionWithStringBodyAndXmlContentType() throws Exception { + String xmlResponse = "success"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(xmlResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + String xmlBody = "test"; + Map headers = new HashMap<>(); + headers.put("content-type", "application/xml"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(xmlBody) + .requestHeaders(headers) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + // When response is not valid JSON, it should be returned as String + Assert.assertTrue(response.getData() instanceof String); + Assert.assertEquals(xmlResponse, response.getData()); + } + + @Test + public void testInvokeConnectionWithJsonObjectBody() throws Exception { + String jsonResponse = "{\"result\":\"ok\"}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + JsonObject jsonBody = new JsonObject(); + jsonBody.addProperty("test", "value"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(jsonBody) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof JsonObject); + } + + @Test + public void testInvokeConnectionWithNullRequestBody() throws Exception { + String jsonResponse = "{\"status\":\"success\"}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.GET) + .requestBody(null) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof JsonObject); + } + + @Test + public void testInvokeConnectionWithNonJsonResponse() throws Exception { + String plainTextResponse = "This is a plain text response"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(plainTextResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + JsonObject jsonBody = new JsonObject(); + jsonBody.addProperty("key", "value"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(jsonBody) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + // Non-JSON response should be returned as String + Assert.assertTrue(response.getData() instanceof String); + Assert.assertEquals(plainTextResponse, response.getData()); + } + + @Test + public void testInvokeConnectionWithContentTypeCaseInsensitive() throws Exception { + String jsonResponse = "{\"data\":\"test\"}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + String stringBody = "test data"; + Map headers = new HashMap<>(); + // Test with uppercase Content-Type + headers.put("Content-Type", "APPLICATION/JSON"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(stringBody) + .requestHeaders(headers) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof JsonObject); + } + + @Test + public void testInvokeConnectionWithMixedCaseContentType() throws Exception { + String xmlResponse = "data"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(xmlResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + String stringBody = "test"; + Map headers = new HashMap<>(); + headers.put("content-type", "Application/Xml"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(stringBody) + .requestHeaders(headers) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof String); + } + + @Test + public void testInvokeConnectionWithMapRequestBody() throws Exception { + String jsonResponse = "{\"created\":true}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + Map mapBody = new HashMap<>(); + mapBody.put("name", "John"); + mapBody.put("age", "30"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(mapBody) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof JsonObject); + } + + @Test + public void testInvokeConnectionWithDefaultContentType() throws Exception { + String jsonResponse = "{\"message\":\"success\"}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + String stringBody = "string data"; + // No content-type header - should default to application/json + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(stringBody) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof JsonObject); + } + + @Test + public void testInvokeConnectionWithFormUrlEncodedContentType() throws Exception { + String jsonResponse = "{\"submitted\":true}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + String formBody = "param1=value1¶m2=value2"; + Map headers = new HashMap<>(); + headers.put("content-type", "application/x-www-form-urlencoded"); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.POST) + .requestBody(formBody) + .requestHeaders(headers) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertTrue(response.getData() instanceof JsonObject); + } + + @Test + public void testInvokeConnectionMetadataContainsRequestId() throws Exception { + String jsonResponse = "{\"data\":\"value\"}"; + when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + .thenReturn(jsonResponse); + + Skyflow client = Skyflow.builder() + .setLogLevel(LogLevel.DEBUG) + .addConnectionConfig(connectionConfig) + .build(); + + InvokeConnectionRequest request = InvokeConnectionRequest.builder() + .method(RequestMethod.GET) + .build(); + + InvokeConnectionResponse response = client.connection().invoke(request); + Assert.assertNotNull(response); + Assert.assertNotNull(response.getMetadata()); + Assert.assertEquals("test-request-id", response.getMetadata().get("requestId")); + } } From 4957bf132e4f233c0d782c05548f0ba7e3e814bc Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Mon, 2 Feb 2026 16:47:44 +0530 Subject: [PATCH 5/9] aadarsh-st/SK-2521-fixed test cases --- .../com/skyflow/vault/controller/ConnectionControllerTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java b/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java index 5c884dcf..5ded96b2 100644 --- a/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java +++ b/src/test/java/com/skyflow/vault/controller/ConnectionControllerTests.java @@ -245,7 +245,7 @@ public void testInvokeConnectionWithJsonObjectBody() throws Exception { @Test public void testInvokeConnectionWithNullRequestBody() throws Exception { String jsonResponse = "{\"status\":\"success\"}"; - when(HttpUtility.sendRequest(anyString(), any(URL.class), any(JsonObject.class), anyMap())) + when(HttpUtility.sendRequest(anyString(), any(URL.class), isNull(), anyMap())) .thenReturn(jsonResponse); Skyflow client = Skyflow.builder() From b2fc15215dee4321bf846a724dd3ebcdf14191c1 Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Tue, 3 Feb 2026 13:37:22 +0530 Subject: [PATCH 6/9] aadarsh-st/SK-2521: Removed hardecoded values --- .../java/com/skyflow/utils/Constants.java | 7 +++++++ .../java/com/skyflow/utils/HttpUtility.java | 2 +- src/main/java/com/skyflow/utils/Utils.java | 20 +++++++++---------- .../controller/ConnectionController.java | 12 +++++------ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/skyflow/utils/Constants.java b/src/main/java/com/skyflow/utils/Constants.java index 1f26cd9d..fd55655e 100644 --- a/src/main/java/com/skyflow/utils/Constants.java +++ b/src/main/java/com/skyflow/utils/Constants.java @@ -60,6 +60,13 @@ private EncodingType() { // Utility class constructor } } + public static final String EMPTY_STRING = ""; + public static final String QUOTE = "\""; + public static final class HttpUtilityExtra { + public static final String RAW_BODY_KEY = "__raw_body__"; + public static final String SDK_GENERATED_PREFIX = "SDK-Generated-"; + private HttpUtilityExtra() {} + } public static final class FileFormatType { public static final String TXT = "txt"; diff --git a/src/main/java/com/skyflow/utils/HttpUtility.java b/src/main/java/com/skyflow/utils/HttpUtility.java index 451be734..f65f692f 100644 --- a/src/main/java/com/skyflow/utils/HttpUtility.java +++ b/src/main/java/com/skyflow/utils/HttpUtility.java @@ -174,7 +174,7 @@ private static String makeFormEncodeKeyValuePair(String key, String value) { try { String encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.toString()); String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); - return encodedKey + "=" + encodedValue + "&"; + return encodedKey + Constants.HttpUtility.FORM_ENCODE_SEPARATOR + encodedValue + Constants.HttpUtility.FORM_ENCODE_DELIMITER; } catch (Exception e) { return key + Constants.HttpUtility.FORM_ENCODE_SEPARATOR + value + Constants.HttpUtility.FORM_ENCODE_DELIMITER; } diff --git a/src/main/java/com/skyflow/utils/Utils.java b/src/main/java/com/skyflow/utils/Utils.java index ef3d3148..0826910f 100644 --- a/src/main/java/com/skyflow/utils/Utils.java +++ b/src/main/java/com/skyflow/utils/Utils.java @@ -79,10 +79,10 @@ public static PrivateKey getPrivateKeyFromPem(String pemKey) throws SkyflowExcep PrivateKey privateKey = null; if (pemKey.contains(PKCS8PrivateHeader)) { - privateKeyContent = privateKeyContent.replace(PKCS8PrivateHeader, ""); - privateKeyContent = privateKeyContent.replace(PKCS8PrivateFooter, ""); - privateKeyContent = privateKeyContent.replace("\n", ""); - privateKeyContent = privateKeyContent.replace("\r\n", ""); + privateKeyContent = privateKeyContent.replace(PKCS8PrivateHeader, Constants.EMPTY_STRING); + privateKeyContent = privateKeyContent.replace(PKCS8PrivateFooter, Constants.EMPTY_STRING); + privateKeyContent = privateKeyContent.replace("\n", Constants.EMPTY_STRING); + privateKeyContent = privateKeyContent.replace("\r\n", Constants.EMPTY_STRING); privateKey = parsePkcs8PrivateKey(Base64.decodeBase64(privateKeyContent)); } else { LogUtil.printErrorLog(ErrorLogs.JWT_INVALID_FORMAT.getLog()); @@ -122,16 +122,16 @@ public static String constructConnectionURL(ConnectionConfig config, InvokeConne } if (invokeConnectionRequest.getQueryParams() != null && !invokeConnectionRequest.getQueryParams().isEmpty()) { - filledURL.append("?"); + filledURL.append(Constants.HttpUtility.FORM_ENCODE_DELIMITER); // "?" for (Map.Entry entry : invokeConnectionRequest.getQueryParams().entrySet()) { String key = entry.getKey(); String value = entry.getValue(); try { String encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.name()); String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name()); - filledURL.append(encodedKey).append("=").append(encodedValue).append("&"); + filledURL.append(encodedKey).append(Constants.HttpUtility.FORM_ENCODE_SEPARATOR).append(encodedValue).append(Constants.HttpUtility.FORM_ENCODE_DELIMITER); } catch (Exception e) { - filledURL.append(key).append("=").append(value).append("&"); + filledURL.append(key).append(Constants.HttpUtility.FORM_ENCODE_SEPARATOR).append(value).append(Constants.HttpUtility.FORM_ENCODE_DELIMITER); } } filledURL = new StringBuilder(filledURL.substring(0, filledURL.length() - 1)); @@ -165,7 +165,7 @@ public static JsonObject getMetrics() { InfoLogs.UNABLE_TO_GENERATE_SDK_METRIC.getLog(), Constants.SDK_METRIC_CLIENT_DEVICE_MODEL )); - deviceModel = ""; + deviceModel = Constants.EMPTY_STRING; } // Retrieve OS details @@ -177,7 +177,7 @@ public static JsonObject getMetrics() { InfoLogs.UNABLE_TO_GENERATE_SDK_METRIC.getLog(), Constants.SDK_METRIC_CLIENT_OS_DETAILS )); - osDetails = ""; + osDetails = Constants.EMPTY_STRING; } // Retrieve Java version details @@ -189,7 +189,7 @@ public static JsonObject getMetrics() { InfoLogs.UNABLE_TO_GENERATE_SDK_METRIC.getLog(), Constants.SDK_METRIC_RUNTIME_DETAILS )); - javaVersion = ""; + javaVersion = Constants.EMPTY_STRING; } details.addProperty(Constants.SDK_METRIC_NAME_VERSION, Constants.SDK_METRIC_NAME_VERSION_PREFIX + sdkVersion); details.addProperty(Constants.SDK_METRIC_CLIENT_DEVICE_MODEL, deviceModel); diff --git a/src/main/java/com/skyflow/vault/controller/ConnectionController.java b/src/main/java/com/skyflow/vault/controller/ConnectionController.java index ddb93a9c..06d806c9 100644 --- a/src/main/java/com/skyflow/vault/controller/ConnectionController.java +++ b/src/main/java/com/skyflow/vault/controller/ConnectionController.java @@ -52,10 +52,10 @@ public InvokeConnectionResponse invoke(InvokeConnectionRequest invokeConnectionR RequestMethod requestMethod = invokeConnectionRequest.getMethod(); Object requestBodyObject = invokeConnectionRequest.getRequestBody(); - String requestContentType = headers - .getOrDefault("content-type", "application/json") + String requestContentType = headers + .getOrDefault(Constants.HttpHeader.CONTENT_TYPE, Constants.HttpHeader.CONTENT_TYPE_JSON) .toLowerCase(); - boolean isJsonRequest = requestContentType.contains("application/json"); + boolean isJsonRequest = requestContentType.contains(Constants.HttpHeader.CONTENT_TYPE_JSON); Object processedRequestBody; @@ -64,8 +64,8 @@ public InvokeConnectionResponse invoke(InvokeConnectionRequest invokeConnectionR if (isJsonRequest) { JsonObject jsonWrapper = new JsonObject(); jsonWrapper.addProperty( - "__raw_body__", - (String) requestBodyObject + Constants.HttpUtilityExtra.RAW_BODY_KEY, + (String) requestBodyObject ); processedRequestBody = jsonWrapper; } else { @@ -85,7 +85,7 @@ public InvokeConnectionResponse invoke(InvokeConnectionRequest invokeConnectionR payloadToSend = (JsonObject) processedRequestBody; } else { payloadToSend = new JsonObject(); - payloadToSend.addProperty("__raw_body__", processedRequestBody.toString()); + payloadToSend.addProperty(Constants.HttpUtilityExtra.RAW_BODY_KEY, processedRequestBody.toString()); } String response = HttpUtility.sendRequest(requestMethod.name(), new URL(filledURL), payloadToSend, headers); From 87d151b30e990ace72f0926a728f80063e2f118e Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Tue, 3 Feb 2026 13:47:34 +0530 Subject: [PATCH 7/9] aadarsh-st/SK-2521-Added new constant --- src/main/java/com/skyflow/utils/Constants.java | 2 ++ src/main/java/com/skyflow/utils/HttpUtility.java | 4 ++-- src/main/java/com/skyflow/utils/Utils.java | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/skyflow/utils/Constants.java b/src/main/java/com/skyflow/utils/Constants.java index fd55655e..92a608ac 100644 --- a/src/main/java/com/skyflow/utils/Constants.java +++ b/src/main/java/com/skyflow/utils/Constants.java @@ -34,6 +34,8 @@ public final class Constants { public static final String ERROR_FROM_CLIENT_HEADER_KEY = "error-from-client"; public static final String PROCESSED_FILE_NAME_PREFIX = "processed-"; public static final String DEIDENTIFIED_FILE_PREFIX = "deidentified"; + public static final String CURLY_PLACEHOLDER = "{%s}"; + public static final class HttpHeader { public static final String CONTENT_TYPE = "content-type"; public static final String CONTENT_TYPE_JSON = "application/json"; diff --git a/src/main/java/com/skyflow/utils/HttpUtility.java b/src/main/java/com/skyflow/utils/HttpUtility.java index f65f692f..cc2bc742 100644 --- a/src/main/java/com/skyflow/utils/HttpUtility.java +++ b/src/main/java/com/skyflow/utils/HttpUtility.java @@ -58,8 +58,8 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< String requestContentType = connection.getRequestProperty(Constants.HttpHeader.CONTENT_TYPE); // Check if this is a raw body (XML, plain text, etc.) - if (params.has("__raw_body__") && params.size() == 1) { - input = params.get("__raw_body__").getAsString().getBytes(StandardCharsets.UTF_8); + if (params.has(Constants.HttpUtilityExtra.RAW_BODY_KEY,) && params.size() == 1) { + input = params.get(Constants.HttpUtilityExtra.RAW_BODY_KEY,).getAsString().getBytes(StandardCharsets.UTF_8); } else if (requestContentType != null && requestContentType.contains(Constants.HttpHeader.CONTENT_TYPE_FORM_URLENCODED)) { input = formatJsonToFormEncodedString(params).getBytes(StandardCharsets.UTF_8); } else if (requestContentType != null && requestContentType.contains(Constants.HttpHeader.CONTENT_TYPE_MULTIPART)) { diff --git a/src/main/java/com/skyflow/utils/Utils.java b/src/main/java/com/skyflow/utils/Utils.java index 0826910f..5db83cdd 100644 --- a/src/main/java/com/skyflow/utils/Utils.java +++ b/src/main/java/com/skyflow/utils/Utils.java @@ -114,9 +114,9 @@ public static String constructConnectionURL(ConnectionConfig config, InvokeConne String value = entry.getValue(); try { String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name()); - filledURL = new StringBuilder(filledURL.toString().replace(String.format("{%s}", key), encodedValue)); + filledURL = new StringBuilder(filledURL.toString().replace(String.format(Constants.CURLY_PLACEHOLDER, key), encodedValue)); } catch (Exception e) { - filledURL = new StringBuilder(filledURL.toString().replace(String.format("{%s}", key), value)); + filledURL = new StringBuilder(filledURL.toString().replace(String.format(Constants.CURLY_PLACEHOLDER, key), value)); } } } From 01404e992267b06943810b6358dcad8677d34094 Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Tue, 3 Feb 2026 14:50:44 +0530 Subject: [PATCH 8/9] aadarsh-st/SK-2521: Fixed undefined error --- src/main/java/com/skyflow/utils/HttpUtility.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/skyflow/utils/HttpUtility.java b/src/main/java/com/skyflow/utils/HttpUtility.java index cc2bc742..fd30ed26 100644 --- a/src/main/java/com/skyflow/utils/HttpUtility.java +++ b/src/main/java/com/skyflow/utils/HttpUtility.java @@ -35,9 +35,9 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod(method); connection.setRequestProperty(Constants.HttpHeader.ACCEPT, Constants.HttpHeader.ACCEPT_ALL); - + boolean hasContentType = headers != null && headers.containsKey(Constants.HttpHeader.CONTENT_TYPE); if (!hasContentType && params != null && !params.isEmpty()) { - connection.setRequestProperty("content-type", "application/json"); + connection.setRequestProperty(Constants.HttpHeader.CONTENT_TYPE, Constants.HttpHeader.CONTENT_TYPE_JSON); } if (headers != null && !headers.isEmpty()) { @@ -58,8 +58,8 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< String requestContentType = connection.getRequestProperty(Constants.HttpHeader.CONTENT_TYPE); // Check if this is a raw body (XML, plain text, etc.) - if (params.has(Constants.HttpUtilityExtra.RAW_BODY_KEY,) && params.size() == 1) { - input = params.get(Constants.HttpUtilityExtra.RAW_BODY_KEY,).getAsString().getBytes(StandardCharsets.UTF_8); + if (params.has(Constants.HttpUtilityExtra.RAW_BODY_KEY) && params.size() == 1) { + input = params.get(Constants.HttpUtilityExtra.RAW_BODY_KEY).getAsString().getBytes(StandardCharsets.UTF_8); } else if (requestContentType != null && requestContentType.contains(Constants.HttpHeader.CONTENT_TYPE_FORM_URLENCODED)) { input = formatJsonToFormEncodedString(params).getBytes(StandardCharsets.UTF_8); } else if (requestContentType != null && requestContentType.contains(Constants.HttpHeader.CONTENT_TYPE_MULTIPART)) { @@ -78,7 +78,7 @@ public static String sendRequest(String method, URL url, JsonObject params, Map< if (requestID != null) { HttpUtility.requestID = requestID.split(Constants.HttpUtility.REQUEST_ID_DELIMITER)[0]; } else { - HttpUtility.requestID = "SDK-Generated-" + UUID.randomUUID(); + HttpUtility.requestID = Constants.HttpUtilityExtra.SDK_GENERATED_PREFIX + UUID.randomUUID(); } Map> responseHeaders = connection.getHeaderFields(); Reader streamReader; From d4a542c020c0e82ffe7763e40b6778935afc71aa Mon Sep 17 00:00:00 2001 From: Aadarsh Date: Tue, 3 Feb 2026 15:05:25 +0530 Subject: [PATCH 9/9] aadarsh-st/SK-2521: fixed test cases --- src/main/java/com/skyflow/utils/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/skyflow/utils/Utils.java b/src/main/java/com/skyflow/utils/Utils.java index 5db83cdd..c53685cc 100644 --- a/src/main/java/com/skyflow/utils/Utils.java +++ b/src/main/java/com/skyflow/utils/Utils.java @@ -122,7 +122,7 @@ public static String constructConnectionURL(ConnectionConfig config, InvokeConne } if (invokeConnectionRequest.getQueryParams() != null && !invokeConnectionRequest.getQueryParams().isEmpty()) { - filledURL.append(Constants.HttpUtility.FORM_ENCODE_DELIMITER); // "?" + filledURL.append("?"); for (Map.Entry entry : invokeConnectionRequest.getQueryParams().entrySet()) { String key = entry.getKey(); String value = entry.getValue();