I'm upgrading from ColdFusion 9 to ColdFusion 2016 and my web services suddenly no longer work. I believe it's because Axis 2 was introduced in Cold Fusion 10 and with it rendered my existing web services non-functional.
Even if I set the Web Service version back to 1 in ColdFusion Administrator, it still doesn't work.
The way I call these web services is with the createObject function as such:
<cfscript>
objSoapHeader = XmlParse("<wsse:Security mustUnderstand=""true"" xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""><wsse:UsernameToken><wsse:Username>USERNAME</wsse:Username><wsse:Password>PASSWORD</wsse:Password></wsse:UsernameToken></wsse:Security>");
Application.UserWebService = CreateObject("webservice", PATH & "Requests/UserService.asmx?WSDL");
addSOAPRequestHeader(Application.UserWebService,"","",objSoapHeader,true);
// Get the .Net resources
Application.NetResources = Application.UserWebService.GetNetResources();
</cfscript>
The error I recieve is :
Cannot perform web service invocation GetNetResources.
The fault returned when invoking the web service operation
is:java.lang.RuntimeException: Error obtaining parser from data
source:LanguageHeader cannot be null!
It states that the LangaugeHeader cannot be null. The WSDL displays two messages associated to the GetNetResources operation:
<wsdl:portType name="UserServiceSoap">
<wsdl:operation name="GetNetResources">
<wsdl:input message="tns:GetNetResourcesSoapIn"/>
<wsdl:output message="tns:GetNetResourcesSoapOut"/>
</wsdl:operation>
</wsdl:portType >
However when looking at the list of messages I can see three messages associated to GetNetResources:
<wsdl:message name="GetNetResourcesSoapIn">
<wsdl:part name="parameters" element=tns:GetNetResources"/>
</wsdl:message>
<wsdl:message name="GetNetResourcesSoapOut">
<wsdl:part name="parameters" element=tns:GetNetResourcesResponse"/>
</wsdl:message>
<wsdl:message name="GetNetResourcesLanguageHeader">
<wsdl:part name="parameters" element=tns:LanguageHeader"/>
</wsdl:message>
If the operation is only specifying two messages, then where in the WSDL file is this third message being associated to the operation?
It seems that the LanguageHeader parameter is absolutely required and enfored in ColdFusion 2016, so why was it working in ColdFusion 9 (Axis 1)?
EDIT 1
To answer my first question above (striked out) I found the following code in the binding as opposed to the portType:
<wsdl:binding name="UserServiceSoap" type="tns:UserServiceSoap">
<wsdl:operation name="GetNetResources">
<soap:operation style="document" soapAction="http://tempuri.org/GetNetResources"/>
<wsdl:input>
<soap:body use="literal"/>
<soap:header message="tns:GetNetResourcesLanguageHeader" use="literal" part="LanguageHeader"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
However that still doesn't answer my second question.
EDIT 2
After playing around with the code a bit, I manged to resolve the RuntimeException by adding a variable to the web service call.
args = {TEST="<locale>en-CA</locale>"};
Application.NetResources = Application.UserWebService.GetNetResources(argumentCollection=args);
Which now results in the following error:
Web service parameter name languageHeader cannot be found in the
provided parameters {TEST}.
As TEST is not an actual parameter specified in the WSDL, I modified it to languageHeader, and recieve this new error:
Web service operation GetNetResources with parameters {LANGUAGEHEADER={<locale>en-CA</locale>}} cannot be found.
This indicates that languageHeader is indeed the correct parameter name, however it still cannot find the the web service operation, therefore I believe the 'type' of the parameter is different.
Perhaps I'm not suppose to be sending a string as the value, however looking back at my WSDL, it states that they type of the Locale is a string:
<wsdl:types>
<s:schema targetNamespace="http://tempuri.org/" elementFormDefault="qualified">
<s:element name="LanguageHeader" type="tns:LanguageHeader"/>
<s:complexType name="LanguageHeader">
<s:sequence>
<s:element name="Locale" type="s:string" maxOccurs="1" minOccurs="0"/>
</s:sequence>
<s:anyAttribute/>
</s:complexType>
</s:schema>
</wsdl:types>
From what I understand I'm suppose to be sending a complexType object as the parameter which contains a Locale as a string.
What kind of object would I be sending from CFML if that is the case?
When consuming a web service with a parameter of a complex data type, send a structure as the parameter.
// Create struct
stLanguageHeader = structNew();
stLanguageHeader.locale = "en-CA";
Application.NetResources = Application.UserWebService.GetNetResources(stLanguageHeader);
Related
I want to know how WSDL secure data on trafic. I searched but I can't find anything I need. This is a WSDL service sample and I want to understand their security mechanism.
<wsdl:definitions
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://services.test" xmlns:intf="http://services.test"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://services.test">
<!--
WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)
-->
....
<wsdl:types>....
<wsdl:message....
<wsdl:portType>
<wsdl:operation ....
<wsdl:binding name="InterfacesSoapBinding" type="impl:Interfaces">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="topup">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="topupRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://services.test" use="encoded"/>
</wsdl:input>
<wsdl:output name="topupResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://services.test" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
....
<wsdl:service name="InterfacesService">
<wsdl:port binding="impl:InterfacesSoapBinding" name="Interfaces">
<wsdlsoap:address location="...."/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
This
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://services.test" use="encoded"/>
is encode data trafic right ?
In your example there is no security declaration at all. The encodingStyle defines only how your SOAP message is encoded and serialized. And the declared encoding style http://schemas.xmlsoap.org/soap/encoding is the standard one. See SOAP encoding for more details.
If you want to learn something about securing a WSDL/SOAP web service please check the OASIS website e.g. WS-SecurityPolicy Examples or especially for message encryption SOAP Message security. In general there are several security approaches for WSDL/SOAP for different use cases.
WS-Policy declaration is the way to provide security for SOAP web services. You need to implement the wsp:PolicyReference in your WSDL file. A complete tutorial is here(https://concentricsky.com/blog/article/implementing-ws-security-cxf-wsdl-first-web-service).
There is a lot of information about Apache Camel + CXF-Endpoint and RPC/encoded legacy webservices.
But until now I did not find a solution for the problem.
I want to call an RPC/encoded webservice from Apache Camel over the CXF endpoint.
CXF does not support RPC/encoded Webservices.
So I tried two approaches to solve the problem.
Convert wsdl from RPC/encoded to RPC/literal and generate source files.
Call the webservice in RPC/literal style which is supported by CXF.
The following article suggests that this approach could be a solution for my problem: Best way to consume RPC/encoded webservice?
Send the complete SOAP-Message without mapping to objects (no JAXB).
Neither approach 1 nor approach 2 works.
In the following sections I will explain my approaches and the problems in more detail.
Prerequisites
Apache Tomcat 7
Apache Camel 2.14.1
Apache CXF 2.7.10
Webservice Endpoint is mocked with SOAP-UI 5.0.0 on http://localhost:9000/myfunctionalmock
First approach: Convert wsdl RPC/encoded to RPC/literal and generate sources
In the RCP/encoded wsdl I have changed following:
WSDL Bindings:
<wsdl:binding name="exampleSoapBinding" type="impl:MyFunctionalWebservices">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="isAlive">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="isAliveRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://my.example.com/myFunction" use="encoded"/>
</wsdl:input>
...
to
<wsdl:binding name="exampleSoapBinding" type="impl:MyFunctionalWebservices">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="isAlive">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="isAliveRequest">
<wsdlsoap:body namespace="http://my.example.com/myFunction" use="literal"/>
</wsdl:input>
…
Arrays of Objects:
<complexType name="ArrayOfMyElement">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="impl:MyElement[]"/>
</restriction>
</complexContent>
</complexType>
to
<complexType name="ArrayOfMyElement">
<xsd:sequence>
<xsd:element name="MyElement"
type="impl:MyElement"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</complexType>
Arrays of simple types:
<complexType name="ArrayOf_xsd_string">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
</restriction>
</complexContent>
</complexType>
to
<complexType name="ArrayOf_xsd_string">
<xsd:sequence>
<xsd:element name="item"
type="xsd:string"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</complexType>
Arrays of undefined Type (anyType):
<complexType name="ArrayOf_xsd_anyType">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:anyType[]"/>
</restriction>
</complexContent>
</complexType>
to
<complexType name="ArrayOf_xsd_anyType">
<xsd:sequence>
<xsd:element name="item"
type="xsd:anyType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</complexType>
After that I have generated source files with IntelliJ Webservice plugin (over CXF wsdl2java)
In Camel I have configured following Endpoint:
CxfEndpoint endpoint = new CxfEndpoint();
endpoint.setAddress("http://127.0.0.1:9000/myfunctionalmock");
endpoint.setWsdlURL("wsdl/myservice_literal.wsdl");
endpoint.setServiceClass("com.my.example.MyFunctionalWebservices");
endpoint.setEndpointNameString("{http://my.example.com/myFunction}rpcrouter");
endpoint.setServiceNameString("{http://my.example.com/myFunction}MyFunctionalWebservicesService");
endpoint.setDataFormat(DataFormat.POJO);
endpoint.setSynchronous(true);
endpoint.setCamelContext(camelContext);
endpoint.setEndpointUriIfNotSpecified(MY_ENDPOINT_URL);
camelContext.addEndpoint(MY_ENDPOINT_URL, endpoint);
Usage of CXF-Endpoint in Camel route:
I want to call following function of webservice:
public Result isAlive(java.lang.String identifier);
The timer in the camel route is only for triggering the webservice.
from("timer://myTimer?period=10000")
.log(LoggingLevel.INFO, "START Timer Webservice.")
.setBody().constant("1620000018")
.setHeader("operationName", constant("isAlive"))
.setHeader("operationNamespace", constant("http://my.example.com/myFunction"))
.to(MyCamelConfiguration.MY_ENDPOINT_URL);
Problems with this approach:
At runtime following message appears at deployment time:
2015-03-05 09:57:46,659; 2010; [localhost-startStop-1]; DEBUG; wsdl11.WSDLServiceBuilder; Operation {http://my.example.com/myFunction}isAlive cannot be unwrapped, input message must reference global element declaration with same localname as operation
Following exception occurs at runtime:
org.apache.cxf.binding.soap.SoapFault: No namespace on "HTML" element. You must send a SOAP request.
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.readVersion(ReadHeadersInterceptor.java:111)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:155)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:835)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1614)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1504)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1310)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:628)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
at org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:149)
at org.apache.camel.impl.SynchronousDelegateProducer.process(SynchronousDelegateProducer.java:62)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:120)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:166)
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:74)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Second approach: Send the SOAP-Message without mapping to Objects.
Endpoint definition in Camel:
CxfEndpoint endpoint = new CxfEndpoint();
endpoint.setAddress("http://127.0.0.1:9000/myfunctionalmock");
endpoint.setEndpointNameString("{http://my.example.com/myFunction}rpcrouter");
endpoint.setServiceNameString("{http://my.example.com/myFunction}MyFunctionalWebservicesService");
endpoint.setDataFormat(DataFormat.RAW);
endpoint.setWrappedStyle(false);
endpoint.setSynchronous(true);
endpoint.setCamelContext(camelContext);
endpoint.setEndpointUriIfNotSpecified(MY_TEMPLATE_ENDPOINT_URL);
camelContext.addEndpoint(MY_TEMPLATE_ENDPOINT_URL, endpoint);
Usage in route:
from("timer://myTimer?period=10000")
.log(LoggingLevel.INFO, "START Timer Webservice.")
.setBody().constant(
"<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:myns=\"http://my.example.com/myFunction\">\n" +
" <soapenv:Header/>\n" +
" <soapenv:Body>\n" +
" <myns:isAlive soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" +
" <identifier xsi:type=\"xsd:string\">1620000018</identifier>\n" +
" </myns:isAlive>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>"
)
.to(MyCamelConfiguration.MY_TEMPLATE_ENDPOINT_URL)
.log(LoggingLevel.INFO, "END Timer Webservice.")
.log(LoggingLevel.INFO, "Body after ws call = ${body}");
But the webservice on http://localhost:9000/myfunctionalmock is never called.
I found following log messages in logfile:
2015-03-05 10:56:35,522; 12843; [Camel (camel-1) thread #0 - timer://myTimer]; DEBUG; phase.PhaseInterceptorChain; Invoking handleMessage on interceptor org.apache.cxf.jaxb.attachment.JAXBAttachmentSchemaValidationHack#1d3694a
2015-03-05 10:56:35,523; 12844; [Camel (camel-1) thread #0 - timer://myTimer]; DEBUG; phase.PhaseInterceptorChain; Invoking handleMessage on interceptor org.apache.cxf.ws.policy.PolicyVerificationInInterceptor#1a0ff10
2015-03-05 10:56:35,523; 12844; [Camel (camel-1) thread #0 - timer://myTimer]; DEBUG; policy.PolicyVerificationInInterceptor; Verified policies for inbound message.
2015-03-05 10:56:35,523; 12844; [Camel (camel-1) thread #0 - timer://myTimer]; INFO ; helpers.MarkerIgnoringBase; END Timer Webservice.
2015-03-05 10:56:35,523; 12844; [Camel (camel-1) thread #0 - timer://myTimer]; INFO ; helpers.MarkerIgnoringBase; Body after ws call = <HTML>
<HEAD><TITLE>Redirection</TITLE></HEAD>
<BODY><H1>Redirect</H1></BODY>
Both approaches do not work.Is there a possibility to call RPC/encoded webservice over CXF in Camel?
Thanks in advance.
Regards,
Max
As you say Apache CXF does not support the old RPC style. You would need to use an older WS library such as Apache Axis 1.x. There is no Camel component for that, but as its all just java code, you can write some java code that uses Axis 1.x, and then let Camel call the java code, using its bean component / processor.
http://camel.apache.org/bean
Another alternative is that as SOAP is over HTTP you can just use Camel's HTTP components also. But you would need to build the message body and headers according to the RPC style, but that should not be so hard either to do.
On trying to modify an existing wsdl and changing the Request Type and Response Type of an operation I am getting the below.
The process I followed is :
1. Modify the xsd
2. Generate Java Bean Skeleton (Can not change it as it is referred in multiple places)
Fixes tried :
1. Referred to multiple articles and have changed the WSDL to be elementFormDefault="unqualified" and to regenerate the supporting files.
2. I have tried to set xmlns="" to disable namespace for the field.
WSDL (Pasting just the modified operation, the original wswdl has around 52 operations)
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="ABCDEF" targetNamespace="http://managemyxyz.services.abc.def/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://managemyabc.services.abc.def/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsd1="http://cat.abc.def/ABC/schema/">
<wsdl:types>
<xsd:schema targetNamespace="http://manageabc.services.abc.def/">
<xsd:complexType name="NewType"/>
</xsd:schema>
<xsd:schema>
<xsd:import namespace="http://cat.abc.def/ABC/schema/" schemaLocation="xsd/ABC.xsd">
</xsd:import>
</xsd:schema>
<wsdl:message name="insertABCRequest">
<wsdl:part name="insertABCRequest" type="xsd1:InsertABCItemRequestType"/>
</wsdl:message>
<wsdl:message name="insertABCItemResponse">
<wsdl:part name="insertABCItemResponse" type="xsd1:InsertABCItemResponseType"/>
</wsdl:message>
<wsdl:portType name="ABCDEF">
<wsdl:operation name="insertABC">
<wsdl:input message="tns:insertABCItemRequest1"/>
<wsdl:output message="tns:insertABCItemResponse1"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ABCSOAP" type="tns:ABC">
<wsdl:operation name="insertABC">
<soap:operation soapAction="http://manageabc.services.abc.def/insertABC"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ABC">
<wsdl:port binding="tns:ABCSOAP" name="ABCSOAP">
<soap:address location="http://localhost:10039/.modulename.war/services/ABCSOAP"/>
</wsdl:port>
ABC.xsd
<element name="InsertABCRequest" type="Q1:InsertABCItemRequestType">
</element>
<complexType name="InsertABCItemRequestType">
<sequence>
<element name="abcdId" type="int"/>
<element name="abcdCode" type="string"/>
<element name="abcNumber" type="string"/>
</sequence>
</complexType>
<element name="InsertABCItemResponse" type="Q1:InsertABCItemResponseType">
</element>
<complexType name="insertABCItemResponse">
<sequence>
<element name="responseHeader" type="Q1:ResponseCodeType"/>
</sequence>
</complexType>
Exception :
[11/28/14 13:21:20:240 IST] 000000af WebServicesSe E com.ibm.ws.webservices.engine.transport.http.WebServicesServlet doPost WSWS3227E: Error: Exception:
WebServicesFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
faultString: org.xml.sax.SAXException: WSWS3047E: Error: Cannot deserialize element fieldName of bean com.abc.xyz.abc.InsertABCRequestType.
Child element fieldName does not belong in namespace .
Most likely, a third party web services platform has sent an incorrect SOAP message. Message being parsed:
faultActor: null
faultDetail:
org.xml.sax.SAXException: WSWS3047E: Error: Cannot deserialize element fieldName of bean com.abc.xyz.abc.InsertABCRequestType.
Child element InsertABCRequestType does not belong in namespace .
Most likely, a third party web services platform has sent an incorrect SOAP message. Message being parsed:
at com.ibm.ws.webservices.engine.WebServicesFault.makeFault(WebServicesFault.java:300)
at com.ibm.ws.webservices.engine.SOAPPart._getSOAPEnvelope(SOAPPart.java:1090)
at com.ibm.ws.webservices.engine.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:628)
at com.ibm.ws.webservices.engine.SOAPPart.getEnvelope(SOAPPart.java:656)
at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCHandlerChain.handleRequest(JAXRPCHandlerChain.java:301)
at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCHandler.invokeServerRequestHandler(JAXRPCHandler.java:516)
at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCHandler$1.invoke(JAXRPCHandler.java:381)
at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:225)
at com.ibm.ws.webservices.engine.WebServicesEngine.invoke(WebServicesEngine.java:336)
at com.ibm.ws.webservices.engine.transport.http.WebServicesServlet.doPost(WebServicesServlet.java:1246)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
at com.ibm.ws.webservices.engine.transport.http.WebServicesServletBase.service(WebServicesServletBase.java:344)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
Environment Details :
Server : IBM WAS 7.0.0.31
IDE : IBM RAD 8.5
Please let me know if any other information is required.
#BK Elizabeth - thank you for your response. As per the current implementation it is the wsdl that is used to generate the java beans using top down approach instead of bottom up approach you referred to in your comment (no doubt that is a better approach).
The real problem was that the generated beans are added at the container level as a shared lib since objects of the beans are passed between multiple modules. So even though I was updating the beans at module level but actually a previous version of the service beans were loaded. On updating the shared lib my changes started reflecting and the error "WSWS3047E: Error: Cannot deserialize element" got resolved".
For "WSWS3047E: Error: Cannot deserialize element" error below mentioned link can be referred, though my problem was bit different problem.
http://www-01.ibm.com/support/docview.wss?uid=swg21220377
I've the task of routing message to different jms queues based on the soapAction. I'm using <cxf:proxy-service> so basically there is no other way to find what operation was invoked other than populating soapAction attribute in WSDL (unless someone tells me otherwise). So this is what I was trying to achieve:
<choice>
<when expression="message.inboundProperties['SOAPAction'] == 'submitOrderStatus'">
<jms:outbound-endpoint queue="mviq.1122.result" />
</when>
....
</choice>
But the above code does not evaluate to true even though if I print the expression shown below using logger, I get "submitOrderStatus"
<logger message="SoapAction is #[message.inboundProperties['SOAPAction']]" level="INFO" />
After banging my head for too long and hours of dissection of log files, I realized that all the values of properties are unquoted except for SOAPAction.
So changing my flow to this saved me:
<when expression="message.inboundProperties['SOAPAction'] == '"submitOrderStatus"'">
<logger message="Can evaluate this message.inboundProperties['SOAPAction'] == '"submitOrderStatus"'" level="INFO" />
<jms:outbound-endpoint queue="mviq.1122.result" />
</when>
I'm very curious to know why does Mule returns SoapAction as double quoted String
EDIT: SoapUI send this over the wire. I'm not sure why SOAPAction is quoted.
POST http://localhost:61005/mvi/service HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "submitOrderStatus"
Content-Length: 5355
Host: localhost:61005
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)`
Below is part of my wsdl:
<wsdl:operation name="submitOrderStatus">
<soap:operation soapAction="submitOrderStatus" style="document"/>
<wsdl:input name="submitOrderStatusRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="submitOrderStatusResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
there is no other way to find what operation was invoked other than populating soapAction attribute in WSDL
This is not correct: see how I get the operation from the cxf_operation flow variable in my answer https://stackoverflow.com/a/14163660/387927
I'm very curious to know why does Mule returns SoapAction as double quoted String
SOAPAction headers are quoted as per the spec: http://www.w3.org/TR/soap11/#_Toc478383528
So your expression should be:
<when expression="#[message.inboundProperties['SOAPAction'] == '"e;submitOrderStatus"e;']">
Just tried to generate java client generation from a WSDL file ( using XFire using XMLBeans binding )
I am able to generate the client + Fault Message ( no error ) , however input message and output message was not generated, it's also not generating the operation in the client. Is there anything wrong with my WSDL file, or is there anything I miss ?
Update :
I updated my test XFire project here.
I begin to suspect that the problem can be isoldated to the WSDL (because I can generate other WSDL successfully). I found these warnings, which I feel related :
WS-I: (BP2402) The wsdl:binding element does not use a
soapbind:binding element as defined in section "3 SOAP Binding." of
the WSDL 1.1 specification.
WS-I: (BP2032) Defective soapbind:fault element: the "name" attribute value does not match the value of the "name" attribute on
the parent element wsdl:fault.
WS-I: (AP2901) A description uses neither the WSDL MIME Binding as described in WSDL 1.1 Section 5 nor WSDL SOAP binding as described in
WSDL 1.1 Section 3 on each of the wsdl:input or wsdl:output elements
of a wsdl:binding.
Just found that soap12 might caused the issue. If I changed the xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/" to xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" and removing soapActionRequired in soap:operation it can generated the client successfully. But the webservice is currently only in soap1.2 only. So changing the wsdl to use soap1.1 is not the case here.
Here is my WSDL file :
<!--Created by TIBCO WSDL-->
<wsdl:definitions xmlns:tns="http://schemas.ocbc.com/soa/WSDL/service/CBS-CustAccountInfo-I" xmlns:soap1="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:jndi="http://www.tibco.com/namespaces/ws/2004/soap/apis/jndi" xmlns:ns="http://schemas.ocbc.com/soa/emf/common/envelope/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:jms="http://www.tibco.com/namespaces/ws/2004/soap/binding/JMS" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="Untitled" targetNamespace="http://schemas.ocbc.com/soa/WSDL/service/CBS-CustAccountInfo-I">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://schemas.ocbc.com/soa/emf/common/envelope/" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="../Schemas/XML/CBS-CustAccountInfo-I-ServiceEnvelope.xsd"/>
</xs:schema>
</wsdl:types>
<wsdl:service name="CBS-CustAccountInfo-I">
<wsdl:port name="CBS-CustAccountInfo-I_HTTP" binding="tns:CBS-CustAccountInfo-I_HTTPBinding">
<soap:address location="https://localhost:15038/Services/CBS-CustAccountInfo-I/Processes/MainRequestResponse_HTTP"/>
</wsdl:port>
</wsdl:service>
<wsdl:portType name="PortType">
<wsdl:operation name="CBS-CustAccountInfo-I">
<wsdl:input message="tns:InputMessage"/>
<wsdl:output message="tns:OutputMessage"/>
<wsdl:fault name="fault1" message="tns:FaultMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CBS-CustAccountInfo-I_HTTPBinding" type="tns:PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="CBS-CustAccountInfo-I">
<soap:operation style="document" soapAction="/Services/CBS-CustAccountInfo-I/Processes/MainRequestResponse_HTTP" soapActionRequired="true"/>
<wsdl:input>
<soap:body use="literal" parts="InputMessage"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="OutputMessage"/>
</wsdl:output>
<wsdl:fault name="fault1">
<soap:fault use="literal" name="fault1"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:message name="InputMessage">
<wsdl:part name="InputMessage" element="ns:ServiceEnvelope"/>
</wsdl:message>
<wsdl:message name="OutputMessage">
<wsdl:part name="OutputMessage" element="ns:ServiceEnvelope"/>
</wsdl:message>
<wsdl:message name="FaultMessage">
<wsdl:part name="FaultMessage" element="ns:ServiceEnvelope"/>
</wsdl:message>
</wsdl:definitions>
And here is my ant task to generate :
<!-- Generating XML Beans -->
<target name="gen-xmlbeans">
<java classname="org.apache.xmlbeans.impl.tool.SchemaCompiler"
classpathref="build.classpath"
fork="true">
<arg value="-out"/>
<arg value="${basedir}/lib/ocbc.jar"/>
<arg value="${schema.path}"/>
</java>
</target>
<!-- Generating Client -->
<target name="ws-generate">
<taskdef name="wsgen" classname="org.codehaus.xfire.gen.WsGenTask">
<classpath>
<fileset dir="${lib.dir}" includes="*.jar" />
</classpath>
</taskdef>
<wsgen outputDirectory="${basedir}/src/" wsdl="${wsdl.path}" package="test.client" overwrite="true" binding="xmlbeans"/>
</target>
Generated Client :
public class CBS_CustAccountInfo_IClient {
private static XFireProxyFactory proxyFactory = new XFireProxyFactory();
private HashMap endpoints = new HashMap();
public CBS_CustAccountInfo_IClient() {
}
public Object getEndpoint(Endpoint endpoint) {
try {
return proxyFactory.create((endpoint).getBinding(), (endpoint).getUrl());
} catch (MalformedURLException e) {
throw new XFireRuntimeException("Invalid URL", e);
}
}
public Object getEndpoint(QName name) {
Endpoint endpoint = ((Endpoint) endpoints.get((name)));
if ((endpoint) == null) {
throw new IllegalStateException("No such endpoint!");
}
return getEndpoint((endpoint));
}
public Collection getEndpoints() {
return endpoints.values();
}
}
#Rudy If you have to use XFire, you might consider to try other binding such as JAXB binding and see if you're able to get the code generated properly.