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 b40a1ad5022 CAMEL-17495 Added support of media type "application/xml" for AS2 component (#9999) b40a1ad5022 is described below commit b40a1ad5022c71e238123bedd937d70c7292c76e Author: Dmitry Kryukov <d...@users.noreply.github.com> AuthorDate: Sat May 6 10:09:05 2023 +0300 CAMEL-17495 Added support of media type "application/xml" for AS2 component (#9999) --- .../camel/component/as2/api/AS2ClientManager.java | 24 ++-- .../camel/component/as2/api/AS2MediaType.java | 4 + .../camel/component/as2/api/AS2MimeType.java | 4 + .../api/entity/ApplicationEDIConsentEntity.java | 2 +- .../as2/api/entity/ApplicationEDIFACTEntity.java | 2 +- .../as2/api/entity/ApplicationEDIX12Entity.java | 2 +- ...cationEDIEntity.java => ApplicationEntity.java} | 6 +- ...EDIX12Entity.java => ApplicationXMLEntity.java} | 8 +- .../component/as2/api/entity/EntityParser.java | 13 +- .../camel/component/as2/api/util/EntityUtils.java | 7 +- .../component/as2/api/util/HttpMessageUtils.java | 44 +++---- .../camel/component/as2/api/AS2MessageTest.java | 10 +- .../component/as2/api/util/EntityUtilsTest.java | 20 +-- .../camel/component/as2/AS2Configuration.java | 3 +- .../apache/camel/component/as2/AS2Consumer.java | 4 +- .../camel/component/as2/AS2ClientManagerIT.java | 134 +++++++++++++++++++-- .../camel/component/as2/AS2ServerManagerIT.java | 83 +++++++++++++ 17 files changed, 288 insertions(+), 82 deletions(-) diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java index ba089042eba..64a87e92e76 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java @@ -22,7 +22,7 @@ import java.security.PrivateKey; import java.security.cert.Certificate; import java.util.concurrent.ExecutionException; -import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity; +import org.apache.camel.component.as2.api.entity.ApplicationEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeCompressedDataEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity; import org.apache.camel.component.as2.api.entity.EntityParser; @@ -249,9 +249,9 @@ public class AS2ClientManager { httpContext.setAttribute(HTTP_REQUEST, request); // Create Message Body - ApplicationEDIEntity applicationEDIEntity; + ApplicationEntity applicationEntity; try { - applicationEDIEntity + applicationEntity = EntityUtils.createEDIEntity(ediMessage, ediMessageContentType, ediMessageTransferEncoding, false, attachedFileName); } catch (Exception e) { @@ -260,15 +260,15 @@ public class AS2ClientManager { switch (as2MessageStructure) { case PLAIN: { // Add EDI Entity to main body of request. - applicationEDIEntity.setMainBody(true); - EntityUtils.setMessageEntity(request, applicationEDIEntity); + applicationEntity.setMainBody(true); + EntityUtils.setMessageEntity(request, applicationEntity); break; } case SIGNED: { // Create Multipart Signed Entity containing EDI Entity AS2SignedDataGenerator signingGenerator = createSigningGenerator(httpContext); MultipartSignedEntity multipartSignedEntity = new MultipartSignedEntity( - applicationEDIEntity, signingGenerator, + applicationEntity, signingGenerator, StandardCharsets.US_ASCII.name(), AS2TransferEncoding.BASE64, true, null); // Add Multipart Signed Entity to main body of request. @@ -281,7 +281,7 @@ public class AS2ClientManager { OutputEncryptor encryptor = createEncryptor(httpContext); ApplicationPkcs7MimeEnvelopedDataEntity pkcs7MimeEnvelopedDataEntity = new ApplicationPkcs7MimeEnvelopedDataEntity( - applicationEDIEntity, envelopedDataGenerator, encryptor, AS2TransferEncoding.BASE64, true); + applicationEntity, envelopedDataGenerator, encryptor, AS2TransferEncoding.BASE64, true); // Add Multipart Enveloped Entity to main body of request. EntityUtils.setMessageEntity(request, pkcs7MimeEnvelopedDataEntity); @@ -291,7 +291,7 @@ public class AS2ClientManager { // Create Multipart Signed Entity containing EDI Entity AS2SignedDataGenerator signingGenrator = createSigningGenerator(httpContext); MultipartSignedEntity multipartSignedEntity = new MultipartSignedEntity( - applicationEDIEntity, + applicationEntity, signingGenrator, StandardCharsets.US_ASCII.name(), AS2TransferEncoding.BASE64, false, null); // Create Enveloped Entity containing Multipart Signed Entity @@ -311,7 +311,7 @@ public class AS2ClientManager { OutputCompressor compressor = createCompressor(httpContext); ApplicationPkcs7MimeCompressedDataEntity pkcs7MimeCompressedDataEntity = new ApplicationPkcs7MimeCompressedDataEntity( - applicationEDIEntity, compressedDataGenerator, compressor, AS2TransferEncoding.BASE64, true); + applicationEntity, compressedDataGenerator, compressor, AS2TransferEncoding.BASE64, true); // Add Compressed Entity to main body of request. EntityUtils.setMessageEntity(request, pkcs7MimeCompressedDataEntity); @@ -321,7 +321,7 @@ public class AS2ClientManager { // Create Multipart Signed Entity containing EDI Entity AS2SignedDataGenerator signingGenrator = createSigningGenerator(httpContext); MultipartSignedEntity multipartSignedEntity = new MultipartSignedEntity( - applicationEDIEntity, + applicationEntity, signingGenrator, StandardCharsets.US_ASCII.name(), AS2TransferEncoding.BASE64, false, null); // Create Compressed Entity containing Multipart Signed Entity @@ -341,7 +341,7 @@ public class AS2ClientManager { OutputCompressor compressor = createCompressor(httpContext); ApplicationPkcs7MimeCompressedDataEntity pkcs7MimeCompressedDataEntity = new ApplicationPkcs7MimeCompressedDataEntity( - applicationEDIEntity, compressedDataGenerator, compressor, AS2TransferEncoding.BASE64, false); + applicationEntity, compressedDataGenerator, compressor, AS2TransferEncoding.BASE64, false); // Create Enveloped Entity containing Compressed Entity CMSEnvelopedDataGenerator envelopedDataGenerator = createEncryptingGenerator(httpContext); @@ -359,7 +359,7 @@ public class AS2ClientManager { // Create Multipart Signed Entity containing EDI Entity AS2SignedDataGenerator signingGenrator = createSigningGenerator(httpContext); MultipartSignedEntity multipartSignedEntity = new MultipartSignedEntity( - applicationEDIEntity, signingGenrator, + applicationEntity, signingGenrator, StandardCharsets.US_ASCII.name(), AS2TransferEncoding.BASE64, false, null); // Create Compressed Entity containing Multipart Signed Entity diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MediaType.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MediaType.java index 289485c0932..3b93cef2c9c 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MediaType.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MediaType.java @@ -50,4 +50,8 @@ public interface AS2MediaType { * Media Type for Application/EDI-consent */ String APPLICATION_EDI_CONSENT = "application/edi-consent"; + /** + * Media Type for Application/XML + */ + String APPLICATION_XML = "application/xml"; } diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MimeType.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MimeType.java index 1eff9d96047..5b51a877b32 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MimeType.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2MimeType.java @@ -37,6 +37,10 @@ public interface AS2MimeType { * Mime Type for Application/EDIFACT */ String APPLICATION_EDIFACT = "application/edifact"; + /** + * Mime Type for Application/XML + */ + String APPLICATION_XML = "application/xml"; /** * Mime Type for Application/EDI-X12 */ diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIConsentEntity.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIConsentEntity.java index f91c2ab65f3..58d6422de1b 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIConsentEntity.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIConsentEntity.java @@ -19,7 +19,7 @@ package org.apache.camel.component.as2.api.entity; import org.apache.camel.component.as2.api.AS2MediaType; import org.apache.http.entity.ContentType; -public class ApplicationEDIConsentEntity extends ApplicationEDIEntity { +public class ApplicationEDIConsentEntity extends ApplicationEntity { public ApplicationEDIConsentEntity(String content, String charset, String contentTransferEncoding, boolean isMainBody, String fileName) { diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIFACTEntity.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIFACTEntity.java index 02fc6ce10e7..e3011cee2bb 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIFACTEntity.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIFACTEntity.java @@ -19,7 +19,7 @@ package org.apache.camel.component.as2.api.entity; import org.apache.camel.component.as2.api.AS2MediaType; import org.apache.http.entity.ContentType; -public class ApplicationEDIFACTEntity extends ApplicationEDIEntity { +public class ApplicationEDIFACTEntity extends ApplicationEntity { public ApplicationEDIFACTEntity(String content, String charset, String contentTransferEncoding, boolean isMainBody, String filename) { diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIX12Entity.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIX12Entity.java index 9d92f016091..cebd717737c 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIX12Entity.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIX12Entity.java @@ -19,7 +19,7 @@ package org.apache.camel.component.as2.api.entity; import org.apache.camel.component.as2.api.AS2MediaType; import org.apache.http.entity.ContentType; -public class ApplicationEDIX12Entity extends ApplicationEDIEntity { +public class ApplicationEDIX12Entity extends ApplicationEntity { public ApplicationEDIX12Entity(String content, String charset, String contentTransferEncoding, boolean isMainBody, String filename) { diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIEntity.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEntity.java similarity index 92% rename from components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIEntity.java rename to components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEntity.java index 77c06203c56..67d09c2fe2a 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIEntity.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEntity.java @@ -30,14 +30,14 @@ import org.apache.http.HeaderIterator; import org.apache.http.entity.ContentType; import org.slf4j.helpers.MessageFormatter; -public abstract class ApplicationEDIEntity extends MimeEntity { +public abstract class ApplicationEntity extends MimeEntity { protected static final String CONTENT_DISPOSITION_PATTERN = "attachment; filename={}"; private final String ediMessage; - protected ApplicationEDIEntity(String ediMessage, ContentType contentType, String contentTransferEncoding, - boolean isMainBody, String filename) { + protected ApplicationEntity(String ediMessage, ContentType contentType, String contentTransferEncoding, + boolean isMainBody, String filename) { this.ediMessage = ObjectHelper.notNull(ediMessage, "EDI Message"); setContentType(ObjectHelper.notNull(contentType, "Content Type").toString()); setContentTransferEncoding(contentTransferEncoding); diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIX12Entity.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationXMLEntity.java similarity index 77% copy from components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIX12Entity.java copy to components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationXMLEntity.java index 9d92f016091..4c5feb5ea70 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationEDIX12Entity.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationXMLEntity.java @@ -19,11 +19,11 @@ package org.apache.camel.component.as2.api.entity; import org.apache.camel.component.as2.api.AS2MediaType; import org.apache.http.entity.ContentType; -public class ApplicationEDIX12Entity extends ApplicationEDIEntity { +public class ApplicationXMLEntity extends ApplicationEntity { - public ApplicationEDIX12Entity(String content, String charset, String contentTransferEncoding, - boolean isMainBody, String filename) { - super(content, ContentType.create(AS2MediaType.APPLICATION_EDI_X12, charset), contentTransferEncoding, isMainBody, + public ApplicationXMLEntity(String content, String charset, String contentTransferEncoding, + boolean isMainBody, String filename) { + super(content, ContentType.create(AS2MediaType.APPLICATION_XML, charset), contentTransferEncoding, isMainBody, filename); } diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java index 768c80a71e3..cba6b1d7ab2 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java @@ -369,14 +369,14 @@ public final class EntityParser { private static void parseApplicationEDIEntity( HttpMessage message, AS2SessionInputBuffer inBuffer, ContentType contentType, String contentTransferEncoding) throws HttpException { - ApplicationEDIEntity applicationEDIEntity = null; + ApplicationEntity applicationEntity = null; ObjectHelper.notNull(message, "message"); ObjectHelper.notNull(inBuffer, "inBuffer"); HttpEntity entity = ObjectHelper.notNull(EntityUtils.getMessageEntity(message), "message entity"); - if (entity instanceof ApplicationEDIEntity) { + if (entity instanceof ApplicationEntity) { // already parsed return; } @@ -385,10 +385,10 @@ public final class EntityParser { try { - applicationEDIEntity = parseEDIEntityBody(inBuffer, null, contentType, contentTransferEncoding, ""); - applicationEDIEntity.setMainBody(true); + applicationEntity = parseEDIEntityBody(inBuffer, null, contentType, contentTransferEncoding, ""); + applicationEntity.setMainBody(true); - EntityUtils.setMessageEntity(message, applicationEDIEntity); + EntityUtils.setMessageEntity(message, applicationEntity); } catch (Exception e) { throw new HttpException("Failed to parse entity content", e); @@ -806,6 +806,7 @@ public final class EntityParser { case AS2MimeType.APPLICATION_EDIFACT: case AS2MimeType.APPLICATION_EDI_X12: case AS2MimeType.APPLICATION_EDI_CONSENT: + case AS2MimeType.APPLICATION_XML: entity = parseEDIEntityBody(inbuffer, boundary, entityContentType, contentTransferEncoding, filename); break; case AS2MimeType.MULTIPART_SIGNED: @@ -863,7 +864,7 @@ public final class EntityParser { } - public static ApplicationEDIEntity parseEDIEntityBody( + public static ApplicationEntity parseEDIEntityBody( AS2SessionInputBuffer inbuffer, String boundary, ContentType ediMessageContentType, diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java index 02df108a54e..d9a03b4d1c5 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java @@ -29,9 +29,10 @@ import org.apache.camel.CamelException; import org.apache.camel.component.as2.api.AS2Header; import org.apache.camel.component.as2.api.AS2MediaType; import org.apache.camel.component.as2.api.entity.ApplicationEDIConsentEntity; -import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity; import org.apache.camel.component.as2.api.entity.ApplicationEDIFACTEntity; import org.apache.camel.component.as2.api.entity.ApplicationEDIX12Entity; +import org.apache.camel.component.as2.api.entity.ApplicationEntity; +import org.apache.camel.component.as2.api.entity.ApplicationXMLEntity; import org.apache.camel.component.as2.api.entity.MimeEntity; import org.apache.camel.util.ObjectHelper; import org.apache.commons.codec.DecoderException; @@ -181,7 +182,7 @@ public final class EntityUtils { } } - public static ApplicationEDIEntity createEDIEntity( + public static ApplicationEntity createEDIEntity( String ediMessage, ContentType ediMessageContentType, String contentTransferEncoding, boolean isMainBody, String filename) throws CamelException { @@ -198,6 +199,8 @@ public final class EntityUtils { return new ApplicationEDIX12Entity(ediMessage, charset, contentTransferEncoding, isMainBody, filename); case AS2MediaType.APPLICATION_EDI_CONSENT: return new ApplicationEDIConsentEntity(ediMessage, charset, contentTransferEncoding, isMainBody, filename); + case AS2MediaType.APPLICATION_XML: + return new ApplicationXMLEntity(ediMessage, charset, contentTransferEncoding, isMainBody, filename); default: throw new CamelException("Invalid EDI entity mime type: " + ediMessageContentType.getMimeType()); } diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/HttpMessageUtils.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/HttpMessageUtils.java index b2027569d4f..0bac259d767 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/HttpMessageUtils.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/HttpMessageUtils.java @@ -22,7 +22,7 @@ import java.util.Objects; import org.apache.camel.component.as2.api.AS2Header; import org.apache.camel.component.as2.api.AS2MimeType; -import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity; +import org.apache.camel.component.as2.api.entity.ApplicationEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeCompressedDataEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity; import org.apache.camel.component.as2.api.entity.EntityParser; @@ -127,7 +127,7 @@ public final class HttpMessageUtils { return null; } - public static ApplicationEDIEntity extractEdiPayload(HttpMessage message, DecrpytingAndSigningInfo decrpytingAndSigningInfo) + public static ApplicationEntity extractEdiPayload(HttpMessage message, DecrpytingAndSigningInfo decrpytingAndSigningInfo) throws HttpException { String contentTypeString = getHeaderValue(message, AS2Header.CONTENT_TYPE); @@ -137,12 +137,12 @@ public final class HttpMessageUtils { ContentType contentType = ContentType.parse(contentTypeString); EntityParser.parseAS2MessageEntity(message); - ApplicationEDIEntity ediEntity = null; + ApplicationEntity ediEntity = null; switch (contentType.getMimeType().toLowerCase()) { case AS2MimeType.APPLICATION_EDIFACT: case AS2MimeType.APPLICATION_EDI_X12: case AS2MimeType.APPLICATION_EDI_CONSENT: { - ediEntity = getEntity(message, ApplicationEDIEntity.class); + ediEntity = getEntity(message, ApplicationEntity.class); break; } case AS2MimeType.MULTIPART_SIGNED: { @@ -176,10 +176,10 @@ public final class HttpMessageUtils { } - private static ApplicationEDIEntity extractEnvelopedData( + private static ApplicationEntity extractEnvelopedData( HttpMessage message, DecrpytingAndSigningInfo decrpytingAndSigningInfo) throws HttpException { - ApplicationEDIEntity ediEntity; + ApplicationEntity ediEntity; if (decrpytingAndSigningInfo.getDecryptingPrivateKey() == null) { throw new HttpException( "Failed to extract EDI payload: private key can not be null for AS2 enveloped message"); @@ -193,10 +193,10 @@ public final class HttpMessageUtils { return ediEntity; } - private static ApplicationEDIEntity extractCompressedData( + private static ApplicationEntity extractCompressedData( HttpMessage message, DecrpytingAndSigningInfo decrpytingAndSigningInfo) throws HttpException { - ApplicationEDIEntity ediEntity; + ApplicationEntity ediEntity; ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = getEntity(message, ApplicationPkcs7MimeCompressedDataEntity.class); @@ -207,10 +207,10 @@ public final class HttpMessageUtils { return ediEntity; } - private static ApplicationEDIEntity extractMultipartSigned( + private static ApplicationEntity extractMultipartSigned( HttpMessage message, DecrpytingAndSigningInfo decrpytingAndSigningInfo) throws HttpException { - ApplicationEDIEntity ediEntity; + ApplicationEntity ediEntity; MultipartSignedEntity multipartSignedEntity = getEntity(message, MultipartSignedEntity.class); @@ -223,8 +223,8 @@ public final class HttpMessageUtils { } MimeEntity mimeEntity = multipartSignedEntity.getSignedDataEntity(); - if (mimeEntity instanceof ApplicationEDIEntity) { - ediEntity = (ApplicationEDIEntity) mimeEntity; + if (mimeEntity instanceof ApplicationEntity) { + ediEntity = (ApplicationEntity) mimeEntity; } else if (mimeEntity instanceof ApplicationPkcs7MimeCompressedDataEntity) { ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) mimeEntity; @@ -237,10 +237,10 @@ public final class HttpMessageUtils { return ediEntity; } - private static ApplicationEDIEntity extractEdiPayloadFromEnvelopedEntity( + private static ApplicationEntity extractEdiPayloadFromEnvelopedEntity( ApplicationPkcs7MimeEnvelopedDataEntity envelopedDataEntity, DecrpytingAndSigningInfo decrpytingAndSigningInfo) throws HttpException { - ApplicationEDIEntity ediEntity = null; + ApplicationEntity ediEntity = null; MimeEntity entity = envelopedDataEntity.getEncryptedEntity(decrpytingAndSigningInfo.getDecryptingPrivateKey()); String contentTypeString = entity.getContentTypeValue(); @@ -253,7 +253,7 @@ public final class HttpMessageUtils { case AS2MimeType.APPLICATION_EDIFACT: case AS2MimeType.APPLICATION_EDI_X12: case AS2MimeType.APPLICATION_EDI_CONSENT: { - ediEntity = (ApplicationEDIEntity) entity; + ediEntity = (ApplicationEntity) entity; break; } case AS2MimeType.MULTIPART_SIGNED: { @@ -264,8 +264,8 @@ public final class HttpMessageUtils { } MimeEntity mimeEntity = multipartSignedEntity.getSignedDataEntity(); - if (mimeEntity instanceof ApplicationEDIEntity) { - ediEntity = (ApplicationEDIEntity) mimeEntity; + if (mimeEntity instanceof ApplicationEntity) { + ediEntity = (ApplicationEntity) mimeEntity; } else if (mimeEntity instanceof ApplicationPkcs7MimeCompressedDataEntity) { ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) mimeEntity; @@ -298,10 +298,10 @@ public final class HttpMessageUtils { return ediEntity; } - public static ApplicationEDIEntity extractEdiPayloadFromCompressedEntity( + public static ApplicationEntity extractEdiPayloadFromCompressedEntity( ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity, DecrpytingAndSigningInfo decrpytingAndSigningInfo) throws HttpException { - ApplicationEDIEntity ediEntity = null; + ApplicationEntity ediEntity = null; MimeEntity entity = compressedDataEntity.getCompressedEntity(new ZlibExpanderProvider()); String contentTypeString = entity.getContentTypeValue(); @@ -314,7 +314,7 @@ public final class HttpMessageUtils { case AS2MimeType.APPLICATION_EDIFACT: case AS2MimeType.APPLICATION_EDI_X12: case AS2MimeType.APPLICATION_EDI_CONSENT: { - ediEntity = (ApplicationEDIEntity) entity; + ediEntity = (ApplicationEntity) entity; break; } case AS2MimeType.MULTIPART_SIGNED: { @@ -325,8 +325,8 @@ public final class HttpMessageUtils { } MimeEntity mimeEntity = multipartSignedEntity.getSignedDataEntity(); - if (mimeEntity instanceof ApplicationEDIEntity) { - ediEntity = (ApplicationEDIEntity) mimeEntity; + if (mimeEntity instanceof ApplicationEntity) { + ediEntity = (ApplicationEntity) mimeEntity; } else { throw new HttpException( diff --git a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java index 8117013839d..95faa06bfc5 100644 --- a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java +++ b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java @@ -43,8 +43,8 @@ import com.helger.security.keystore.EKeyStoreType; import org.apache.camel.component.as2.api.entity.AS2DispositionModifier; import org.apache.camel.component.as2.api.entity.AS2DispositionType; import org.apache.camel.component.as2.api.entity.AS2MessageDispositionNotificationEntity; -import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity; import org.apache.camel.component.as2.api.entity.ApplicationEDIFACTEntity; +import org.apache.camel.component.as2.api.entity.ApplicationEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeCompressedDataEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7SignatureEntity; @@ -170,7 +170,7 @@ public class AS2MessageTest { private static File keystoreFile; - private static ApplicationEDIEntity ediEntity; + private static ApplicationEntity ediEntity; private AS2SignedDataGenerator gen; @@ -655,8 +655,8 @@ public class AS2MessageTest { assertTrue(entity instanceof MultipartSignedEntity, "Unexpected request entity type"); MultipartSignedEntity multipartSignedEntity = (MultipartSignedEntity) entity; MimeEntity signedEntity = multipartSignedEntity.getSignedDataEntity(); - assertTrue(signedEntity instanceof ApplicationEDIEntity, "Signed entity wrong type"); - ApplicationEDIEntity ediMessageEntity = (ApplicationEDIEntity) signedEntity; + assertTrue(signedEntity instanceof ApplicationEntity, "Signed entity wrong type"); + ApplicationEntity ediMessageEntity = (ApplicationEntity) signedEntity; assertNotNull(ediMessageEntity, "Multipart signed entity does not contain EDI message entity"); ApplicationPkcs7SignatureEntity signatureEntity = multipartSignedEntity.getSignatureEntity(); assertNotNull(signatureEntity, "Multipart signed entity does not contain signature entity"); @@ -714,7 +714,7 @@ public class AS2MessageTest { certList.toArray(new X509Certificate[0]), signingKP.getPrivate()); // Create plain edi request message to acknowledge - ApplicationEDIEntity ediEntity = EntityUtils.createEDIEntity(EDI_MESSAGE, + ApplicationEntity ediEntity = EntityUtils.createEDIEntity(EDI_MESSAGE, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, StandardCharsets.US_ASCII), null, false, "filename.txt"); HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", REQUEST_URI); HttpMessageUtils.setHeaderValue(request, AS2Header.SUBJECT, SUBJECT); diff --git a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/EntityUtilsTest.java b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/EntityUtilsTest.java index 63ec1b2afed..9a3f992a385 100644 --- a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/EntityUtilsTest.java +++ b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/EntityUtilsTest.java @@ -20,7 +20,7 @@ import java.nio.charset.StandardCharsets; import org.apache.camel.component.as2.api.AS2Header; import org.apache.camel.component.as2.api.AS2MediaType; -import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity; +import org.apache.camel.component.as2.api.entity.ApplicationEntity; import org.apache.http.Header; import org.apache.http.entity.ContentType; import org.junit.jupiter.api.Assertions; @@ -32,11 +32,11 @@ public class EntityUtilsTest { public void testCreateEDIEntityContentTypeWithoutEncoding() throws Exception { ContentType ediMessageContentType = ContentType.create(AS2MediaType.APPLICATION_EDIFACT, (String) null); String ediMessage = "whatever"; - ApplicationEDIEntity applicationEDIEntity + ApplicationEntity applicationEntity = EntityUtils.createEDIEntity(ediMessage, ediMessageContentType, null, false, "sample.txt"); - String actualContentType = applicationEDIEntity.getContentTypeValue(); + String actualContentType = applicationEntity.getContentTypeValue(); Assertions.assertEquals("application/edifact", actualContentType, "content type matches"); - Header[] actualContentDisposition = applicationEDIEntity.getHeaders(AS2Header.CONTENT_DISPOSITION); + Header[] actualContentDisposition = applicationEntity.getHeaders(AS2Header.CONTENT_DISPOSITION); Assertions.assertEquals(1, actualContentDisposition.length, "exactly one Content-Disposition header found"); Assertions.assertEquals("Content-Disposition: attachment; filename=sample.txt", actualContentDisposition[0].toString()); @@ -46,11 +46,11 @@ public class EntityUtilsTest { public void testCreateEDIEntityContentTypeWithEncoding() throws Exception { ContentType ediMessageContentType = ContentType.create(AS2MediaType.APPLICATION_EDIFACT, StandardCharsets.US_ASCII); String ediMessage = "whatever"; - ApplicationEDIEntity applicationEDIEntity + ApplicationEntity applicationEntity = EntityUtils.createEDIEntity(ediMessage, ediMessageContentType, null, false, "sample.txt"); - String actualContentType = applicationEDIEntity.getContentTypeValue(); + String actualContentType = applicationEntity.getContentTypeValue(); Assertions.assertEquals("application/edifact; charset=US-ASCII", actualContentType, "content type matches"); - Header[] actualContentDisposition = applicationEDIEntity.getHeaders(AS2Header.CONTENT_DISPOSITION); + Header[] actualContentDisposition = applicationEntity.getHeaders(AS2Header.CONTENT_DISPOSITION); Assertions.assertEquals(1, actualContentDisposition.length, "exactly one Content-Disposition header found"); Assertions.assertEquals("Content-Disposition: attachment; filename=sample.txt", actualContentDisposition[0].toString()); @@ -60,11 +60,11 @@ public class EntityUtilsTest { public void testCreateEDIEntityContentTypeWithoutContentDisposition() throws Exception { ContentType ediMessageContentType = ContentType.create(AS2MediaType.APPLICATION_EDIFACT, (String) null); String ediMessage = "whatever"; - ApplicationEDIEntity applicationEDIEntity + ApplicationEntity applicationEntity = EntityUtils.createEDIEntity(ediMessage, ediMessageContentType, null, false, ""); - String actualContentType = applicationEDIEntity.getContentTypeValue(); + String actualContentType = applicationEntity.getContentTypeValue(); Assertions.assertEquals("application/edifact", actualContentType, "content type matches"); - Header[] actualContentDisposition = applicationEDIEntity.getHeaders(AS2Header.CONTENT_DISPOSITION); + Header[] actualContentDisposition = applicationEntity.getHeaders(AS2Header.CONTENT_DISPOSITION); Assertions.assertEquals(0, actualContentDisposition.length, "no Content-Disposition headers found"); } } diff --git a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java index 8be9214115b..f9916915dfd 100644 --- a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java +++ b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java @@ -259,7 +259,8 @@ public class AS2Configuration { } /** - * The content type of EDI message. One of application/edifact, application/edi-x12, application/edi-consent + * The content type of EDI message. One of application/edifact, application/edi-x12, application/edi-consent, + * application/xml */ public void setEdiMessageType(ContentType ediMessageType) { this.ediMessageType = ediMessageType; diff --git a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java index 540fe9c0242..92d39d0f038 100644 --- a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java +++ b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Consumer.java @@ -24,7 +24,7 @@ import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.component.as2.api.AS2ServerConnection; import org.apache.camel.component.as2.api.AS2ServerManager; -import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity; +import org.apache.camel.component.as2.api.entity.ApplicationEntity; import org.apache.camel.component.as2.api.entity.EntityParser; import org.apache.camel.component.as2.api.util.HttpMessageUtils; import org.apache.camel.component.as2.internal.AS2ApiName; @@ -120,7 +120,7 @@ public class AS2Consumer extends AbstractApiConsumer<AS2ApiName, AS2Configuratio apiProxy.handleMDNResponse(context, getEndpoint().getSubject(), ofNullable(getEndpoint().getFrom()).orElse(getEndpoint().getConfiguration().getServer())); } - ApplicationEDIEntity ediEntity + ApplicationEntity ediEntity = HttpMessageUtils.extractEdiPayload(request, new HttpMessageUtils.DecrpytingAndSigningInfo( as2ServerConnection.getValidateSigningCertificateChain(), diff --git a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java index 7736ea68f33..cff3b7ba171 100644 --- a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java +++ b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java @@ -44,7 +44,7 @@ import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.api.entity.AS2DispositionModifier; import org.apache.camel.component.as2.api.entity.AS2DispositionType; import org.apache.camel.component.as2.api.entity.AS2MessageDispositionNotificationEntity; -import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity; +import org.apache.camel.component.as2.api.entity.ApplicationEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeCompressedDataEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7SignatureEntity; @@ -196,8 +196,8 @@ public class AS2ClientManagerIT extends AbstractAS2ITSupport { assertTrue(request instanceof HttpEntityEnclosingRequest, "Request does not contain body"); HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); assertNotNull(entity, "Request body"); - assertTrue(entity instanceof ApplicationEDIEntity, "Request body does not contain EDI entity"); - String ediMessage = ((ApplicationEDIEntity) entity).getEdiMessage(); + assertTrue(entity instanceof ApplicationEntity, "Request body does not contain EDI entity"); + String ediMessage = ((ApplicationEntity) entity).getEdiMessage(); assertEquals(EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""), "EDI message is different"); assertNotNull(response, "Response"); @@ -275,8 +275,8 @@ public class AS2ClientManagerIT extends AbstractAS2ITSupport { assertTrue(request instanceof HttpEntityEnclosingRequest, "Request does not contain body"); HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); assertNotNull(entity, "Request body"); - assertTrue(entity instanceof ApplicationEDIEntity, "Request body does not contain EDI entity"); - String ediMessage = ((ApplicationEDIEntity) entity).getEdiMessage(); + assertTrue(entity instanceof ApplicationEntity, "Request body does not contain EDI entity"); + String ediMessage = ((ApplicationEntity) entity).getEdiMessage(); assertEquals(EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""), "EDI message is different"); assertNotNull(response, "Response"); @@ -367,8 +367,8 @@ public class AS2ClientManagerIT extends AbstractAS2ITSupport { "Request body does not contain ApplicationPkcs7Mime entity"); MimeEntity envelopeEntity = ((ApplicationPkcs7MimeEnvelopedDataEntity) entity).getEncryptedEntity(clientKeyPair.getPrivate()); - assertTrue(envelopeEntity instanceof ApplicationEDIEntity, "Enveloped entity is not an EDI entity"); - String ediMessage = ((ApplicationEDIEntity) envelopeEntity).getEdiMessage(); + assertTrue(envelopeEntity instanceof ApplicationEntity, "Enveloped entity is not an EDI entity"); + String ediMessage = ((ApplicationEntity) envelopeEntity).getEdiMessage(); assertEquals(EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""), "EDI message is different"); assertNotNull(response, "Response"); @@ -461,8 +461,118 @@ public class AS2ClientManagerIT extends AbstractAS2ITSupport { assertTrue(entity instanceof MultipartSignedEntity, "Request body does not contain EDI entity"); MimeEntity signedEntity = ((MultipartSignedEntity) entity).getSignedDataEntity(); - assertTrue(signedEntity instanceof ApplicationEDIEntity, "Signed entity wrong type"); - ApplicationEDIEntity ediMessageEntity = (ApplicationEDIEntity) signedEntity; + assertTrue(signedEntity instanceof ApplicationEntity, "Signed entity wrong type"); + ApplicationEntity ediMessageEntity = (ApplicationEntity) signedEntity; + String ediMessage = ediMessageEntity.getEdiMessage(); + assertEquals(EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""), "EDI message is different"); + + assertNotNull(response, "Response"); + String contentTypeHeaderValue = HttpMessageUtils.getHeaderValue(response, AS2Header.CONTENT_TYPE); + ContentType responseContentType = ContentType.parse(contentTypeHeaderValue); + assertEquals(AS2MimeType.MULTIPART_SIGNED, responseContentType.getMimeType(), "Unexpected response type"); + assertEquals(AS2Constants.MIME_VERSION, HttpMessageUtils.getHeaderValue(response, AS2Header.MIME_VERSION), + "Unexpected mime version"); + assertEquals(EXPECTED_AS2_VERSION, HttpMessageUtils.getHeaderValue(response, AS2Header.AS2_VERSION), + "Unexpected AS2 version"); + assertEquals(EXPECTED_MDN_SUBJECT, HttpMessageUtils.getHeaderValue(response, AS2Header.SUBJECT), + "Unexpected MDN subject"); + assertEquals(MDN_FROM, HttpMessageUtils.getHeaderValue(response, AS2Header.FROM), "Unexpected MDN from"); + assertEquals(AS2_NAME, HttpMessageUtils.getHeaderValue(response, AS2Header.AS2_FROM), "Unexpected AS2 from"); + assertEquals(AS2_NAME, HttpMessageUtils.getHeaderValue(response, AS2Header.AS2_TO), "Unexpected AS2 to"); + assertNotNull(HttpMessageUtils.getHeaderValue(response, AS2Header.MESSAGE_ID), "Missing message id"); + + assertNotNull(responseEntity, "Response entity"); + assertTrue(responseEntity instanceof MultipartSignedEntity, "Unexpected response entity type"); + MultipartSignedEntity responseSignedEntity = (MultipartSignedEntity) responseEntity; + assertTrue(SigningUtils.isValid(responseSignedEntity, new Certificate[] { serverCert }), + "Signature for response entity is invalid"); + MimeEntity responseSignedDataEntity = responseSignedEntity.getSignedDataEntity(); + assertTrue(responseSignedDataEntity instanceof DispositionNotificationMultipartReportEntity, + "Signed entity wrong type"); + DispositionNotificationMultipartReportEntity reportEntity + = (DispositionNotificationMultipartReportEntity) responseSignedDataEntity; + assertEquals(2, reportEntity.getPartCount(), "Unexpected number of body parts in report"); + MimeEntity firstPart = reportEntity.getPart(0); + assertEquals(ContentType.create(AS2MimeType.TEXT_PLAIN, StandardCharsets.US_ASCII).toString(), + firstPart.getContentTypeValue(), "Unexpected content type in first body part of report"); + MimeEntity secondPart = reportEntity.getPart(1); + assertEquals(ContentType.create(AS2MimeType.MESSAGE_DISPOSITION_NOTIFICATION, StandardCharsets.US_ASCII).toString(), + secondPart.getContentTypeValue(), + "Unexpected content type in second body part of report"); + ApplicationPkcs7SignatureEntity signatureEntity = responseSignedEntity.getSignatureEntity(); + assertNotNull(signatureEntity, "Signature Entity"); + + assertTrue(secondPart instanceof AS2MessageDispositionNotificationEntity, ""); + AS2MessageDispositionNotificationEntity messageDispositionNotificationEntity + = (AS2MessageDispositionNotificationEntity) secondPart; + assertEquals(ORIGIN_SERVER_NAME, messageDispositionNotificationEntity.getReportingUA(), + "Unexpected value for reporting UA"); + assertEquals(AS2_NAME, messageDispositionNotificationEntity.getFinalRecipient(), + "Unexpected value for final recipient"); + assertEquals(HttpMessageUtils.getHeaderValue(request, AS2Header.MESSAGE_ID), + messageDispositionNotificationEntity.getOriginalMessageId(), "Unexpected value for original message ID"); + assertEquals(DispositionMode.AUTOMATIC_ACTION_MDN_SENT_AUTOMATICALLY, + messageDispositionNotificationEntity.getDispositionMode(), "Unexpected value for disposition mode"); + assertEquals(AS2DispositionType.PROCESSED, messageDispositionNotificationEntity.getDispositionType(), + "Unexpected value for disposition type"); + + ReceivedContentMic receivedContentMic = messageDispositionNotificationEntity.getReceivedContentMic(); + ReceivedContentMic computedContentMic + = MicUtils.createReceivedContentMic((HttpEntityEnclosingRequest) request, new Certificate[] { clientCert }, + clientKeyPair.getPrivate()); + assertEquals(computedContentMic.getEncodedMessageDigest(), receivedContentMic.getEncodedMessageDigest(), + "Received content MIC does not match computed"); + } + + @Test + public void multipartSignedXMLMessageTest() throws Exception { + final Map<String, Object> headers = new HashMap<>(); + // parameter type is String + headers.put("CamelAS2.requestUri", REQUEST_URI); + // parameter type is String + headers.put("CamelAS2.subject", SUBJECT); + // parameter type is String + headers.put("CamelAS2.from", FROM); + // parameter type is String + headers.put("CamelAS2.as2From", AS2_NAME); + // parameter type is String + headers.put("CamelAS2.as2To", AS2_NAME); + // parameter type is org.apache.camel.component.as2.api.AS2MessageStructure + headers.put("CamelAS2.as2MessageStructure", AS2MessageStructure.SIGNED); + // parameter type is org.apache.http.entity.ContentType + headers.put("CamelAS2.ediMessageContentType", + ContentType.create(AS2MediaType.APPLICATION_XML, StandardCharsets.US_ASCII)); // this line is the difference + // parameter type is String + headers.put("CamelAS2.ediMessageTransferEncoding", EDI_MESSAGE_CONTENT_TRANSFER_ENCODING); + // parameter type is org.apache.camel.component.as2.api.AS2SignatureAlgorithm + headers.put("CamelAS2.signingAlgorithm", AS2SignatureAlgorithm.SHA512WITHRSA); + // parameter type is java.security.cert.Certificate[] + headers.put("CamelAS2.signingCertificateChain", new Certificate[] { clientCert }); + // parameter type is java.security.PrivateKey + headers.put("CamelAS2.signingPrivateKey", clientKeyPair.getPrivate()); + // parameter type is String + headers.put("CamelAS2.dispositionNotificationTo", "mr...@example.com"); + // parameter type is String[] + headers.put("CamelAS2.signedReceiptMicAlgorithms", SIGNED_RECEIPT_MIC_ALGORITHMS); + // parameter type is String + headers.put("CamelAS2.attachedFileName", ""); + + final Triple<HttpEntity, HttpRequest, HttpResponse> result = executeRequest(headers); + HttpEntity responseEntity = result.getLeft(); + HttpRequest request = result.getMiddle(); + HttpResponse response = result.getRight(); + + assertNotNull(result, "send result"); + LOG.debug("send: " + result); + assertNotNull(request, "Request"); + assertTrue(request instanceof HttpEntityEnclosingRequest, "Request does not contain body"); + HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); + assertNotNull(entity, "Request body"); + assertTrue(entity instanceof MultipartSignedEntity, "Request body does not contain EDI entity"); + + MimeEntity signedEntity = ((MultipartSignedEntity) entity).getSignedDataEntity(); + assertTrue(signedEntity instanceof ApplicationEntity, "Signed entity wrong type"); + ApplicationEntity ediMessageEntity = (ApplicationEntity) signedEntity; String ediMessage = ediMessageEntity.getEdiMessage(); assertEquals(EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""), "EDI message is different"); @@ -568,8 +678,8 @@ public class AS2ClientManagerIT extends AbstractAS2ITSupport { MimeEntity compressedEntity = ((ApplicationPkcs7MimeCompressedDataEntity) entity).getCompressedEntity(new ZlibExpanderProvider()); - assertTrue(compressedEntity instanceof ApplicationEDIEntity, "Signed entity wrong type"); - ApplicationEDIEntity ediMessageEntity = (ApplicationEDIEntity) compressedEntity; + assertTrue(compressedEntity instanceof ApplicationEntity, "Signed entity wrong type"); + ApplicationEntity ediMessageEntity = (ApplicationEntity) compressedEntity; String ediMessage = ediMessageEntity.getEdiMessage(); assertEquals(EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""), "EDI message is different"); @@ -643,7 +753,7 @@ public class AS2ClientManagerIT extends AbstractAS2ITSupport { new Certificate[] { clientCert }, clientKeyPair.getPrivate()); // Create plain edi request message to acknowledge - ApplicationEDIEntity ediEntity = EntityUtils.createEDIEntity(EDI_MESSAGE, + ApplicationEntity ediEntity = EntityUtils.createEDIEntity(EDI_MESSAGE, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, StandardCharsets.US_ASCII), null, false, ATTACHED_FILE_NAME); HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", REQUEST_URI); diff --git a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java index 2261a0f96c4..22485cd5c24 100644 --- a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java +++ b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java @@ -47,6 +47,7 @@ import org.apache.camel.component.as2.api.AS2SignedDataGenerator; import org.apache.camel.component.as2.api.entity.ApplicationEDIFACTEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7SignatureEntity; +import org.apache.camel.component.as2.api.entity.ApplicationXMLEntity; import org.apache.camel.component.as2.api.entity.MimeEntity; import org.apache.camel.component.as2.api.entity.MultipartSignedEntity; import org.apache.camel.component.as2.api.util.SigningUtils; @@ -308,6 +309,88 @@ public class AS2ServerManagerIT extends AbstractAS2ITSupport { "Unexpected content for enveloped mime part"); } + @Test + public void receiveMultipartSignedXMLMessageTest() throws Exception { + + AS2ClientConnection clientConnection + = new AS2ClientConnection( + AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, TARGET_PORT, HTTP_SOCKET_TIMEOUT, + HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, HTTP_CONNECTION_POOL_TTL, clientSslContext, + null); + AS2ClientManager clientManager = new AS2ClientManager(clientConnection); + + clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.SIGNED, + ContentType.create(AS2MediaType.APPLICATION_XML, StandardCharsets.US_ASCII), null, // this line is the difference + AS2SignatureAlgorithm.SHA256WITHRSA, + certList.toArray(new Certificate[0]), signingKP.getPrivate(), null, DISPOSITION_NOTIFICATION_TO, + SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null); + + MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs"); + mockEndpoint.expectedMinimumMessageCount(1); + mockEndpoint.setResultWaitTime(TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS)); + mockEndpoint.assertIsSatisfied(); + + final List<Exchange> exchanges = mockEndpoint.getExchanges(); + assertNotNull(exchanges, "listen result"); + assertFalse(exchanges.isEmpty(), "listen result"); + LOG.debug("poll result: " + exchanges); + + Exchange exchange = exchanges.get(0); + Message message = exchange.getIn(); + assertNotNull(message, "exchange message"); + HttpCoreContext coreContext = exchange.getProperty(AS2Constants.AS2_INTERCHANGE, HttpCoreContext.class); + assertNotNull(coreContext, "context"); + HttpRequest request = coreContext.getRequest(); + assertNotNull(request, "request"); + assertEquals(METHOD, request.getRequestLine().getMethod(), "Unexpected method value"); + assertEquals(REQUEST_URI, request.getRequestLine().getUri(), "Unexpected request URI value"); + assertEquals(HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion(), "Unexpected HTTP version value"); + + assertEquals(SUBJECT, request.getFirstHeader(AS2Header.SUBJECT).getValue(), "Unexpected subject value"); + assertEquals(FROM, request.getFirstHeader(AS2Header.FROM).getValue(), "Unexpected from value"); + assertEquals(AS2_VERSION, request.getFirstHeader(AS2Header.AS2_VERSION).getValue(), "Unexpected AS2 version value"); + assertEquals(AS2_NAME, request.getFirstHeader(AS2Header.AS2_FROM).getValue(), "Unexpected AS2 from value"); + assertEquals(AS2_NAME, request.getFirstHeader(AS2Header.AS2_TO).getValue(), "Unexpected AS2 to value"); + assertTrue(request.getFirstHeader(AS2Header.MESSAGE_ID).getValue().endsWith(CLIENT_FQDN + ">"), + "Unexpected message id value"); + assertEquals(TARGET_HOST + ":" + TARGET_PORT, request.getFirstHeader(AS2Header.TARGET_HOST).getValue(), + "Unexpected target host value"); + assertEquals(USER_AGENT, request.getFirstHeader(AS2Header.USER_AGENT).getValue(), "Unexpected user agent value"); + assertNotNull(request.getFirstHeader(AS2Header.DATE), "Date value missing"); + assertNotNull(request.getFirstHeader(AS2Header.CONTENT_LENGTH), "Content length value missing"); + assertTrue(request.getFirstHeader(AS2Header.CONTENT_TYPE).getValue().startsWith(AS2MediaType.MULTIPART_SIGNED), + "Unexpected content type for message"); + + assertTrue(request instanceof BasicHttpEntityEnclosingRequest, "Request does not contain entity"); + HttpEntity entity = ((BasicHttpEntityEnclosingRequest) request).getEntity(); + assertNotNull(entity, "Request does not contain entity"); + assertTrue(entity instanceof MultipartSignedEntity, "Unexpected request entity type"); + MultipartSignedEntity signedEntity = (MultipartSignedEntity) entity; + assertTrue(signedEntity.isMainBody(), "Entity not set as main body of request"); + assertEquals(2, signedEntity.getPartCount(), "Request contains invalid number of mime parts"); + + // Validated first mime part. + assertTrue(signedEntity.getPart(0) instanceof ApplicationXMLEntity, "First mime part incorrect type "); + ApplicationXMLEntity xmlEntity = (ApplicationXMLEntity) signedEntity.getPart(0); + assertTrue(xmlEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_XML), + "Unexpected content type for first mime part"); + assertFalse(xmlEntity.isMainBody(), "First mime type set as main body of request"); + + // Validate second mime part. + assertTrue(signedEntity.getPart(1) instanceof ApplicationPkcs7SignatureEntity, "Second mime part incorrect type "); + ApplicationPkcs7SignatureEntity signatureEntity = (ApplicationPkcs7SignatureEntity) signedEntity.getPart(1); + assertTrue(signatureEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_PKCS7_SIGNATURE), + "Unexpected content type for second mime part"); + assertFalse(signatureEntity.isMainBody(), "First mime type set as main body of request"); + + // Validate Signature + assertTrue(SigningUtils.isValid(signedEntity, new Certificate[] { signingCert }), "Signature is invalid"); + + String rcvdMessage = message.getBody(String.class); + assertEquals(EDI_MESSAGE.replaceAll("[\n\r]", ""), rcvdMessage.replaceAll("[\n\r]", ""), + "Unexpected content for enveloped mime part"); + } + @Test public void receiveMultipartInvalidSignedMessageTest() throws Exception {