Reputation: 2388
I'm trying to walk through the Camel Report Incident tutorial and am stuck at the end of part 5. When I try to run the unit test it fails with the message The given SOAPAction http://reportincident.example.camel.apache.org/ReportIncident does not match an operation.
I saw a similar question where the problem was that the declared soapAction attribute on the WSDL file had a different value from the actual SOAP request. This does not seem to be my case. Any ideas about what is going wrong? Thanks in advance.
reportIncident.wsdl
<?xml version="1.0" encoding="ISO-8859-1"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://reportincident.example.camel.apache.org"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://reportincident.example.camel.apache.org">
<!-- Type definitions for input- and output parameters for webservice -->
<wsdl:types>
<xs:schema targetNamespace="http://reportincident.example.camel.apache.org">
<xs:element name="inputReportIncident">
<xs:complexType name="inputReportIncident">
<xs:sequence>
<xs:element type="xs:string" name="incidentId" />
<xs:element type="xs:string" name="incidentDate" />
<xs:element type="xs:string" name="givenName" />
<xs:element type="xs:string" name="familyName" />
<xs:element type="xs:string" name="summary" />
<xs:element type="xs:string" name="details" />
<xs:element type="xs:string" name="email" />
<xs:element type="xs:string" name="phone" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="outputReportIncident">
<xs:complexType name="outputReportIncident">
<xs:sequence>
<xs:element type="xs:string" name="code" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<!-- Message definitions for input and output -->
<wsdl:message name="inputReportIncident">
<wsdl:part name="parameters" element="tns:inputReportIncident" />
</wsdl:message>
<wsdl:message name="outputReportIncident">
<wsdl:part name="parameters" element="tns:outputReportIncident" />
</wsdl:message>
<!-- Port (interface) definitions -->
<wsdl:portType name="ReportIncidentEndpoint">
<wsdl:operation name="ReportIncident">
<wsdl:input message="tns:inputReportIncident" />
<wsdl:output message="tns:outputReportIncident" />
</wsdl:operation>
</wsdl:portType>
<!-- Port bindings to transports and encoding - HTTP, document literal
encoding is used -->
<wsdl:binding name="ReportIncidentBinding" type="tns:ReportIncidentEndpoint">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="ReportIncident">
<soap:operation soapAction="http://reportincident.example.camel.apache.org/ReportIncident" style="document" />
<wsdl:input>
<soap:body parts="parameters" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body parts="parameters" use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- Service definition -->
<wsdl:service name="ReportIncidentService">
<wsdl:port name="ReportIncidentPort" binding="tns:ReportIncidentBinding">
<soap:address location="http://reportincident.example.camel.apache.org" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
route definition (inside a RouteBuilder subclass)
OutputReportIncident ok = new OutputReportIncident();
ok.setCode("0");
// endpoint to our CXF webservice
String cxfEndpoint = "cxf://http://localhost:8080/part-five/webservices/incident"
+ "?serviceClass=org.apache.camel.example.reportincident.ReportIncidentEndpoint"
+ "&wsdlURL=reportIncident.wsdl";
// first part from the webservice -> file backup
from(cxfEndpoint)
// we need to convert the CXF payload to InputReportIncident that FilenameGenerator and velocity expects
.convertBodyTo(InputReportIncident.class)
// then set the file name using the FilenameGenerator bean
.setHeader("CamelFileName", BeanLanguage.bean(FilenameGenerator.class, "generateFilename"))
// transform the message using velocity to generate the mail message
.to("velocity:mailBody.vm")
// and store the file
.to("file://target/subfolder")
// return OK as response
// usando transformação!
.transform(constant(ok));
pom.xml (wsdl2java is used to generate Java files from WSDL)
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.13.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/reportIncident.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
test code
package org.apache.camel.example.reportincident;
import static org.junit.Assert.*;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;
import org.jvnet.mock_javamail.Mailbox;
public class ReportIncidentRoutesTest {
// should be the same address as we have in our route
private static String ADDRESS = "http://localhost:8080/part-five/webservices/incident";
private CamelContext context;
@Test
public void testRendportIncident() throws Exception {
// start camel
startCamel();
// assert mailbox is empty before starting
Mailbox inbox = Mailbox.get("[email protected]");
assertEquals("Should not have mails", 0, inbox.size());
// create input parameter
InputReportIncident input = new InputReportIncident();
input.setIncidentId("123");
input.setIncidentDate("2008-08-18");
input.setGivenName("Claus");
input.setFamilyName("Ibsen");
input.setSummary("Bla");
input.setDetails("Bla bla");
input.setEmail("[email protected]");
input.setPhone("0045 2962 7576");
// create the webservice client and send the request
ReportIncidentEndpoint client = createCXFClient();
OutputReportIncident out = client.reportIncident(input);
// assert we got a OK back
assertEquals("0", out.getCode());
// let some time pass to allow Camel to pickup the file and send it as an email
Thread.sleep(3000);
// assert mail box
assertEquals("Should have got 1 mail", 1, inbox.size());
// stop camel
context.stop();
}
private void startCamel() throws Exception {
context = new DefaultCamelContext();
context.disableJMX();
context.addRoutes(new ReportIncidentRoutes());
context.start();
}
private ReportIncidentEndpoint createCXFClient() {
// we use CXF to create a client for us as its easier than JAXWS and works
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ReportIncidentEndpoint.class);
factory.setAddress(ADDRESS);
return (ReportIncidentEndpoint) factory.create();
}
}
Upvotes: 0
Views: 4549
Reputation: 3291
I think you just need to pass the WSDL url to the JaxWsProxyFactoryBean and it can take care of the soap action for you.
Please change the ReportIncidentRoutesTest.createCXFClient() like this
private ReportIncidentEndpoint createCXFClient() {
// we use CXF to create a client for us as its easier than JAXWS and works
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ReportIncidentEndpoint.class);
factory.setWsdlURL("reportIncident.wsdl");
factory.setAddress(ADDRESS);
return (ReportIncidentEndpoint) factory.create();
}
Upvotes: 1