WSO2 ESB - How to build soapenv:Body for remote service call - web-services

I have the WSDL file of the remote web service I need to call from a proxy service in the WSO2 ESB and would like to know if I need to construct the soap:Body's elements manually through XSLT/Enrich or there is a way to generate the soapenv:Body's contains from the WSDL and maybe replace '?' for the values.
For example, if you've used soapUI before you'll know that when you import a WSDL file in a project a soapenv:Envelope gets generated automatically with all the XML elements and question marks for their values. Same goes for the TryIt tool in the WSO2 ESB.
Here is an example of an auto-generated soapenv:Envelope in soapUI after importing WSDL:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:abc="http://abc.com/">
<soapenv:Header/>
<soapenv:Body>
<abc:RegisterCandidate>
<abc:NameFirst>?</abc:NameFirst>
<abc:NameMiddle>?</abc:NameMiddle>
<abc:NameLast>?</abc:NameLast>
<abc:PhoneHome>?</abc:PhoneHome>
<abc:EmailAddress>?</abc:EmailAddress>
<abc:Address1>?</abc:Address1>
<abc:Address2>?</abc:Address2>
<abc:City>?</abc:City>
<abc:State>?</abc:State>
<abc:ZipCode>?</abc:ZipCode>
<abc:Country>?</abc:Country>
</abc:RegisterCandidate>
</soapenv:Body>
</soapenv:Envelope>
Is this possible in the Proxy Service through any of the mediators available to read a WSDL and generate soapenv:Body with its XML tags (in the code above it would be abc:RegisterCandidate with its children)? I've done it with the use of the XSL templates, but it's manual and not very elegant.
I've found a few articles/blogs online about writing proxy services in the WSO2 ESB that call remote web services and what the developers were doing in there was to insert the XML elements needed in the soapenv:Body with the use of XSL templates to have the correct/full SOAP message that is then sent (send mediator) to the remote web service server.
Thank you.

There is no way to generate the soap body from the remote service's wsdl as in your requirement. But there is an easier way than using xslt. That is to use the payload factory mediator. You can define the payload and assign values using xpath as shown in the sample.

Related

Cannot consume Talend Soap API

I am trying to use the Tsoap component within Talend to consume the API. I have tried the Soap UI Client (separate application) and was able to get the response.
However within the Tsoap component within the Soap Message, I have pasted the sample request and I get an error eery single time. Can anyone help!
" <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns=\"http://clients.mindbodyonline.com/api/0_5\">
<soapenv:Header/>
<soapenv:Body>
<GetSites>
<Request>
<SourceCredentials>
<SourceName>Test235</SourceName>
<Password>3IERKOFDNFEOFMKDFOEMFD=</Password>
<SiteIDs>
<int>-99</int>
</SiteIDs>
</SourceCredentials>
<XMLDetail>Full</XMLDetail>
<PageSize>0</PageSize>
<CurrentPageIndex>0</CurrentPageIndex>
</Request>
</GetSites>
</soapenv:Body>
</soapenv:Envelope>"
What am I doing wrong?? Can anyone help please.
Can you send the error what you are getting?
Try this if you haven't done (just a guess)
--> If you are using and HTTPS web service then make sure to setup the authentication( I used Trust serve with SLL and provided the keystore file path and password)

WSO2 responds payload in binary

I have a corportative environment and make changes in axis2.xml and carbon.xml can generate impacts.
My problem is that WSO2 is responding the message in binary as an example:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<axis2ns1073:binary xmlns:axis2ns1073="http://ws.apache.org/commons/ns/payload">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48UzpFbnZlbG9wZSB4bWxuczpTPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VudmVsb3BlLyI+PFM6Qm9keT48UzpGYXVsdCB4bWxuczpuczQ9Imh0dHA6Ly93d3cudzMub3JnLzIwMDMvMDUvc29hcC1lbnZlbG9wZSI+PGZhdWx0Y29kZT4wMDU8L2ZhdWx0Y29kZT48ZmF1bHRzdHJpbmc+RVJSTyBETyBDUk0gLSBFU1RBIE9TIEpBIEZPSSBJTlNFUklEQSBOQSBCQVNFIERPIFNQUzI8L2ZhdWx0c3RyaW5nPjxkZXRhaWw+PGlucHV0TWVzc2FnZVZhbGlkYXRpb25GYXVsdD5PUkEtMDAwMDE6IHVuaXF1ZSBjb25zdHJhaW50IFdTX0hJU1RPUklDT19FTlRSQURBX1BLIHZpb2xhZGE8L2lucHV0TWVzc2FnZVZhbGlkYXRpb25GYXVsdD48L2RldGFpbD48L1M6RmF1bHQ+PC9TOkJvZHk+PC9TOkVudmVsb3BlPg==</axis2ns1073:binary>
</soapenv:Body>
</soapenv:Envelope>
Is there any way or mediator I can resolve this without much impact on other projects within the ESB?
Looks like you have enabled the binary message builder/formatter..Is there any need to use them?
If you use ESB 4.7.0/4.8.X , all those versions are using Pass thru transport..
What is the ESB version you use? Try disable binary message builder and use default message builders/formatters.
If you use binary builders for any specific requirement then use builder mediator to build message if you want to process the message when it passing through the system.

Technically,to create soap message, WSDL file is a must?

I'm using the SoapUI to generate the soap request. It hints me to input the wsdl file. I do it, and it create the soap-style message. Everything is OK.
But I have a doubt. If I have webservice without any WSDL file, can I still generate the soap-style message by hand? If it can, how to?
Or if I know the webservice need to input two int paramaters and return one string value, can I speculate the soap message only by these limited information?
If you are just doing -requests- then you don't need to have the WSDL file if you know the specific service you're asking and the parameters as you say. You can even do it by hand by creating the request and then sending it over HTTP (for example you could create it with your editor in a file and then send it via wget or curl).
As for an example I'll cite wikipedia:
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetStockPrice xmlns:m="http://www.example.org/stock">
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
What you need to change is the parts in the soap:Body: of course the GetStockPrice (which is the service you're accessing) and StockName which is the parameter (in your case you may have more than one).
If in doubt you can put something to listen on a socket (for example netcat) and make your application with WSDL do a query to it and see the exact informations, then remove WSDL and work "by hand".
In Java: If you have webservice (annotated class etc.), the your server create one WSDL file when you deployed it. This WSDL you can use for soapUi.
If you have any structure (endpoint, class, XSD etc.), you can create soap message by hand.
If you weren't use WSDL for soap message, it wouldn't call/send this message. So the wsdl document is a required element according to the protocol. WSDL describes of how the service can be called, what parameters it expects, and what data structures it returns.
From Wikipedia:
WSDL is often used in combination with SOAP and an XML Schema to
provide Web services over the Internet. A client program connecting to
a Web service can read the WSDL file to determine what operations are
available on the server. Any special datatypes used are embedded in
the WSDL file in the form of XML Schema. The client can then use SOAP
to actually call one of the operations listed in the WSDL file using
for example XML over HTTP.
Here is in example for invoking web service dynamically. In this case the author doesn't know the description of the WSDL.
The purpose of the WSDL is to describe the service.
This machine-readable description allows computer programs to create clients that know how to call the service and process the responses.

SOAP message using namespaces

We are designing a Web application which is invoked by an external system. We are going to receive a Web service from an external system which looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tis="http://schemas.tis.com/1.2/" xmlns:der="http://schemas.tis.com/DataProvisioning/">
<soapenv:Header>
<tis:SessionId>99999999</tis:SessionId>
</soapenv:Header>
<soapenv:Body>
<tis:Create>
<tis:MOType>SPPM#http://schemas.tis.com/DataProvisioning/</tis:MOType>
<tis:MOId>
<der:codex>12345677</der:msisdn>
</tis:MOId>
<tis:MOAttributes>
<der:createSPDD ProfileID="1" Action="createData">
<der:TechProduct Action="add" BarCode="15">
<der:Arguments ArgName="arg1" ArgType="string" ArgValue="1"></der:Arguments>
<der:Arguments ArgName="arg3" ArgType="string" ArgValue="2"></der:Arguments>
</der:TechProduct>
<der:TechProduct Action="delete" BarCode="21">
<der:Arguments ArgName="arg1" ArgType="string" ArgValue="1"></der:Arguments>
<der:Arguments ArgName="arg3" ArgType="string" ArgValue="2"></der:Arguments>
</der:TechProduct>
</der:createSPDD>
</tis:MOAttributes>
</tis:Create>
As you can see this SOAP Envelope we will receive contains namespaces in it. Up to now my Web services applications have been coded using JAX-WS and bottom-up approach (just adding #WebService and #WebMethod annotation to classes). What is the correct way to design a Web service that needs to receive a message based on namespaces ? Should I design first the WSDL ? I cannot see how to collect attributes which are in the Header or Body such as MoType or MoId. Any help ?
Thanks a lot
From your question it is tough to understand whether you want to expose a web service or you want to consume one. If you want to expose a web service with this structure and namespace you can choose bottom-up or top-down approach. Using top-down approach you will create
WSDL (here clearly you can mention the namespace for the service related details)
Schema (define the namespace for request and response elements)
Generate the Java classes from the WSDL and Schema.
Write the implementation for the Web Service interface.
If at all you want to consume the service then no need to write any WSDL. Get the WSDL and Schema(if any) from the service provider, Generate the Java classes from the WSDL and Schema received. You dont have worry about reading the values based on namespaces, the jaxws framework will do it for you.
Google the steps to consume a jaxws service.

Can A Header Be Added & Body Modified In A Salesforce SOAP Response?

From doing some testing on SOAP requests to a webservice I created in Salesforce I note the response returned is of the following format.
Note my request function I called is GetMsgRQ
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/schemas/class/MyIntegrationServices">
<soapenv:Body>
<GetMsgRQResponse>
<result>
<acctId>001J000000leVpEIAU</acctId>
<acctName>MyTest</acctName>
</result>
</lGetMsgRQResponse>
</soapenv:Body>
</soapenv:Envelope>
Relating to this I wonder is it possible to add a SOAP:Header?
Also I note the response has created an element "GetMsgRQResponse" (adding "Response" to "GetMsgRQ". Is it possible to create/specify the SOAP:Body without this occuring? Can I just set what the whole SOAP body response will be or will Salesforce always add such additional elements as the "GetMsgRQResponse" here and "result"?
Thanks in advance for any help on this. I know I can use a HTTP Request to send a full SOAP envelope but for my requirement I need to just provide a response instead of doing so.
I don't believe you can directly add any kind SOAP headers in an Apex defined WebService methods.
If you have absolutely no other option you could construct your own custom SOAP response via a REST web service (via #RestResource annotation) but that is a pretty ugly solution.