You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/10/17 13:56:51 UTC
[camel] branch main updated: CAMEL-18613: camel-cxf - Add option on endpoint to configure schema validation (#8556)
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 f7da21d841a CAMEL-18613: camel-cxf - Add option on endpoint to configure schema validation (#8556)
f7da21d841a is described below
commit f7da21d841a965ed6c83849479bdc5f7bf9aaf3e
Author: Luigi De Masi <55...@users.noreply.github.com>
AuthorDate: Mon Oct 17 15:56:41 2022 +0200
CAMEL-18613: camel-cxf - Add option on endpoint to configure schema validation (#8556)
---
.../camel/component/cxf/jaxws/CxfEndpoint.java | 26 +++
.../cxf/jaxws/CxfSchemaValidationTest.java | 183 +++++++++++++++++++++
2 files changed, 209 insertions(+)
diff --git a/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java b/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java
index a74290c0d15..b7bcadfa0c8 100644
--- a/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java
+++ b/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java
@@ -216,6 +216,10 @@ public class CxfEndpoint extends DefaultEndpoint implements AsyncEndpoint, Heade
description = "Sets whether synchronous processing should be strictly used")
private boolean synchronous;
+ @UriParam(defaultValue = "false", label = "advanced",
+ description = "Enable schema validation for request and response. Disabled by default for performance reason")
+ private Boolean schemaValidationEnabled;
+
public CxfEndpoint() {
setExchangePattern(ExchangePattern.InOut);
}
@@ -374,6 +378,13 @@ public class CxfEndpoint extends DefaultEndpoint implements AsyncEndpoint, Heade
sfb.getProperties().put(FaultListener.class.getName(), new NullFaultListener());
}
+ if (this.getSchemaValidationEnabled() != null) {
+ if (sfb.getProperties() == null) {
+ sfb.setProperties(new HashMap<>());
+ }
+ sfb.getProperties().put(Message.SCHEMA_VALIDATION_ENABLED, schemaValidationEnabled);
+ }
+
sfb.setBus(getBus());
sfb.setStart(false);
getNullSafeCxfConfigurer().configure(sfb);
@@ -570,6 +581,13 @@ public class CxfEndpoint extends DefaultEndpoint implements AsyncEndpoint, Heade
factoryBean.getProperties().put(FaultListener.class.getName(), new NullFaultListener());
}
+ if (this.getSchemaValidationEnabled() != null) {
+ if (factoryBean.getProperties() == null) {
+ factoryBean.setProperties(new HashMap<>());
+ }
+ factoryBean.getProperties().put(Message.SCHEMA_VALIDATION_ENABLED, schemaValidationEnabled);
+ }
+
factoryBean.setBus(getBus());
getNullSafeCxfConfigurer().configure(factoryBean);
@@ -1490,4 +1508,12 @@ public class CxfEndpoint extends DefaultEndpoint implements AsyncEndpoint, Heade
return null;
}
}
+
+ public Boolean getSchemaValidationEnabled() {
+ return schemaValidationEnabled;
+ }
+
+ public void setSchemaValidationEnabled(Boolean schemaValidationEnabled) {
+ this.schemaValidationEnabled = schemaValidationEnabled;
+ }
}
diff --git a/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfSchemaValidationTest.java b/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfSchemaValidationTest.java
new file mode 100644
index 00000000000..5a6650a2c96
--- /dev/null
+++ b/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfSchemaValidationTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.component.cxf.jaxws;
+
+import java.net.URL;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Holder;
+import javax.xml.ws.soap.SOAPFaultException;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cxf.common.CXFTestSupport;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.camel.wsdl_first.Person;
+import org.apache.camel.wsdl_first.PersonService;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.ext.logging.LoggingInInterceptor;
+import org.apache.cxf.ext.logging.LoggingOutInterceptor;
+import org.apache.cxf.frontend.ClientProxy;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class CxfSchemaValidationTest extends CamelTestSupport {
+
+ protected static final String PORT_NAME_PROP = "portName={http://camel.apache.org/wsdl-first}soap";
+ protected static final String SERVICE_NAME = "{http://camel.apache.org/wsdl-first}PersonService";
+ protected static final String SERVICE_NAME_PROP = "serviceName=" + SERVICE_NAME;
+ protected static final String WSDL_URL_PROP = "wsdlURL=classpath:person.wsdl";
+
+ protected final String serviceAddressValidationEnabled = "http://localhost:" + CXFTestSupport.getPort1()
+ + "/" + getClass().getSimpleName() + "/PersonService";
+
+ protected final String serviceAddressValidationDisabled = "http://localhost:" + CXFTestSupport.getPort2()
+ + "/" + getClass().getSimpleName() + "/PersonService";
+
+ protected final String cxfServerUriValidationEnabled = "cxf://" + serviceAddressValidationEnabled + "?"
+ + PORT_NAME_PROP + "&" + SERVICE_NAME_PROP + "&" + WSDL_URL_PROP
+ + "&dataFormat=payload&schemaValidationEnabled=true";
+ protected final String cxfServerUriValidationDisabled
+ = "cxf://" + serviceAddressValidationDisabled + "?" + PORT_NAME_PROP + "&"
+ + SERVICE_NAME_PROP + "&" + WSDL_URL_PROP + "&dataFormat=payload";
+
+ protected final String cxfProducerUriValidationEnabled
+ = "cxf://" + serviceAddressValidationDisabled + "?" + PORT_NAME_PROP + "&"
+ + SERVICE_NAME_PROP + "&" + WSDL_URL_PROP + "&dataFormat=payload&schemaValidationEnabled=true";
+
+ protected final String cxfProducerUriValidationDisabled
+ = "cxf://" + serviceAddressValidationDisabled + "?" + PORT_NAME_PROP + "&"
+ + SERVICE_NAME_PROP + "&" + WSDL_URL_PROP + "&dataFormat=payload";
+
+ protected final String clientUriValidationEnabled = "direct:validationEnabled";
+
+ protected final String clientUriValidationDisabled = "direct:validationDisabled";
+
+ protected final String notValidRequest = "<GetPerson xmlns='http://camel.apache.org/wsdl-first/types'>"
+ //Max Length: 30,
+ + "<personId>4yLKOBllJjx4SCXRMXoNiOFEzQfCNA8BSBsyPUaQ</personId>"
+ + "</GetPerson>";
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ public void configure() {
+ from(cxfServerUriValidationEnabled).to("direct:result");
+
+ from(cxfServerUriValidationDisabled).to("direct:result");
+
+ from(clientUriValidationEnabled).to(cxfProducerUriValidationEnabled);
+
+ from(clientUriValidationDisabled).to(cxfProducerUriValidationDisabled);
+
+ from("direct:result")
+ .process(exchange -> {
+ String xml = "<GetPersonResponse xmlns=\"http://camel.apache.org/wsdl-first/types\">"
+ + "<personId>123</personId><ssn>456</ssn><name>Donald Duck</name>"
+ + "</GetPersonResponse>";
+
+ exchange.getMessage().setBody(xml);
+ });
+ }
+ };
+ }
+
+ @Test
+ public void schemaValidationDisabledServerTest() throws Exception {
+ // invoke the service with a non-valid message
+ try {
+ invokeService(serviceAddressValidationDisabled, RandomStringUtils.random(40, true, true));
+ } catch (SOAPFaultException e) {
+ fail("Do not expect an exception here");
+ }
+ }
+
+ @Test
+ public void schemaValidationEnabledServerTest() throws Exception {
+ //first, invoke service with valid message. No exception should be thrown
+ invokeService(serviceAddressValidationEnabled, RandomStringUtils.random(10, true, true));
+
+ // then invoke the service with a non-valid message
+
+ /*
+ Generate a personId string that should cause a validation error:
+
+ <simpleType name="MyStringType">
+ <restriction base="string">
+ <maxLength value="30" />
+ </restriction>
+ </simpleType>
+ ......
+ <xsd:element name="personId" type="tns:MyStringType"/>
+
+ */
+ try {
+ invokeService(serviceAddressValidationEnabled, RandomStringUtils.random(40, true, true));
+ fail("expect a Validation exception here");
+ } catch (SOAPFaultException e) {
+ assertEquals("the length of the value is 40, but the required maximum is 30.", e.getMessage(), "");
+ }
+ }
+
+ @Test
+ public void schemaValidationEnabledClientTest() {
+ Exchange ex = template.send(clientUriValidationEnabled, exchange -> {
+ exchange.getMessage().setBody(notValidRequest);
+ });
+
+ assertNotNull(ex.getException());
+ assertTrue(ex.getException().getMessage().contains("cvc-maxLength-valid"));
+ }
+
+ @Test
+ public void schemaValidationDisabledClientTest() {
+ Exchange ex = template.send(clientUriValidationDisabled, exchange -> {
+ exchange.getMessage().setBody(notValidRequest);
+ });
+ assertNull(ex.getException());
+
+ }
+
+ private void invokeService(String address, String personIdParam) throws Exception {
+ URL wsdlURL = getClass().getClassLoader().getResource("person.wsdl");
+ PersonService ss = new PersonService(wsdlURL, QName.valueOf(SERVICE_NAME));
+
+ Person client = ss.getSoap();
+
+ Client c = ClientProxy.getClient(client);
+ c.getInInterceptors().add(new LoggingInInterceptor());
+ c.getOutInterceptors().add(new LoggingOutInterceptor());
+ ((BindingProvider) client).getRequestContext()
+ .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
+
+ Holder<String> personId = new Holder<>();
+
+ personId.value = personIdParam;
+ Holder<String> ssn = new Holder<>();
+ Holder<String> name = new Holder<>();
+ client.getPerson(personId, ssn, name);
+ }
+}