Security mechanism in WSDL - web-services

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).

Related

Add ws-security to flow in Mule

I am using mule without anypoint studio.
Exposed webservice in mule. Client sends a request, I transform the message (f.e. fill in some fields) and forward it to the external webservice (not managed by me).
Java classes for the external webservice were created using wsimport based on their wsdl
They require wss xml signature based on the keystore they gave me
Their service (and wsdl) is accessible via https
My goal: I want to add ws-security (just Signature action for now) in order to be able to make requests to their WS.
In conclusion: Client sends a request to WS on the mule I own (http), I transform it,
add ws-security and send it to the external webservice (https).
This is my WS:
#WebService
public interface LFlow {
#WebMethod
String exec(#WebParam(name = "pname") String pname,
#WebParam(name = "mname") String mname,
#WebParam(name = "parameters") String parameters);
}
And the request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:abc="http://a.b.c/">
<soapenv:Header/>
<soapenv:Body>
<abc:exec>
<pname>B</pname>
<mname>getC</mname>
<parameters>smth</parameters>
</abc:exec>
</soapenv:Body>
</soapenv:Envelope>
This is mule config I have for that:
<?xml version="1.0" encoding="UTF-8"?>
<mule <!--(...)--> >
<context:property-placeholder location="classpath:l.properties, classpath:wss.properties"
ignore-resource-not-found="true"/>
(...)
<flow name="lFlow">
<!-- Defined in other place: <http:connector name="domain-http-connector" /> -->
<http:inbound-endpoint connector-ref="domain-http-connector" address="${l.bind.address}" exchange-pattern="request-response"
doc:name="HTTP">
<cxf:jaxws-service serviceClass="a.b.c.LFlow" mtomEnabled="true">
<cxf:outFaultInterceptors>
<spring:bean class="a.b.c.interceptors.FaultSoapInterceptor"/>
</cxf:outFaultInterceptors>
</cxf:jaxws-service>
</http:inbound-endpoint>
<choice doc:name="Forward to proper process">
<!--(...)-->
<when expression="#[payload[0] == 'B']">
<flow-ref name="b" doc:name="b"/>
</when>
</choice>
</flow>
<!--(...)-->
<sub-flow name="b">
<choice doc:name="forward to proper method">
<!--(...)-->
<when expression="#[payload[1] == 'getC']">
<invoke object-ref="aHandler" method="getC" doc:name="Get C element"
methodArgumentTypes="java.lang.String" methodArguments="#[payload[2]]"/>
</when>
</choice>
</sub-flow>
</mule>
the wss.properties file is in the src/main/resources directory and looks like this:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

> org.apache.ws.security.crypto.merlin.keystore.type=jks

> org.apache.ws.security.crypto.merlin.keystore.password=pass

> org.apache.ws.security.crypto.merlin.keystore.alias=alias
org.apache.ws.security.crypto.merlin.file=path-to-keystore
handler on my side that does some transformations (not in this exmaple for simplicity):
#Component
public class AHandler {
private final AService aService;
#Autowired
public AHandler(final AService aService) {
this.aService = aService;
}
public GetCResponse getC(final String jsonPayload) {
return aService.getC(mapToGetCRequest(jsonPayload));
}
}
then it is routed to the class that is supposed to send it to the external web-service:
#Service
public class AServiceImpl implements AService {
// (...)
#Override
public GetCResponse getC(final GetCRequest request) {
return getInstance().getC(request);
}
private BInterface getInstance() {
/**
I have generated *.jar for the external B service using wsimport from their wsdl-url
*/
final B service = new B();
final BInterface port = service.getBSOAP();
final BindingProvider bindingProvider = (BindingProvider) port;
final Map<String, Object> context = bindingProvider.getRequestContext();
context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, /*wsdl-url*/);
context.put("thread.local.request.context", "true");
return port;
}
}
and this is part of the wsdl:
(...) <?xml name=B>
</wsdl:types>
<wsdl:message name="GetCRequest">
<wsdl:part element="b:GetCRequest" name="payload">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetCResponse">
<wsdl:part element="b:GetCResponse" name="payload">
</wsdl:part>
<wsdl:portType name="BInterface">
<wsdl:operation name="getC">
<wsdl:input message="b:GetCRequest">
</wsdl:input>
<wsdl:output message="b:GetCResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BSOAPBinding" type="b:BInterface">
<soap:binding style="b" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getC">
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="B">
<wsdl:port binding="b:BSOAPBinding" name="BSOAP">
<soap:address location="https://b.local/cxf/ba/b"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Communication works in soapui. I added outgoing ws-security configuration, added "signature" entry, chosen previously added keystore, with alias and password, and there it works. But I can't make it work in mule, hence the question.
As far as I know, I should either:
create WSS4JOutInterceptor with configured: action, signatureUser, signaturePropFile, passwordCallbackRef and somehow connect it with mule outgoing messages or
add <jaxws-client> or <proxy-client> with wss config embedded:
<cxf:ws-security>
<cxf:ws-config>
<cxf:property key="action" value="Signature"/>
<cxf:property key="signaturePropFile" value="wss.properties"/>
<cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
</cxf:ws-config>
</cxf:ws-security>
But I just can't make it work. I would really appreciate any help
Edited (24.08.2021T12:03:00Z):
Mule sdk 3.8.0
To answer what happens when I apply my solutions is complicated. I am not sure where exactly I should put the wss config. Should I use <jaxws-client> or <proxy-client> ? should it be in the <subflow> or <flow> ? what "attributes" to these elements I should pass (bare minimum, required to test if it even works) ? or maybe I should use <cxf:inInterceptors>/<cxf:outInterceptors> ?
I tried different configurations but I am not sure if I did it the right way, so the errors I was getting were probably results of my improper use. So I didn't put them here, cause they might make it harder to read my question.
Edited (24.08.2021T12:54:00Z):
But according to the doc:
proxy-client provides raw SOAP and WS-* processing for outgoing XML
messages, allowing you to send outgoing messages in raw XML form and
apply things like WS-Security to them.
I should use <proxy-client> and I believe it should be in the "subflow":
<sub-flow name="b">
<cxf:proxy-client>
<cxf:ws-security>
<cxf:ws-config>
<cxf:property key="action" value="Signature"/>
<cxf:property key="signatureUser" value="keystore-alias"/>
<cxf:property key="signaturePropFile" value="wss.properties"/>
<cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
</cxf:ws-config>
</cxf:ws-security>
</cxf:proxy-client>
<choice doc:name="forward to proper method">
<!--(...)-->
<when expression="#[payload[1] == 'getC']">
<invoke object-ref="aHandler" method="getC" doc:name="Get C element"
methodArgumentTypes="java.lang.String" methodArguments="#[payload[2]]"/>
</when>
</choice>
</sub-flow>
Is that correct ? what attributes should I define for <cxf:proxy-client> ? or maybe instead of defining <cxf:ws-security> inside, I should define interceptors like this:
<bean id="clientWss4jOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Signature"/>
<entry key="signatureUser" value=""/>
<entry key="signaturePropFile" value=""/>
<entry key="passwordCallbackRef" value-ref=""/>
</map>
</constructor-arg>
</bean>
(...)
<sub-flow name="b">
<cxf:proxy-client doc:name="Proxy client">
<cxf:outInterceptors>
<spring:bean id="clientWss4jOutInterceptor">
</spring:bean>
</cxf:outInterceptors>
</cxf:proxy-client>
(...)
Edited (25.08.2021T11:28:00Z):
When try to use consumer like this (mule-config.xml):
<?xml version="1.0" encoding="UTF-8"?>
<mule
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tls="http://www.mulesoft.org/schema/mule/tls"
version="CE-3.8.0"
xmlns:ws="http://www.mulesoft.org/schema/mule/ws"
(...)
<tls:context name="tlsContext">
<tls:key-store
path="C:\\Users\\john\\Documents\\integrationB.keystore"
keyPassword="privatekey-password"
password="keystore-password"
alias="alias" />
</tls:context>
<!--service, port, wsdl-url, address - all taken from wsdl-->
<ws:consumer-config
name="WebServiceConsumer"
serviceAddress="https://b.local/cxf/ba/b"
wsdlLocation="https://b.local/cxf/ba/b?wsdl"
service="B"
port="BSOAP">
<ws:security>
<ws:wss-sign tlsContext-ref="tlsContext" />
</ws:security>
</ws:consumer-config>
<flow name="lFlow">
<http:inbound-endpoint
connector-ref="domain-http-connector"
address="${l.bind.address}"
exchange-pattern="request-response"
doc:name="HTTP">
<cxf:jaxws-service serviceClass="a.b.c.LFlow" mtomEnabled="true">
<cxf:outFaultInterceptors>
<spring:bean class="a.b.c.interceptors.FaultSoapInterceptor"/>
</cxf:outFaultInterceptors>
</cxf:jaxws-service>
</http:inbound-endpoint>
<http:listener config-ref="HTTP_Listener_Configuration" path="*" doc:name="HTTP">
<http:response-builder statusCode="200"/>
</http:listener>
<ws:consumer config-ref="WebServiceConsumer" operation="getC" doc:name="Get C element"/>
<choice doc:name="Forward to proper process">
<!--(...)-->
<when expression="#[payload[0] == 'B']">
<flow-ref name="b" doc:name="b"/>
</when>
</choice>
</flow>
<!--(...)-->
<sub-flow name="b">
<choice doc:name="forward to proper method">
<!--(...)-->
<when expression="#[payload[1] == 'getC']">
<invoke object-ref="aHandler" method="getC" doc:name="Get C element"
methodArgumentTypes="java.lang.String" methodArguments="#[payload[2]]"/>
</when>
</choice>
</sub-flow>
</mule>
I get during app-start:
Caused by:
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException:
Line 46 in XML document from URL [file:/(...)/mule-config.xml] is
invalid; nested exception is org.xml.sax.SAXParseException;
lineNumber: 46; columnNumber: 61; cvc-complex-type.2.4.a: Invalid
content was found starting with element 'ws:consumer-config'. One of
(...) is expected.
46:61 points to the last charatcer of: port="BSOAP">.
If possible I would avoid using CXF and try the Web Service Consumer that it is much easier to use:
<tls:context name="tlsContext">
<tls:key-store path="path" keyPassword="pass" password="pass" alias="keyalias" />
</tls:context>
<ws:consumer-config name="Web_Service_Consumerweather" serviceAddress="http://localhost/test" wsdlLocation="Test.wsdl"
service="TestService" port="TestPort">
<ws:security>
<ws:wss-sign tlsContext-ref="tlsContext" />
</ws:security>
</ws:consumer-config>
<flow name="listInventory" doc:name="listInventory">
<http:listener config-ref="HTTP_Listener_Configuration" path="inventory" doc:name="HTTP">
<http:response-builder statusCode="200"/>
</http:listener>
<ws:consumer config-ref="Web_Service_Consumer" operation="ListInventory" doc:name="List Inventory"/>
</flow>
Also note that Mule 3.8 has been replaced by Mule 3.9. The latest release is Mule 4.3 which is not compatible with Mule 3.x and doesn't support CXF.
Documentation: https://docs.mulesoft.com/web-service-consumer-connector/0.3.9/

Web Services in ColdFusion 2016 no longer functional

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);

JAX- RPC : Getting error "org.xml.sax.SAXException: WSWS3047E: Error: Cannot deserialize element"

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

WSDL Client Generation not complete?

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.

Axis2 problem in setting SOAPAction HTTP header

I am trying co connect to a 3'rd party SOAP web service. It seems that the service can work when the HTTP SOAPAction header is an empty String (""). This is the snippet of the wsdl:
<wsdl:binding name="detailsRequestMessage" type="tns:UssdPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="details">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
Where you see the soapAction=""
I generated a stubusing the Axis2 (1.5) wsdl2java.
I was hoping to get the following (the successful output when running with SoapUI):
POST /details HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
User-Agent: Jakarta Commons-HttpClient/3.1
Host: some.host
Content-Length: 323
But instead I am getting:
POST /details HTTP/1.1
Content-Type: text/xml; charset=UTF-8
SOAPAction: "http://some.url/wsussd/ussdtypes/UssdPortType/detailsRequest"
User-Agent: Axis2
Host: some.host
Content-Length: 300
Does anyone has any idea what is the problem or how do I set the soapAction in the program.
Thanks,
Ronen
rperez wasn't entirely clear with his answer.
I have found https://issues.apache.org/jira/browse/AXIS2-4264 which claims the issue was fixed in 1.6.0, but I still have problems in 1.6.2
However, this does work:
stub._getServiceClient().getOptions().setProperty(org.apache.axis2.Constants.Configuration.DISABLE_SOAP_ACTION, true);
Have a look at the answer to this question...you may be able to find similar code in your generated stubs.
If that's the case, then I think you can set the action (according to the API):
serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
options.setAction("");
I think the action is handled differently depending on the SOAP version. To specify a different version:
options.setSoapVersionURI(
org.apache.axiom.soap.SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
(or the SOAP12 version of the constant).
Hope that helps.