You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2022/10/31 19:00:38 UTC
[camel-quarkus] 07/19: [closes #4203] Add tests for CXF SOAP MTOM
This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch 2.13.x
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit d7ce39e28867f1f100348fd436a9f2d098eae04f
Author: Lukas Lowinger <ll...@redhat.com>
AuthorDate: Thu Oct 20 13:31:42 2022 +0200
[closes #4203] Add tests for CXF SOAP MTOM
---
.../cxf/soap/deployment/CxfSoapProcessor.java | 20 ++-
.../cxf-soap/cxf-soap-mtom/README.adoc | 4 +
.../cxf-soap/cxf-soap-mtom/pom.xml | 150 +++++++++++++++++++++
.../cxf/soap/mtom/it/CxfSoapMtomResource.java | 88 ++++++++++++
.../cxf/soap/mtom/it/CxfSoapMtomRoutes.java | 141 +++++++++++++++++++
.../component/cxf/soap/mtom/it/IImageService.java | 33 +++++
.../component/cxf/soap/mtom/it/ImageService.java | 63 +++++++++
.../cxf/soap/mtom/it/MtomAttachmentChecker.java | 96 +++++++++++++
.../src/main/resources/application.properties | 19 +++
.../component/cxf/soap/mtom/it/CxfSoapMtomIT.java | 23 ++++
.../cxf/soap/mtom/it/CxfSoapMtomTest.java | 83 ++++++++++++
.../src/test/resources/linux-image.png | Bin 0 -> 38982 bytes
integration-test-groups/cxf-soap/pom.xml | 1 +
integration-tests/cxf-soap-grouped/pom.xml | 16 ++-
14 files changed, 732 insertions(+), 5 deletions(-)
diff --git a/extensions/cxf-soap/deployment/src/main/java/org/apache/camel/quarkus/component/cxf/soap/deployment/CxfSoapProcessor.java b/extensions/cxf-soap/deployment/src/main/java/org/apache/camel/quarkus/component/cxf/soap/deployment/CxfSoapProcessor.java
index 17f76a9365..0e9985491f 100644
--- a/extensions/cxf-soap/deployment/src/main/java/org/apache/camel/quarkus/component/cxf/soap/deployment/CxfSoapProcessor.java
+++ b/extensions/cxf-soap/deployment/src/main/java/org/apache/camel/quarkus/component/cxf/soap/deployment/CxfSoapProcessor.java
@@ -25,6 +25,8 @@ import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
@@ -43,7 +45,10 @@ class CxfSoapProcessor {
}
@BuildStep
- void registerForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass, CombinedIndexBuildItem combinedIndex) {
+ void registerForReflection(
+ CombinedIndexBuildItem combinedIndex,
+ BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
+ BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods) {
IndexView index = combinedIndex.getIndex();
@@ -55,6 +60,19 @@ class CxfSoapProcessor {
.map(className -> new ReflectiveClassBuildItem(false, false, className))
.forEach(reflectiveClass::produce);
+ reflectiveMethods.produce(new ReflectiveMethodBuildItem("org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory",
+ "getServiceFactory", new String[0]));
+
+ }
+
+ @BuildStep
+ void registerForReflection(
+ BuildProducer<RuntimeInitializedClassBuildItem> runtimeInitializedClasses) {
+
+ // TODO: Move to quarkus-cxf
+ runtimeInitializedClasses
+ .produce(new RuntimeInitializedClassBuildItem("com.sun.xml.messaging.saaj.soap.StringDataContentHandler"));
+
}
@BuildStep
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/README.adoc b/integration-test-groups/cxf-soap/cxf-soap-mtom/README.adoc
new file mode 100644
index 0000000000..dac25bdb6f
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/README.adoc
@@ -0,0 +1,4 @@
+= Camel Quarkus CXF SOAP MTOM tests
+
+Tests are not using any external SOAP services (eg. via testcontainers). They purely test if Camel Quarkus is able to send and consume messages with attachments with both MTOM enabled/disabled.
+
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/pom.xml b/integration-test-groups/cxf-soap/cxf-soap-mtom/pom.xml
new file mode 100644
index 0000000000..ef3aea6031
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/pom.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-build-parent-it</artifactId>
+ <version>2.13.1-SNAPSHOT</version>
+ <relativePath>../../../poms/build-parent-it/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-quarkus-integration-test-cxf-soap-mtom</artifactId>
+ <name>Camel Quarkus :: Integration Tests :: Cxf Soap Mtom</name>
+ <description>Integration tests for Camel Quarkus CXF extension Mtom</description>
+
+ <dependencies>
+ <dependency><!-- for java.awt.Image -->
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-awt</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-cxf-soap</artifactId>
+ </dependency>
+
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit5</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.rest-assured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>native</id>
+ <activation>
+ <property>
+ <name>native</name>
+ </property>
+ </activation>
+ <properties>
+ <quarkus.package.type>native</quarkus.package.type>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>virtualDependencies</id>
+ <activation>
+ <property>
+ <name>!noVirtualDependencies</name>
+ </property>
+ </activation>
+ <dependencies>
+ <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-cxf-soap-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomResource.java b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomResource.java
new file mode 100644
index 0000000000..4a4b08ed08
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomResource.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.mtom.it;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.net.URI;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.imageio.ImageIO;
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.ProducerTemplate;
+
+import static org.apache.camel.component.cxf.common.message.CxfConstants.OPERATION_NAME;
+
+@Path("/cxf-soap/mtom")
+@ApplicationScoped
+public class CxfSoapMtomResource {
+
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ @Path("/upload")
+ @POST
+ @Produces(MediaType.TEXT_PLAIN)
+ public Response upload(@QueryParam("imageName") String imageName, @QueryParam("mtomEnabled") boolean mtomEnabled,
+ byte[] image) throws Exception {
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(image)) {
+ final String response = producerTemplate.requestBodyAndHeader(
+ "direct:" + mtomEndpoint(mtomEnabled),
+ new Object[] { ImageIO.read(bais), imageName },
+ OPERATION_NAME, "uploadImage", String.class);
+ return Response
+ .created(new URI("https://camel.apache.org/"))
+ .entity(response)
+ .build();
+ }
+ }
+
+ @Path("/download")
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ public Response download(@QueryParam("imageName") String imageName, @QueryParam("mtomEnabled") boolean mtomEnabled)
+ throws Exception {
+ final BufferedImage response = (BufferedImage) producerTemplate.requestBodyAndHeader(
+ "direct:" + mtomEndpoint(mtomEnabled),
+ imageName,
+ OPERATION_NAME,
+ "downloadImage", Image.class);
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ ImageIO.write(response, "png", baos);
+ byte[] bytes = baos.toByteArray();
+ return Response
+ .created(new URI("https://camel.apache.org/"))
+ .entity(bytes)
+ .build();
+ }
+ }
+
+ private String mtomEndpoint(boolean mtomEnabled) {
+ return mtomEnabled ? "mtomEnabledInvoker" : "mtomDisabledInvoker";
+ }
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomRoutes.java b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomRoutes.java
new file mode 100644
index 0000000000..a7f454a035
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomRoutes.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.mtom.it;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.xml.ws.handler.Handler;
+
+import io.quarkus.runtime.LaunchMode;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
+import org.apache.cxf.ext.logging.LoggingFeature;
+import org.apache.cxf.message.MessageContentsList;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+
+@ApplicationScoped
+public class CxfSoapMtomRoutes extends RouteBuilder {
+
+ @Inject
+ @Named("loggingMtomFeatureClient")
+ LoggingFeature loggingFeature;
+
+ @Override
+ public void configure() {
+
+ from("direct:mtomEnabledInvoker")
+ .to("cxf:bean:soapMtomEnabledClientEndpoint?dataFormat=POJO");
+
+ from("direct:mtomDisabledInvoker")
+ .to("cxf:bean:soapMtomDisabledClientEndpoint?dataFormat=POJO");
+
+ from("cxf:bean:soapMtomEnabledServerEndpoint?dataFormat=POJO")
+ .to("direct:processImage");
+
+ from("cxf:bean:soapMtomDisabledServerEndpoint?dataFormat=POJO")
+ .to("direct:processImage");
+
+ from("direct:processImage")
+ .process("imageServiceProcessor")
+ .recipientList((simple("bean:imageService?method=${header.operationName}")));
+
+ }
+
+ @ApplicationScoped
+ @Named("imageServiceProcessor")
+ static class ImageServiceProcessor implements Processor {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ String operationName = (String) exchange.getIn().getHeaders().get("operationName");
+ MessageContentsList list = (MessageContentsList) exchange.getIn().getBody();
+ if ("uploadImage".equals(operationName)) {
+ exchange.getIn().getHeaders().put("image", list.get(0));
+ exchange.getIn().getHeaders().put("imageName", list.get(1));
+ exchange.getIn().getHeaders()
+ .put("operationName", "uploadImage(${header.image},${header.imageName})");
+ } else if ("downloadImage".equals(operationName)) {
+ exchange.getIn().setBody(list.get(0));
+ }
+ }
+
+ }
+
+ @Produces
+ @ApplicationScoped
+ @Named("loggingMtomFeatureClient")
+ public LoggingFeature loggingFeature() {
+ final LoggingFeature result = new LoggingFeature();
+ result.setPrettyLogging(true);
+ return result;
+ }
+
+ @Produces
+ @ApplicationScoped
+ @Named
+ CxfEndpoint soapMtomEnabledClientEndpoint() {
+ return commonCxfEndpoint(true, getServerUrl() + "/soapservice/mtom-enabled-image-service");
+ }
+
+ @Produces
+ @ApplicationScoped
+ @Named
+ CxfEndpoint soapMtomDisabledClientEndpoint() {
+ return commonCxfEndpoint(false, getServerUrl() + "/soapservice/mtom-disabled-image-service");
+ }
+
+ @Produces
+ @ApplicationScoped
+ @Named
+ CxfEndpoint soapMtomEnabledServerEndpoint() {
+ return commonCxfEndpoint(true, "/mtom-enabled-image-service");
+ }
+
+ @Produces
+ @ApplicationScoped
+ @Named
+ CxfEndpoint soapMtomDisabledServerEndpoint() {
+ return commonCxfEndpoint(false, "/mtom-disabled-image-service");
+ }
+
+ CxfEndpoint commonCxfEndpoint(boolean mtomEnabled, String address) {
+ final CxfEndpoint result = new CxfEndpoint();
+ result.getFeatures().add(loggingFeature);
+ result.setServiceClass(IImageService.class);
+ result.setMtomEnabled(mtomEnabled);
+ result.setAddress(address);
+ List<Handler> handlers = new ArrayList<>();
+ handlers.add(new MtomAttachmentChecker(mtomEnabled));
+ result.setHandlers(handlers);
+ return result;
+ }
+
+ private static String getServerUrl() {
+ Config config = ConfigProvider.getConfig();
+ final int port = LaunchMode.current().equals(LaunchMode.TEST) ? config.getValue("quarkus.http.test-port", Integer.class)
+ : config.getValue("quarkus.http.port", Integer.class);
+ return String.format("http://localhost:%d", port);
+ }
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/IImageService.java b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/IImageService.java
new file mode 100644
index 0000000000..3340c2cfbf
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/IImageService.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.mtom.it;
+
+import java.awt.*;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+
+@WebService
+public interface IImageService {
+
+ @WebMethod
+ Image downloadImage(String name);
+
+ @WebMethod
+ String uploadImage(Image image, String name);
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/ImageService.java b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/ImageService.java
new file mode 100644
index 0000000000..93ec42986d
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/ImageService.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.mtom.it;
+
+import java.awt.*;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Named;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@ApplicationScoped
+@Named("imageService")
+public class ImageService implements IImageService {
+
+ public static final String MSG_SUCCESS = "Upload Successful";
+ private static final Logger log = LoggerFactory.getLogger(ImageService.class);
+
+ private final Map<String, Image> imageRepository;
+
+ public ImageService() {
+ imageRepository = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ public Image downloadImage(String name) {
+ final Image image = imageRepository.get(name);
+ if (image == null) {
+ throw new IllegalStateException("Image with name " + name + " does not exist.");
+ }
+ return image;
+ }
+
+ @Override
+ public String uploadImage(Image image, String name) {
+
+ log.info("Upload image: " + image + " with name: " + name);
+
+ if (image != null && name != null && !"".equals(name)) {
+ imageRepository.put(name, image);
+ return MSG_SUCCESS;
+ }
+ throw new IllegalStateException("Illegal Data Format.");
+ }
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/MtomAttachmentChecker.java b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/MtomAttachmentChecker.java
new file mode 100644
index 0000000000..d8eefeafce
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/MtomAttachmentChecker.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.mtom.it;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPException;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPHandler;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Asserts whether the attachment is present where expected (inline or multipart body) throws an IllegalStateException
+ * to signal that something is wrong.
+ */
+public class MtomAttachmentChecker implements SOAPHandler<SOAPMessageContext> {
+ boolean mtomEnabled;
+
+ public MtomAttachmentChecker(boolean mtomEnabled) {
+ this.mtomEnabled = mtomEnabled;
+ }
+
+ static boolean walk(String localName, NodeList nodes) {
+ boolean found = false;
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (localName.equals(n.getLocalName())) {
+ found = true;
+ break;
+ } else if (!found) {
+ found = walk(localName, n.getChildNodes());
+ }
+ }
+
+ return found;
+ }
+
+ @Override
+ public boolean handleMessage(SOAPMessageContext msgContext) {
+ try {
+ SOAPEnvelope envelope = msgContext.getMessage().getSOAPPart().getEnvelope();
+ SOAPBody body = envelope.getBody();
+ boolean found = walk("Include", body.getChildNodes());
+ if (mtomEnabled) {
+ // skip those messages which don't have attachments
+ boolean skip = walk("uploadImageResponse", body.getChildNodes()) || walk("downloadImage", body.getChildNodes());
+ if (!skip && !found) {
+ throw new IllegalStateException("The SOAP message should contain an <xop:Include> element");
+ }
+ } else if (found) {
+ throw new IllegalStateException("The SOAP message shouldn't contain an <xop:Include> element");
+ }
+
+ } catch (SOAPException ex) {
+ throw new WebServiceException(ex);
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean handleFault(SOAPMessageContext context) {
+ return true;
+ }
+
+ @Override
+ public void close(MessageContext context) {
+ }
+
+ @Override
+ public Set<QName> getHeaders() {
+ return Collections.emptySet();
+ }
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/resources/application.properties b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/resources/application.properties
new file mode 100644
index 0000000000..574727024a
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/main/resources/application.properties
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+quarkus.cxf.path=/soapservice
+quarkus.native.resources.includes = wsdl/*.wsdl
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomIT.java b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomIT.java
new file mode 100644
index 0000000000..6da4ad90da
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomIT.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.mtom.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class CxfSoapMtomIT extends CxfSoapMtomTest {
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomTest.java b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomTest.java
new file mode 100644
index 0000000000..9fdc27c1f8
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/java/org/apache/camel/quarkus/component/cxf/soap/mtom/it/CxfSoapMtomTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.mtom.it;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import io.quarkus.test.junit.DisabledOnIntegrationTest;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+@QuarkusTest
+class CxfSoapMtomTest {
+
+ @DisabledOnIntegrationTest("https://github.com/apache/camel-quarkus/issues/4208")
+ @ParameterizedTest
+ @ValueSource(booleans = { true, false })
+ public void uploadDownloadMtom(boolean mtomEnabled) throws IOException {
+ byte[] imageBytes = CxfSoapMtomTest.class.getClassLoader().getResourceAsStream("linux-image.png").readAllBytes();
+ String imageName = "linux-image-name";
+ RestAssured.given()
+ .contentType(ContentType.BINARY)
+ .queryParam("imageName", imageName)
+ .queryParam("mtomEnabled", mtomEnabled)
+ .body(imageBytes)
+ .post("/cxf-soap/mtom/upload")
+ .then()
+ .statusCode(201)
+ .body(CoreMatchers.equalTo(ImageService.MSG_SUCCESS));
+ byte[] downloadedImageBytes = RestAssured.given()
+ .contentType(ContentType.TEXT)
+ .queryParam("imageName", imageName)
+ .queryParam("mtomEnabled", mtomEnabled)
+ .post("/cxf-soap/mtom/download")
+ .then()
+ .statusCode(201)
+ .extract().asByteArray();
+
+ try (ByteArrayInputStream imageBais = new ByteArrayInputStream(
+ imageBytes); ByteArrayInputStream downloadedImageBais = new ByteArrayInputStream(downloadedImageBytes)) {
+ Assertions.assertTrue(bufferedImagesEqual(ImageIO.read(imageBais),
+ ImageIO.read(downloadedImageBais)), "Uploaded image should match downloaded");
+ }
+ }
+
+ // copied from https://stackoverflow.com/a/15305092
+ boolean bufferedImagesEqual(BufferedImage img1, BufferedImage img2) {
+ if (img1.getWidth() == img2.getWidth() && img1.getHeight() == img2.getHeight()) {
+ for (int x = 0; x < img1.getWidth(); x++) {
+ for (int y = 0; y < img1.getHeight(); y++) {
+ if (img1.getRGB(x, y) != img2.getRGB(x, y))
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/resources/linux-image.png b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/resources/linux-image.png
new file mode 100644
index 0000000000..17d7bfef0d
Binary files /dev/null and b/integration-test-groups/cxf-soap/cxf-soap-mtom/src/test/resources/linux-image.png differ
diff --git a/integration-test-groups/cxf-soap/pom.xml b/integration-test-groups/cxf-soap/pom.xml
index d5f1c22d43..bfb960c740 100644
--- a/integration-test-groups/cxf-soap/pom.xml
+++ b/integration-test-groups/cxf-soap/pom.xml
@@ -38,6 +38,7 @@
<modules>
<!-- extensions a..z; do not remove this comment, it is important when sorting via mvn process-resources -Pformat -->
<module>cxf-soap-client</module>
+ <module>cxf-soap-mtom</module>
<module>cxf-soap-server</module>
<module>cxf-soap-ws-security-client</module>
</modules>
diff --git a/integration-tests/cxf-soap-grouped/pom.xml b/integration-tests/cxf-soap-grouped/pom.xml
index ca70eea4f2..6b809b1b6e 100644
--- a/integration-tests/cxf-soap-grouped/pom.xml
+++ b/integration-tests/cxf-soap-grouped/pom.xml
@@ -32,6 +32,14 @@
<!-- Regenerate the dependencies via `mvn process-resources -Pformat -N` from the source tree root directory -->
<dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-cxf-soap</artifactId>
@@ -48,13 +56,13 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
- <dependency>
+ <dependency><!-- for java.awt.Image -->
<groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy</artifactId>
+ <artifactId>quarkus-awt</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-direct</artifactId>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy</artifactId>
</dependency>
<!-- test dependencies -->