This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 281692df4f1 CAMEL-21403: retrieve full message for content containing 
non ASCII chars (#16150)
281692df4f1 is described below

commit 281692df4f18434116663ea89664af2b90ce0d07
Author: Jono Morris <[email protected]>
AuthorDate: Sun Nov 10 02:20:43 2024 +1300

    CAMEL-21403: retrieve full message for content containing non ASCII chars 
(#16150)
    
    * CAMEL-21403 allow for non ASCII chars
    
    * CAMEL-21403 improve flaky test
    
    * CAMEL-21403 remove commented code
---
 .../camel/component/as2/api/util/MicUtilsTest.java | 55 +++++++++++++
 .../component/as2/AS2AsyncMDNServerManagerIT.java  | 96 ++++++++++++++--------
 2 files changed, 118 insertions(+), 33 deletions(-)

diff --git 
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java
 
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java
index a55183d2dcf..931dc049b37 100644
--- 
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java
+++ 
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java
@@ -76,6 +76,33 @@ public class MicUtilsTest {
                                               + "UNT+23+00000000000117'\n"
                                               + "UNZ+1+00000000000778'";
 
+    private static final String EDI_MESSAGE_WITH_NON_ASCII = 
"UNB+UNOA:1+005435656:1+006415160:1+060515:1434+00000000000778'\n"
+                                                             + 
"UNH+00000000000117+INVOIC:D:97B:UN'\n"
+                                                             + 
"BGM+380+342459+9'\n"
+                                                             + 
"DTM+3:20060515:102'\n"
+                                                             + 
"RFF+ON:521052'\n"
+                                                             + 
"NAD+BY+792820524::16++CUMMINS MID-RANGE ENGINE PLANT ΠΠΠ'\n"
+                                                             + 
"NAD+SE+005435656::16++GENERAL WIDGET COMPANY óóó'\n"
+                                                             + "CUX+1:USD'\n"
+                                                             + 
"LIN+1++157870:IN'\n"
+                                                             + 
"IMD+F++:::WIDGET ΣΣΣ'\n"
+                                                             + 
"QTY+47:1020:EA'\n"
+                                                             + "ALI+US'\n"
+                                                             + 
"MOA+203:1202.58'\n"
+                                                             + 
"PRI+INV:1.179'\n"
+                                                             + 
"LIN+2++157871:IN'\n"
+                                                             + 
"IMD+F++:::DIFFERENT WIDGET ΦΦΦ'\n"
+                                                             + 
"QTY+47:20:EA'\n"
+                                                             + "ALI+JP'\n"
+                                                             + "MOA+203:410'\n"
+                                                             + 
"PRI+INV:20.5'\n"
+                                                             + "UNS+S'\n"
+                                                             + 
"MOA+39:2137.58'\n"
+                                                             + "ALC+C+ABG'\n"
+                                                             + "MOA+8:525'\n"
+                                                             + 
"UNT+23+00000000000117'\n"
+                                                             + 
"UNZ+1+00000000000778'";
+
     private static final String EXPECTED_MESSAGE_DIGEST_ALGORITHM = "sha1";
     private static final String EXPECTED_ENCODED_MESSAGE_DIGEST = 
"XUt+ug5GEDD0X9+Nv8DGYZZThOQ=";
 
@@ -112,6 +139,34 @@ public class MicUtilsTest {
                 "Unexpected encoded message digest value");
     }
 
+    // verify that a MIC is calculated correctly for an EDI message containing 
non ASCII chars
+    @Test
+    public void createReceivedContentMicWithNonAsciiContentTest() throws 
Exception {
+
+        BasicClassicHttpRequest request = new BasicClassicHttpRequest("POST", 
"/");
+        request.addHeader(AS2Header.DISPOSITION_NOTIFICATION_OPTIONS, 
DISPOSITION_NOTIFICATION_OPTIONS_VALUE);
+        request.addHeader(AS2Header.CONTENT_TYPE, 
"application/edifact;charset=UTF-8");
+
+        InputStream is = new ApplicationEDIFACTEntity(
+                EDI_MESSAGE_WITH_NON_ASCII, StandardCharsets.UTF_8.name(), 
AS2TransferEncoding.NONE, true, "filename.txt")
+                .getContent();
+        request.setEntity(new BasicHttpEntity(is, 
ContentType.create(CONTENT_TYPE_VALUE, StandardCharsets.UTF_8)));
+        ReceivedContentMic receivedContentMic = 
MicUtils.createReceivedContentMic(request, null, null);
+
+        assertNotNull(receivedContentMic, "Failed to create Received Content 
MIC");
+        assertEquals(EXPECTED_MESSAGE_DIGEST_ALGORITHM, 
receivedContentMic.getDigestAlgorithmId(),
+                "Unexpected digest algorithm value");
+
+        // calculate the MIC of the EDI message directly for comparison
+        String expectedDigest = new ReceivedContentMic(
+                "sha1", MicUtils.createMic(
+                        // the entity parser appends 'CR' and 'LF' for each 
line
+                        EDI_MESSAGE_WITH_NON_ASCII.replaceAll("\n", 
"\r\n").getBytes(StandardCharsets.UTF_8), "sha1"))
+                .getEncodedMessageDigest();
+
+        assertEquals(expectedDigest, 
receivedContentMic.getEncodedMessageDigest(), "Unexpected encoded message 
digest value");
+    }
+
     @ParameterizedTest
     @ValueSource(strings = { "md5", "sha1", "sha256", "sha384", "sha512" })
     public void createReceivedContentMicTest(String requestedMicalg) throws 
Exception {
diff --git 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerIT.java
 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerIT.java
index 00c9573fb50..b7856510cdd 100644
--- 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerIT.java
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2AsyncMDNServerManagerIT.java
@@ -43,6 +43,7 @@ import 
org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
 import org.apache.camel.component.as2.api.util.HttpMessageUtils;
 import org.apache.camel.component.as2.api.util.MicUtils;
 import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.AvailablePortFinder;
 import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.hc.core5.http.ClassicHttpRequest;
@@ -108,9 +109,12 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
 
     private static final String EDI_MESSAGE_CONTENT_TRANSFER_ENCODING = "7bit";
     private static final int PARTNER_TARGET_PORT = 8888;
-    private static final int RECEIPT_SERVER_PORT = 8890;
-    private static final String RECIPIENT_DELIVERY_ADDRESS = 
"http://localhost:"; + RECEIPT_SERVER_PORT + "/handle-receipts";
-    private static final String MOCK_RECEIPT_ENDPOINT = "mock:as2RcvRcptMsgs";
+
+    private static final int RECEIPT_SERVER_PORT = 
AvailablePortFinder.getNextAvailable();
+    private static final int RECEIPT_SERVER_PORT2 = 
AvailablePortFinder.getNextAvailable();
+    private static final int RECEIPT_SERVER_PORT3 = 
AvailablePortFinder.getNextAvailable();
+    private static final int RECEIPT_SERVER_PORT4 = 
AvailablePortFinder.getNextAvailable();
+
     private static AS2ServerConnection serverConnection;
     private static RequestHandler requestHandler;
     private static final String[] SIGNED_RECEIPT_MIC_ALGORITHMS = new String[] 
{ "sha1", "md5" };
@@ -136,7 +140,8 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
     // 'Receipt-Delivery-Option' header specifying the return-URL.
     @Test
     public void deliveryHeaderMultipartReportTest() throws Exception {
-        DispositionNotificationMultipartReportEntity reportEntity = 
executeRequestWithAsyncResponseHeader();
+        DispositionNotificationMultipartReportEntity reportEntity
+                = executeRequestWithAsyncResponseHeader("direct://SEND", 
RECEIPT_SERVER_PORT, "mock:as2RcvRcptMsgs");
         verifyMultiPartReportParts(reportEntity);
         verifyMultiPartReportEntity(reportEntity);
     }
@@ -145,7 +150,8 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
     // 'Receipt-Delivery-Option' path variable specifying the return-URL.
     @Test
     public void deliveryPathMultipartReportTest() throws Exception {
-        DispositionNotificationMultipartReportEntity reportEntity = 
executeRequestWithAsyncResponsePath();
+        DispositionNotificationMultipartReportEntity reportEntity
+                = executeRequestWithAsyncResponsePath("direct://SEND3", 
"mock:as2RcvRcptMsgs3");
         verifyMultiPartReportParts(reportEntity);
         verifyMultiPartReportEntity(reportEntity);
     }
@@ -154,7 +160,8 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
     // 'Receipt-Delivery-Option' header specifying the return-URL.
     @Test
     public void deliveryHeaderMultipartSignedEntityTest() throws Exception {
-        MultipartSignedEntity responseSignedEntity = 
executeRequestWithSignedAsyncResponseHeader();
+        MultipartSignedEntity responseSignedEntity
+                = executeRequestWithSignedAsyncResponseHeader("direct://SEND", 
RECEIPT_SERVER_PORT2, "mock:as2RcvRcptMsgs2");
 
         MimeEntity responseSignedDataEntity = 
responseSignedEntity.getSignedDataEntity();
         assertTrue(responseSignedDataEntity instanceof 
DispositionNotificationMultipartReportEntity,
@@ -174,7 +181,8 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
     // 'Receipt-Delivery-Option' path variable specifying the return-URL.
     @Test
     public void deliveryPathMultipartSignedEntityTest() throws Exception {
-        MultipartSignedEntity responseSignedEntity = 
executeRequestWithSignedAsyncResponsePath();
+        MultipartSignedEntity responseSignedEntity
+                = executeRequestWithSignedAsyncResponsePath("direct://SEND4", 
"mock:as2RcvRcptMsgs4");
 
         MimeEntity responseSignedDataEntity = 
responseSignedEntity.getSignedDataEntity();
         assertTrue(responseSignedDataEntity instanceof 
DispositionNotificationMultipartReportEntity,
@@ -241,8 +249,8 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
                 "Received content MIC does not match computed");
     }
 
-    private DispositionNotificationMultipartReportEntity verifyAsyncResponse() 
throws Exception {
-        Exchange exchange = receiveFromMock(MOCK_RECEIPT_ENDPOINT);
+    private DispositionNotificationMultipartReportEntity 
verifyAsyncResponse(String mock) throws Exception {
+        Exchange exchange = receiveFromMock(mock);
         Message message = exchange.getIn();
         assertNotNull(message);
         assertTrue(message.getBody() instanceof 
DispositionNotificationMultipartReportEntity);
@@ -250,8 +258,8 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
         return (DispositionNotificationMultipartReportEntity) 
message.getBody();
     }
 
-    private MultipartSignedEntity verifySignedAsyncResponse() throws Exception 
{
-        Exchange exchange = receiveFromMock(MOCK_RECEIPT_ENDPOINT);
+    private MultipartSignedEntity verifySignedAsyncResponse(String mock) 
throws Exception {
+        Exchange exchange = receiveFromMock(mock);
         Message message = exchange.getIn();
         assertNotNull(message);
         assertTrue(message.getBody() instanceof MultipartSignedEntity);
@@ -260,42 +268,46 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
     }
 
     // Request asynchronous receipt by including a 'receiptDeliveryOption' 
header specifying the return url.
-    private DispositionNotificationMultipartReportEntity 
executeRequestWithAsyncResponseHeader() throws Exception {
-        executeRequestAsyncHeader(getAS2HeadersForAsyncReceipt());
+    private DispositionNotificationMultipartReportEntity 
executeRequestWithAsyncResponseHeader(
+            String endpointUri, int port, String mock)
+            throws Exception {
+        executeRequestAsyncHeader(endpointUri, 
getAS2HeadersForAsyncReceipt("http://localhost:"; + port + "/handle-receipts"));
 
-        return verifyAsyncResponse();
+        return verifyAsyncResponse(mock);
     }
 
     // Request asynchronous receipt by including a 'receiptDeliveryOption' 
path parameter in the endpoint uri
     // specifying the return url.
-    private DispositionNotificationMultipartReportEntity 
executeRequestWithAsyncResponsePath() throws Exception {
-        executeRequestAsyncPath(getAS2Headers());
+    private DispositionNotificationMultipartReportEntity 
executeRequestWithAsyncResponsePath(String endpointUri, String mock)
+            throws Exception {
+        executeRequestAsyncPath(endpointUri, getAS2Headers());
 
-        return verifyAsyncResponse();
+        return verifyAsyncResponse(mock);
     }
 
     // Request signed asynchronous receipt by including a 
'receiptDeliveryOption' header specifying the return url,
     // and a 'signedReceiptMicAlgorithms' header specifying the signing 
algorithms.
-    private MultipartSignedEntity 
executeRequestWithSignedAsyncResponseHeader() throws Exception {
-        Map<String, Object> headers = getAS2HeadersForAsyncReceipt();
+    private MultipartSignedEntity 
executeRequestWithSignedAsyncResponseHeader(String endpointUri, int port, 
String mock)
+            throws Exception {
+        Map<String, Object> headers = 
getAS2HeadersForAsyncReceipt("http://localhost:"; + port + "/handle-receipts");
         addSignedMessageHeaders(headers);
         // In order to receive signed MDN receipts the client must include 
both the 'signed-receipt-protocol' and
         // the 'signed-receipt-micalg' option parameters.
-        executeRequestAsyncHeader(headers);
+        executeRequestAsyncHeader(endpointUri, headers);
 
-        return verifySignedAsyncResponse();
+        return verifySignedAsyncResponse(mock);
     }
 
     // Request a signed asynchronous receipt by including a 
'receiptDeliveryOption' path parameter in the endpoint uri
     // specifying the return url, and a 'signedReceiptMicAlgorithms' header 
specifying the signing algorithms.
-    private MultipartSignedEntity executeRequestWithSignedAsyncResponsePath() 
throws Exception {
+    private MultipartSignedEntity 
executeRequestWithSignedAsyncResponsePath(String endpointUri, String mock) 
throws Exception {
         Map<String, Object> headers = getAS2Headers();
         addSignedMessageHeaders(headers);
         // In order to receive signed MDN receipts the client must include 
both the 'signed-receipt-protocol' and
         // the 'signed-receipt-micalg' option parameters.
-        executeRequestAsyncPath(headers);
+        executeRequestAsyncPath(endpointUri, headers);
 
-        return verifySignedAsyncResponse();
+        return verifySignedAsyncResponse(mock);
     }
 
     private void addSignedMessageHeaders(Map<String, Object> headers) {
@@ -324,9 +336,9 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
     }
 
     // Headers requesting that the AS2-MDN (receipt) be returned asynchronously
-    private Map<String, Object> getAS2HeadersForAsyncReceipt() {
+    private Map<String, Object> getAS2HeadersForAsyncReceipt(String 
deliveryAddress) {
         Map<String, Object> headers = getAS2Headers();
-        headers.put("CamelAs2.receiptDeliveryOption", 
RECIPIENT_DELIVERY_ADDRESS);
+        headers.put("CamelAs2.receiptDeliveryOption", deliveryAddress);
 
         return headers;
     }
@@ -344,16 +356,18 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
         return exchanges.get(0);
     }
 
-    private Triple<HttpEntity, HttpRequest, HttpResponse> 
executeRequestAsyncHeader(Map<String, Object> headers)
+    private Triple<HttpEntity, HttpRequest, HttpResponse> 
executeRequestAsyncHeader(
+            String endpointUri, Map<String, Object> headers)
             throws Exception {
-        HttpEntity responseEntity = requestBodyAndHeaders("direct://SEND", 
EDI_MESSAGE, headers);
+        HttpEntity responseEntity = requestBodyAndHeaders(endpointUri, 
EDI_MESSAGE, headers);
 
         return new ImmutableTriple<>(responseEntity, 
requestHandler.getRequest(), requestHandler.getResponse());
     }
 
-    private Triple<HttpEntity, HttpRequest, HttpResponse> 
executeRequestAsyncPath(Map<String, Object> headers)
+    private Triple<HttpEntity, HttpRequest, HttpResponse> 
executeRequestAsyncPath(
+            String endpointUri, Map<String, Object> headers)
             throws Exception {
-        HttpEntity responseEntity = requestBodyAndHeaders("direct://SEND2", 
EDI_MESSAGE, headers);
+        HttpEntity responseEntity = requestBodyAndHeaders(endpointUri, 
EDI_MESSAGE, headers);
 
         return new ImmutableTriple<>(responseEntity, 
requestHandler.getRequest(), requestHandler.getResponse());
     }
@@ -368,14 +382,30 @@ public class AS2AsyncMDNServerManagerIT extends 
AbstractAS2ITSupport {
                         
.to("as2://client/send?inBody=ediMessage&httpSocketTimeout=5m&httpConnectionTimeout=5m");
 
                 // with option for asynchronous receipt specified as path-param
-                from("direct://SEND2")
+                from("direct://SEND3")
                         
.toF("as2://client/send?inBody=ediMessage&httpSocketTimeout=5m&httpConnectionTimeout=5m"
-                             + "&receiptDeliveryOption=%s", 
RECIPIENT_DELIVERY_ADDRESS);
+                             + "&receiptDeliveryOption=%s", 
"http://localhost:"; + RECEIPT_SERVER_PORT3 + "/handle-receipts");
+
+                from("direct://SEND4")
+                        
.toF("as2://client/send?inBody=ediMessage&httpSocketTimeout=5m&httpConnectionTimeout=5m"
+                             + "&receiptDeliveryOption=%s", 
"http://localhost:"; + RECEIPT_SERVER_PORT4 + "/handle-receipts");
 
                 // asynchronous AS2-MDN (receipt) server instance
                 
fromF("as2://receipt/receive?requestUriPattern=/handle-receipts&asyncMdnPortNumber=%s",
                         RECEIPT_SERVER_PORT)
-                        .to(MOCK_RECEIPT_ENDPOINT);
+                        .to("mock:as2RcvRcptMsgs");
+
+                
fromF("as2://receipt/receive?requestUriPattern=/handle-receipts&asyncMdnPortNumber=%s",
+                        RECEIPT_SERVER_PORT2)
+                        .to("mock:as2RcvRcptMsgs2");
+
+                
fromF("as2://receipt/receive?requestUriPattern=/handle-receipts&asyncMdnPortNumber=%s",
+                        RECEIPT_SERVER_PORT3)
+                        .to("mock:as2RcvRcptMsgs3");
+
+                
fromF("as2://receipt/receive?requestUriPattern=/handle-receipts&asyncMdnPortNumber=%s",
+                        RECEIPT_SERVER_PORT4)
+                        .to("mock:as2RcvRcptMsgs4");
             }
         };
     }

Reply via email to