wso2 cpp code generation with wsdl2cpp client side with MTOM attachment - soap

I have a soap web service exposed with axis2 (Java) which serializes POJOs, such as a Person that has a name and so on, as action responses. Moreover, I have an action which uses a DataHandler that is serialized in order to put a binary attachment in the response using <xop:Include ...></xop:Include>
I have generated the client side code in c++ using wsdl2cpp provided by wso2 wsfcpp. The getPerson(personId) action works fine and the results are as expected. However, the getFile(someId) action is successful although the generated code doesn't seem to work properly.
The service as enableMTOM=true set in axis2.xml as well as the client. I even added the Options.setEnableMTOM(true) to be sure in the main on the client side.
I believe that the problem is the code that is generated from the wsdl since the envelope of the getFile(someId) response is valid (and I have tested it manually with the axis2c api and I can retrieve the file as expected).
Here is the schema contained in the wsdl (which is generated from axis2 Java) for the response:
<xs:element name="getFileResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="xs:base64Binary"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Here is the command line used to generate the client code:
WSDL2CPP -uri MyService.xml -g -d adb -u -f
Here is the response received from the service:
<ns:getFileResponse xmlns:ns="http://services.myplace.com">
<ns:return>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:1.3ad8fc0571509f196559ee5312c14d23250854e4c9c8383e#apache.org"></xop:Include>
</ns:return>
</ns:getFileResponse>
Is there something missing in the wsdl or is that feature (soap with MTOM client code generation) not implemented by wsfcpp?
Thanks in advance!

I've tried the same thing with gSoap and I had the same problem. I figured that axis2 automatically detect whether the binary is optimized or not. Also, I found that in either case, the return element type exposed by the wsdl is type="xs:base64Binary".
The only work around I found was to patch, by replacing xs:base64Binary by xop:Include, the WSDL using a python (or whatever) script and then generate the code.
That solved the problem but makes maintainability issues.

Related

How can I add WS-A adressing to a SOAP webservice-request via Robot Framework?

I am new with Robot Framework and I run into a problem.
I try to call a web service that requires WSA (Web Service Addressing).
I tried sending a request while using SoapUI.
Sending a request via SoapUI provides a <wsa:Action>, a <wsa:RelatesTo> and a <wsa:MessageID> tag in the header when WSA is enabled.
Now I want to do the same with RobotFramework.
How can I inject these same tags via Robot Framework?
Here is my test
*** Settings ***
Library SudsLibrary
Library Collections
Library String
*** Test Cases ***
test
[Tags] blah
Create Soap Client C:${/}Robot WS${/}WS${/}wsdl${/}C60W30A.wsdl
Set Http Authentication MyUID MyPWD
${C60W30A}= Create Wsdl Object ns0:Invoer
${taimen}= Set Soap Headers "wsa:Action" GenBetKenmOperation
Set Wsdl Object Attribute ${C60W30A} Functie 04
Set Wsdl Object Attribute ${C60W30A} Bronsysteem COA
Set Wsdl Object Attribute ${C60W30A} Gebruiker WILLT10
${result}= Call Soap Method GenBetKenmOperation ${C60W30A}
Where the resulting XML is:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.MyCompany.nl/inning/coa/GenererenBetKenmerk" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:GenererenBetKenm>
<Invoer>
<Functie>04</Functie>
<Bronsysteem>COA</Bronsysteem>
<Gebruiker>GeBrID</Gebruiker>
</Invoer>
</ns1:GenererenBetKenm>
</ns0:Body>
</SOAP-ENV:Envelope>
And the error:
FAIL : WebFault: Server raised fault: 'A required header representing a Message Addressing Property is not present'
As you can see the <wsa:Action> tag is missing. As wel are the other SOAP-header tags when I add them.

SOAP-body auto generated namespace

I have to do some support on a single-function SOAP webservice, and I am failing to understand a specific aspect of the WSDL file & the resulting SOAP request as generated by SoapUI.
The WSDL for this service specifies a targetNamespace in the definitions part (targetNamespace="tetra-river-common-types/trafficinfo").
If I load the WSDL file into SoapUI, it reads everything perfectly fine; no issues at all with any of the definitions. The types for this service are defined in a single external schema file with the following definition in the WSDL file:
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="tetra-river-common-types" schemaLocation="tetra-river-interface.xsd" />
</xsd:schema>
</wsdl:types>
However, after loading the WSDL file into SoapUI, and opening the auto generated request, it shows the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tet="tetra-river-common-types">
<soapenv:Header/>
<soapenv:Body>
<tet:TrafficInformation>
<tet:Item1>?</tet:Item1>
<!-- several other items with the tet: namespace prefixed -->
</tet:TrafficInformation>
</soapenv:Body>
</soapenv:Envelope>
My question is: how is the tet: namespace determined by SoapUI? I see no mention of it in either the WSDL file or the XSD file. I assume it takes the first 3 characters from the targetNamespace, but I am unsure.
The problem I am facing is that the webservice itself expects this exact message, but with tetra: as the namespace.
If you see the wsdl, there is an import of namespace as below:
namespace="tetra-river-common-types"
And if you see the request in the soapUI, in the very first line has the same namespace with prefix tet i.e.,
xmlns:tet="tetra-river-common-types"
Hence, the respective request elements are prefixed with tet.
It does not really matter what the prefix is as along the referring to the same namespace.
For more information on namespaces, see here

JMeter changing my namespace

I'm trying to use JMeter to invoke a RPC/SOAP Web service and when I invoke the service my namespaces are mangled from the actual values to NS1.
<?xml version="1.0" encoding="UTF-8"?>
<wpc:invoke xmlns:wpc="http://wpc.ibm.com">
<wpc:envelope communicationVersion="5.3">
<wpc:WPCResponseType>asynchronous</wpc:WPCResponseType>
<wpc:wpcHeader>
<wpc:companyName>mycompany</wpc:companyName>
<wpc:wpsUserID>me</wpc:wpsUserID>
<wpc:wpcUserID>wpcUsername</wpc:wpcUserID>
<wpc:password />
<wpc:messageIdentifier>9E2FA100-BE54-11E5-8A91-BF48E24665E0</wpc:messageIdentifier>
<wpc:timestamp>2016-01-18</wpc:timestamp>
<wpc:supplierId><![CDATA[0Z188]]></wpc:supplierId>
<wpc:localeForDisplay>en_US</wpc:localeForDisplay>
<wpc:localeRestriction>en_US</wpc:localeRestriction>
</wpc:wpcHeader>
<wpc:wpcBody>
<wpc:wpcCommand mode="ASYNC" type="UPLOAD">
<wpc:wpcCatalogName>Item Transaction Catalog</wpc:wpcCatalogName>
<wpc:wpcFileDocStorePath>test_data/upload/0003_items.csv</wpc:wpcFileDocStorePath>
<wpc:wpcUpdateOnly>false</wpc:wpcUpdateOnly>
</wpc:wpcCommand>
</wpc:wpcBody>
</wpc:envelope>
</wpc:invoke>
Changes to:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:invoke xmlns:ns1="http://wpc.ibm.com">
<ns1:envelope communicationVersion="5.3">
<ns1:WPCResponseType>asynchronous</ns1:WPCResponseType>
<ns1:wpcHeader>
<ns1:companyName>mycompany</ns1:companyName>
<ns1:wpsUserID>me</ns1:wpsUserID>
<ns1:wpcUserID>wpcUsername</ns1:wpcUserID>
<ns1:password/>
<ns1:messageIdentifier>9E2FA100-BE54-11E5-8A91-BF48E24665E0</ns1:messageIdentifier>
<ns1:timestamp>2016-01-18</ns1:timestamp>
<ns1:supplierId><![CDATA[0Z188]]></ns1:supplierId>
<ns1:localeForDisplay>en_US</ns1:localeForDisplay>
<ns1:localeRestriction>en_US</ns1:localeRestriction>
</ns1:wpcHeader>
<ns1:wpcBody>
<ns1:wpcCommand mode="ASYNC" type="UPLOAD">
<ns1:wpcCatalogName>Item Transaction Catalog</ns1:wpcCatalogName>
<ns1:wpcFileDocStorePath>test_data/upload/0003_items.csv</ns1:wpcFileDocStorePath>
<ns1:wpcUpdateOnly>false</ns1:wpcUpdateOnly>
</ns1:wpcCommand>
</ns1:wpcBody>
</ns1:envelope>
</ns1:invoke>
There must be a setting in JMeter to keep the message from being transformed from my original meaningful namespace to this arbitrary namespace called NS1? When the message is received at the target endpoint it cannot parse the request because of this semantic error.
Any/all replies are appreciated!
MG
JMeter should not change anything in the request body, maybe it is an issues with your web service? Double check the request which is being sent by JMeter using a sniffer tool like Wireshark
In any case try switching to HTTP Request sampler, this is recommended way of sending web service requests (just don't forget to add HTTP Header Manager to send Content-Type and SOAPAction headers).
References:
JMeter User's Manual: Building a SOAP WebService Test Plan
Testing SOAP/REST Web Services Using JMeter

WNS template registration gets rejected from Azure Notification Hubs

I'm sending create or update template registration requests to my Azure Notification Hub using the REST API, but my requests always get rejected for template registrations for Windows Notification Service while it works for all other service types.
The body of my request looks correct to me, when I compare it with the documentation:
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<WindowsTemplateRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<Tags>SomeTag:1,TEST_REGISTRATION</Tags>
<ChannelUri>https://db3.notify.windows.com/?token=AgY7AABrfRCVgRV%2ba4DwoDjC2omrnOVwCkdhCrrzlJi6UpIwHzcig6%2fG5xZfnDqU0%2fXoE848ddiqyTaTlSSltp2Dn9Z3qaPsMAyh7kS%2bmlis1%2bwoh%2b%2b4DsAK1yeV1d9G1rUIuFs%3s</ChannelUri>
<BodyTemplate><![CDATA[<?xml version="1.0" encoding="utf-8" ?><data><title>$(title_en)</title><message>$(message_en)</message><notificationType>1</notificationType></data>]]></BodyTemplate>
<WnsHeaders>
<WNSHeader>
<Header>X-WNS-Type</Header>
<Value>wns/raw</Value>
</WNSHeader>
</WnsHeaders>
</WindowsTemplateRegistrationDescription>
</content>
</entry>
ANH always returns the response code 400 (Invalid request body. The registration could not be created because the request was malformed.), but using this format works for all other service types (e.g. GCM, MPNS) and I can create a WNS template registration manually using the Service Bus Explorer with the exact same ChannelUri, template and WnsHeaders.
What else could be wrong here? Is there any way to debug this?
Found the answer in this question: What does the following Azure Notification Hub REST response mean: 'The specified resource description is invalid.'?
"WNSHeader" needs to be written in Pascal case, like this: "WnsHeader", so the documentation is not 100% correct...

Hand-crafted WSDL from XSD fails in CXF: the namespace on the "QueryResponse" element, is not a valid SOAP version

I have a web service that follows some of the semantics of a SOAP service, but they don't provide a WSDL for said service. Instead, they provide an XSD, by which I'm reverse-engineering a WSDL out of. Things seemed to be going well, even so far as to be able to
create a WSDL
Import the XSD as part of the WSDL using the xsd:import tag
Create Java wrappers with CXF
Call the service.
Now, what I get when I call the service is an exception:
INFO: Creating Service {http://service.something.net/xml}QueryService from WSDL: file:/C:/mydocs/Work/project/my-service.wsdl
Aug 09, 2011 1:22:34 PM org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
WARNING: Interceptor for {http://service.something.net/xml}QueryService#{http://servicesomething..../xml}QueryRequest has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: "http://service.something.net/xml", the namespace on the "QueryResponse" element, is not a valid SOAP version.
The WSDL can be found in this gist, and the XSD is something I got from the vendor.
What does the error mean? What might I have done wrong in my .wsdl file generation?
Edit 1
I have manually tested the service from the vendor service, and the response seems okay to me:
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<QueryResponse xmlns="http://service.something.net/xml">
....
</QueryResponse>
</Body>
</Envelope>
Unless I'm missing something, there should not be any reason why CXF even wants the QueryResponse to be a SOAP element, since it's namespace isn't SOAP but http://service.something.net/xml.
Where you are importing your XSD:
<wsdl:types>
<xsd:schema targetNamespace="http://service.something.net/xml">
<xsd:include schemaLocation="My-XSD.xsd" />
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://service.something.net/xml"
schemaLocation="My-XSD.xsd">
</xsd:import>
</xsd:schema>
</wsdl:types>
try this instead:
<wsdl:types>
<xs:schema targetNamespace="http://service.something.net/xml"
elementFormDefault="qualified">
<xs:import schemaLocation="My-XSD.xsd"/>
</xs:schema>
</wsdl:types>
Basically you shouldn't need the include, just the import. Also you want to specify fully qualified element form.
Hope this works.