+
+
diff --git a/build/resources/main/logback.xml b/build/resources/main/logback.xml
new file mode 100644
index 0000000..609c775
--- /dev/null
+++ b/build/resources/main/logback.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
diff --git a/build/test-results/test/TEST-CorezoidMessageIntegrationTest.xml b/build/test-results/test/TEST-CorezoidMessageIntegrationTest.xml
new file mode 100644
index 0000000..69521a3
--- /dev/null
+++ b/build/test-results/test/TEST-CorezoidMessageIntegrationTest.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/build/test-results/test/TEST-CorezoidMessageTest.xml b/build/test-results/test/TEST-CorezoidMessageTest.xml
new file mode 100644
index 0000000..89541eb
--- /dev/null
+++ b/build/test-results/test/TEST-CorezoidMessageTest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/build/test-results/test/TEST-HttpManagerTest.xml b/build/test-results/test/TEST-HttpManagerTest.xml
new file mode 100644
index 0000000..09482c0
--- /dev/null
+++ b/build/test-results/test/TEST-HttpManagerTest.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/build/test-results/test/TEST-RequestOperationTest.xml b/build/test-results/test/TEST-RequestOperationTest.xml
new file mode 100644
index 0000000..4bfcb6f
--- /dev/null
+++ b/build/test-results/test/TEST-RequestOperationTest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/build/test-results/test/TEST-ResponseOperationTest.xml b/build/test-results/test/TEST-ResponseOperationTest.xml
new file mode 100644
index 0000000..d4c654b
--- /dev/null
+++ b/build/test-results/test/TEST-ResponseOperationTest.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/build/test-results/test/TEST-com.corezoid.sdk.test.UtiisTest.xml b/build/test-results/test/TEST-com.corezoid.sdk.test.UtiisTest.xml
new file mode 100644
index 0000000..80fcff8
--- /dev/null
+++ b/build/test-results/test/TEST-com.corezoid.sdk.test.UtiisTest.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >testRequestOperationShouldThrowException : ref and taskId is null
+>>testRequestOperationShouldThrowException : taskId is empty
+>>testRequestOperationShouldThrowException : ref and taskId is null
+>>testRequestOperationShouldThrowException : ref is empty
+>>testGetConvQueryModifyRefMessage :
+body {"ops":[{"obj_id":"11","conv_id":"1234","type":"modify","obj":"task","data":{"phone":"1","card":"2"}}]}
+url https://api.corezoid.com/api/1/json/12345/1751363558/b45354cf865adc098d87ddfee042bfa073308b5f
+>>testGetConvQueryModifyRefMessage :
+body {"ops":[{"ref":"11","conv_id":"1234","type":"modify","obj":"task","data":{"phone":"1","card":"2"}}]}
+url https://api.corezoid.com/api/1/json/12345/1751363558/b1e87e654e7f1f8e378e04a63ed6b8ed0dedef69
+>>testcheckAnswerShouldThrowException : Request processing failed, request_proc = fail
+>>testGetConvQueryCreateMessage :
+body {"ops":[{"ref":"11","conv_id":"1234","type":"create","obj":"task","data":{"phone":"1","card":"2"}}]}
+url https://api.corezoid.com/api/1/json/12345/1751363558/fb6b8de2bc6477d4aa5bb05c1bdc1857ee899693
+>>checkSignTrue : true
+>>testCheckAnswerReturnsNotEmptyMap : {PB11345969838=ok}
+>>testGetConAnswerMessage :
+body {"request_proc":"ok","ops":[{"ref":"22","conv_id":"11","proc":"ok","res_data":{"id":"1","test":"2"}}]}
+>>testConveyorQueryBuilderShouldThrowException : apiSecret is null or empty
+>>testConveyorQueryBuilderShouldThrowException : apiSecret is null or empty
+>>testConveyorQueryBuilderShouldThrowException : apiLogin is null or empty
+>>testConveyorQueryBuilderShouldThrowException : apiLogin is null or empty
+>>testConveyorQueryBuilderShouldThrowException : operations is null
+>>testResponseOperationBuilderShouldThrowEsception : convId is null or empty
+>>testResponseOperationBuilderShouldThrowEsception : convId is null or empty
+>>testResponseOperationBuilderShouldThrowEsception : ref is null or empty
+>>testResponseOperationBuilderShouldThrowEsception : ref is null or empty
+>>testResponseOperationBuilderShouldThrowEsception : data is null
+>>testRequestOperationBuilderShouldThrowEsception : convId is null or empty
+>>testRequestOperationBuilderShouldThrowEsception : convId is null or empty
+>>testRequestOperationBuilderShouldThrowEsception : ref and taskId is null
+>>testRequestOperationBuilderShouldThrowEsception : ref is empty
+>>testRequestOperationBuilderShouldThrowEsception : data is null
+>>checkSignFalse : false
+]]>
+
+
diff --git a/build/test-results/test/binary/output.bin b/build/test-results/test/binary/output.bin
new file mode 100644
index 0000000..f3c1ba9
--- /dev/null
+++ b/build/test-results/test/binary/output.bin
@@ -0,0 +1,34 @@
+D>>testRequestOperationShouldThrowException : ref and taskId is null
+=>>testRequestOperationShouldThrowException : taskId is empty
+D>>testRequestOperationShouldThrowException : ref and taskId is null
+:>>testRequestOperationShouldThrowException : ref is empty
+%>>testGetConvQueryModifyRefMessage :
+obody {"ops":[{"obj_id":"11","conv_id":"1234","type":"modify","obj":"task","data":{"phone":"1","card":"2"}}]}
+eurl https://api.corezoid.com/api/1/json/12345/1751363558/b45354cf865adc098d87ddfee042bfa073308b5f
+%>>testGetConvQueryModifyRefMessage :
+lbody {"ops":[{"ref":"11","conv_id":"1234","type":"modify","obj":"task","data":{"phone":"1","card":"2"}}]}
+eurl https://api.corezoid.com/api/1/json/12345/1751363558/b1e87e654e7f1f8e378e04a63ed6b8ed0dedef69
+X>>testcheckAnswerShouldThrowException : Request processing failed, request_proc = fail
+">>testGetConvQueryCreateMessage :
+lbody {"ops":[{"ref":"11","conv_id":"1234","type":"create","obj":"task","data":{"phone":"1","card":"2"}}]}
+eurl https://api.corezoid.com/api/1/json/12345/1751363558/fb6b8de2bc6477d4aa5bb05c1bdc1857ee899693
+>>checkSignTrue : true
+9>>testCheckAnswerReturnsNotEmptyMap : {PB11345969838=ok}
+>>testGetConAnswerMessage :
+nbody {"request_proc":"ok","ops":[{"ref":"22","conv_id":"11","proc":"ok","res_data":{"id":"1","test":"2"}}]}
+L>>testConveyorQueryBuilderShouldThrowException : apiSecret is null or empty
+L>>testConveyorQueryBuilderShouldThrowException : apiSecret is null or empty
+K>>testConveyorQueryBuilderShouldThrowException : apiLogin is null or empty
+K>>testConveyorQueryBuilderShouldThrowException : apiLogin is null or empty
+D>>testConveyorQueryBuilderShouldThrowException : operations is null
+ M>>testResponseOperationBuilderShouldThrowEsception : convId is null or empty
+ M>>testResponseOperationBuilderShouldThrowEsception : convId is null or empty
+ J>>testResponseOperationBuilderShouldThrowEsception : ref is null or empty
+ J>>testResponseOperationBuilderShouldThrowEsception : ref is null or empty
+ B>>testResponseOperationBuilderShouldThrowEsception : data is null
+ L>>testRequestOperationBuilderShouldThrowEsception : convId is null or empty
+ L>>testRequestOperationBuilderShouldThrowEsception : convId is null or empty
+ K>>testRequestOperationBuilderShouldThrowEsception : ref and taskId is null
+ A>>testRequestOperationBuilderShouldThrowEsception : ref is empty
+ A>>testRequestOperationBuilderShouldThrowEsception : data is null
+!>>checkSignFalse : false
diff --git a/build/test-results/test/binary/output.bin.idx b/build/test-results/test/binary/output.bin.idx
new file mode 100644
index 0000000..0c5de7e
Binary files /dev/null and b/build/test-results/test/binary/output.bin.idx differ
diff --git a/build/test-results/test/binary/results.bin b/build/test-results/test/binary/results.bin
new file mode 100644
index 0000000..3f9bc6b
Binary files /dev/null and b/build/test-results/test/binary/results.bin differ
diff --git a/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage$1.class.uniqueId3 b/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage$1.class.uniqueId3
new file mode 100644
index 0000000..ab8872b
Binary files /dev/null and b/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage$1.class.uniqueId3 differ
diff --git a/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage$ResultType.class.uniqueId1 b/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage$ResultType.class.uniqueId1
new file mode 100644
index 0000000..9959519
Binary files /dev/null and b/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage$ResultType.class.uniqueId1 differ
diff --git a/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage.class.uniqueId2 b/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage.class.uniqueId2
new file mode 100644
index 0000000..aedf37d
Binary files /dev/null and b/build/tmp/compileJava/compileTransaction/stash-dir/CorezoidMessage.class.uniqueId2 differ
diff --git a/build/tmp/compileJava/compileTransaction/stash-dir/HttpManager.class.uniqueId0 b/build/tmp/compileJava/compileTransaction/stash-dir/HttpManager.class.uniqueId0
new file mode 100644
index 0000000..7c5cf82
Binary files /dev/null and b/build/tmp/compileJava/compileTransaction/stash-dir/HttpManager.class.uniqueId0 differ
diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin
new file mode 100644
index 0000000..6c9a6b3
Binary files /dev/null and b/build/tmp/compileJava/previous-compilation-data.bin differ
diff --git a/build/tmp/compileTestJava/compileTransaction/stash-dir/CorezoidMessageIntegrationTest.class.uniqueId0 b/build/tmp/compileTestJava/compileTransaction/stash-dir/CorezoidMessageIntegrationTest.class.uniqueId0
new file mode 100644
index 0000000..8c660cb
Binary files /dev/null and b/build/tmp/compileTestJava/compileTransaction/stash-dir/CorezoidMessageIntegrationTest.class.uniqueId0 differ
diff --git a/build/tmp/compileTestJava/compileTransaction/stash-dir/CorezoidMessageTest.class.uniqueId3 b/build/tmp/compileTestJava/compileTransaction/stash-dir/CorezoidMessageTest.class.uniqueId3
new file mode 100644
index 0000000..c51036f
Binary files /dev/null and b/build/tmp/compileTestJava/compileTransaction/stash-dir/CorezoidMessageTest.class.uniqueId3 differ
diff --git a/build/tmp/compileTestJava/compileTransaction/stash-dir/HttpManagerTest.class.uniqueId1 b/build/tmp/compileTestJava/compileTransaction/stash-dir/HttpManagerTest.class.uniqueId1
new file mode 100644
index 0000000..a3d4d68
Binary files /dev/null and b/build/tmp/compileTestJava/compileTransaction/stash-dir/HttpManagerTest.class.uniqueId1 differ
diff --git a/build/tmp/compileTestJava/compileTransaction/stash-dir/UtiisTest.class.uniqueId2 b/build/tmp/compileTestJava/compileTransaction/stash-dir/UtiisTest.class.uniqueId2
new file mode 100644
index 0000000..b6905c1
Binary files /dev/null and b/build/tmp/compileTestJava/compileTransaction/stash-dir/UtiisTest.class.uniqueId2 differ
diff --git a/build/tmp/compileTestJava/previous-compilation-data.bin b/build/tmp/compileTestJava/previous-compilation-data.bin
new file mode 100644
index 0000000..5dcc3e8
Binary files /dev/null and b/build/tmp/compileTestJava/previous-compilation-data.bin differ
diff --git a/src/main/java/com/corezoid/sdk/entity/CorezoidMessage.java b/src/main/java/com/corezoid/sdk/entity/CorezoidMessage.java
index 2eb38fc..39f62c0 100644
--- a/src/main/java/com/corezoid/sdk/entity/CorezoidMessage.java
+++ b/src/main/java/com/corezoid/sdk/entity/CorezoidMessage.java
@@ -106,17 +106,41 @@ public static CorezoidMessage request(String host, String apiSecret, String apiL
//----------------------------------------------------------------------------------------------------------------------
/**
- * Verifies the signature of a message.
+ * Verifies the signature of a message received from Corezoid.
*
* This method checks if a received signature matches the calculated signature
- * for the given content, time, and API secret.
+ * for the given content, time, and API secret. This is typically used when
+ * processing callbacks or webhooks from Corezoid to ensure message authenticity.
*
+ *
+ *
Security Note: This method uses SHA-1 hashing as required
+ * by the Corezoid API specification. While SHA-1 is cryptographically weak,
+ * it cannot be changed without breaking compatibility with Corezoid servers.
*
- * @param sign The signature to verify (from the SIGNATURE query parameter)
- * @param apiSecret The API secret key used for signing
+ * @param sign The signature to verify (from the SIGNATURE query parameter in callbacks)
+ * @param apiSecret The API secret key used for signing (same as used for requests)
* @param time The timestamp when the message was created (from the GMT_UNIXTIME query parameter)
- * @param content The message body content
- * @return true if the signature is valid, false otherwise
+ * @param content The message body content (JSON string)
+ * @return true if the signature is valid and the message is authentic, false otherwise
+ *
+ * @see #request(String, String, List) for creating signed requests
+ *
+ * @example
+ *
*/
public static boolean checkSign(String sign, String apiSecret, String time,
String content) {
@@ -130,12 +154,43 @@ public static boolean checkSign(String sign, String apiSecret, String time,
* Parses a response from the Corezoid API into a map of reference-to-status pairs.
*
* This method processes the JSON response from the Corezoid API and extracts
- * the status of each operation, indexed by the task reference.
+ * the status of each operation, indexed by the task reference. This is used
+ * to determine the success or failure of individual operations in a request.
*
*
* @param jsonString The JSON response string from the Corezoid API
- * @return A map where keys are task references and values are processing statuses
- * @throws Exception if the response indicates a failure or cannot be parsed
+ * @return A map where keys are task references and values are processing statuses
+ * (typically "ok", "fail", or other status codes)
+ * @throws Exception if the response indicates a failure (request_proc != "ok")
+ * or the JSON cannot be parsed
+ *
+ * @example
+ *
*/
public static Map parseAnswer(String jsonString) throws Exception {
ObjectMapper mapper = new ObjectMapper();
@@ -168,13 +223,8 @@ private CorezoidMessage(String body, String time, String apiSecret,
this.time = time;
this.apiSecret = apiSecret;
this.signCode = generateSign(time, apiSecret, body);
- this.url = new StringBuilder()
- .append(baseUri).append("/api/")
- .append(version).append(slash)
- .append(format).append(slash)
- .append(apiLogin).append(slash)
- .append(time).append(slash)
- .append(signCode).toString();
+ this.url = String.format("%s/api/%s/%s/%s/%s/%s",
+ baseUri, version, format, apiLogin, time, signCode);
}
//----------------------------------------------------------------------------------------------------------------------
@@ -205,19 +255,14 @@ public boolean equals(Object obj) {
@Override
public int hashCode() {
- int hash = 3;
- hash = 89 * hash + (this.body != null ? this.body.hashCode() : 0);
- hash = 89 * hash + (this.time != null ? this.time.hashCode() : 0);
- hash = 89 * hash + (this.apiSecret != null ? this.apiSecret.hashCode() : 0);
- hash = 89 * hash + (this.signCode != null ? this.signCode.hashCode() : 0);
- hash = 89 * hash + (this.url != null ? this.url.hashCode() : 0);
- return hash;
+ // Only use signCode to match the equals() method implementation
+ return this.signCode != null ? this.signCode.hashCode() : 0;
}
//----------------------------------------------------------------------------------------------------------------------
/**
- * Genarate signature {SIGNATURE} = hex( sha1({GMT_UNIXTIME} + {API_SECRET}
+ * Generate signature {SIGNATURE} = hex( sha1({GMT_UNIXTIME} + {API_SECRET}
* + {CONTENT} + {API_SECRET}) )
*
* @param time - time
diff --git a/src/main/java/com/corezoid/sdk/utils/HttpManager.java b/src/main/java/com/corezoid/sdk/utils/HttpManager.java
index d4edb52..ba8d0f3 100644
--- a/src/main/java/com/corezoid/sdk/utils/HttpManager.java
+++ b/src/main/java/com/corezoid/sdk/utils/HttpManager.java
@@ -27,8 +27,25 @@
* request execution, and response handling. It provides methods for sending messages
* to the Corezoid API and processing the responses.
*
+ *
+ *
Thread Safety: This class is thread-safe and can be shared across
+ * multiple threads. It's recommended to create a single instance and reuse it throughout
+ * your application for optimal performance.
+ *
+ *
Connection Pooling: Uses Apache HttpClient's connection pooling
+ * for efficient connection reuse. The pool is automatically managed and cleaned up.
+ *
+ *
Best Practices:
+ *
+ *
Create one HttpManager instance per application, not per request
+ *
Configure appropriate timeouts based on your network conditions
+ *
Set maxConnections based on expected concurrent request volume
+ *
Monitor connection pool usage in high-throughput scenarios
+ *
*
* @author Corezoid
+ * @see CorezoidMessage for creating messages to send
+ * @see HttpException for HTTP-related error handling
*/
public class HttpManager {
//----------------------------------------------------------------------------------------------------------------------
@@ -37,12 +54,33 @@ public class HttpManager {
//----------------------------------------------------------------------------------------------------------------------
/**
+ * Creates an HttpManager with custom connection pool and timeout settings.
+ *
+ * This constructor allows you to configure the HTTP client for your specific
+ * network conditions and performance requirements.
+ *
*
- * create PoolingClientConnectionManager.
- *
- * @param maxCount max total connection, default max connection per route
- * @param connectionTimeout milliseconds
- * @param answerTimeout milliseconds
+ * @param maxCount Maximum total connections in the pool. This should be set based
+ * on your expected concurrent request volume. Default max connections
+ * per route is also set to this value.
+ * @param connectionTimeout Connection establishment timeout in milliseconds.
+ * Time to wait when establishing a connection to the server.
+ * Recommended: 3000-10000ms depending on network conditions.
+ * @param answerTimeout Response timeout in milliseconds. Time to wait for the server
+ * to send a complete response after the connection is established.
+ * Recommended: 10000-30000ms depending on expected response times.
+ *
+ * @example
+ *
{@code
+ * // For high-throughput applications
+ * HttpManager highThroughput = new HttpManager(50, 5000, 15000);
+ *
+ * // For slow networks
+ * HttpManager slowNetwork = new HttpManager(10, 10000, 30000);
+ *
+ * // For development/testing
+ * HttpManager development = new HttpManager(5, 3000, 10000);
+ * }
*/
public HttpManager(int maxCount, int connectionTimeout, int answerTimeout) {
PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
@@ -58,17 +96,62 @@ public HttpManager(int maxCount, int connectionTimeout, int answerTimeout) {
}
//----------------------------------------------------------------------------------------------------------------------
+ /**
+ * Creates an HttpManager with default settings suitable for most applications.
+ *
+ * Default configuration:
+ *
+ *
Max connections: 15
+ *
Connection timeout: 1000ms (1 second)
+ *
Response timeout: 10000ms (10 seconds)
+ *
+ *
+ *
+ *
These defaults work well for moderate-load applications. For high-throughput
+ * or special network conditions, consider using the parameterized constructor.
+ *
+ * @see #HttpManager(int, int, int) for custom configuration
+ */
public HttpManager() {
this(15, 1000, 10000);
}
//----------------------------------------------------------------------------------------------------------------------
/**
- * send request
+ * Sends a CorezoidMessage to the Corezoid API and returns the response.
+ *
+ * This method performs the actual HTTP POST request to the Corezoid API endpoint
+ * specified in the message URL. It handles the complete request/response cycle
+ * including connection management, error handling, and response parsing.
+ *
+ *
+ *
Error Handling: This method throws HttpException for various
+ * failure scenarios including network errors, timeouts, and HTTP error responses.
*
- * @param message - corezoid message
- * @return
- * @throws org.apache.http.HttpException
+ * @param message The CorezoidMessage containing the request URL, body, and signature
+ * @return The raw JSON response string from the Corezoid API
+ * @throws HttpException if the request fails due to network issues, timeouts,
+ * HTTP error responses (4xx, 5xx), or other communication problems
+ *
+ * @example
+ *