How does a SOAP WS know the requested operation? - soap

Say my WSDL contains the following:
<message name="modifRequest">
<part name="siList" element="sn:siListElement"/>
</message>
<message name="modifResponse">
<part name="siList" element="sn:boolElement"/>
</message>
<portType name="siModificationPortType">
<operation name="delete">
<input message="tns:modifRequest" />
<output message="tns:modifResponse" />
</operation>
<operation name="update">
<input message="tns:modifRequest" />
<output message="tns:modifResponse" />
</operation>
</portType>
Which generates the following SOAP client message in SoapUI, whether in an update or a delete request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sim="simSchema">
<soapenv:Header/>
<soapenv:Body>
<sim:siListElement>
<!--1 or more repetitions:-->
<sim:si name="?" desc="?" workspace="workspace">
<!--Zero or more repetitions:-->
<sim:bp name="?" value="?" bps="?"/>
</sim:si>
</sim:siListElement>
So it seems that the only thing sent through HTTP to the WS is the siListElement. But how does the WS know the operation the client wants to reach (here, delete/update)? Especially in that case where the inputs of both operations have the same structure.

The WS know the operation through SOAPAction HTTP Header. When you create a new SOAP Test request in SOAPUI you have to select the operation and choosing it then SOAPUI automatically sets the operation for you request an maps this operation to the necessary SOAPAction which it will send as HTTP header when you run the test request.
This "magic" happens because in your WSDL surely there is also a information which you are missing in your question which is binding the wsdl:operation against soap:operation. In your WSDL probably there are something like:
<binding name="bindingDelete" type="siModificationPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="delete">
<soap:operation soapAction="delete"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<binding name="bindingAdd" type="siModificationPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="add">
<soap:operation soapAction="add"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
So when you specify to SOAPUI that your operation is delete then SOAPUI is sending SOAPAction http header with the correct value like for example delete, instead of you specify add operation then SOAPAction http header with some value like add is send.
You can check what I'm saying runing your request and clicking on the Raw tab on the left side of your SOAPRequest and checking the different SOAPAction values for your operation types:
Hope this helps,

Related

WSO2 ESB Call SOAP Endpoint couldn't perform operation

I want to call SOAP endpoint URL with Action from WSO2 ESB. I could call the SOAP URL and getting entire wsdl response but i couldn't perform the Action.
Let say my wsdl respone
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ....>
<wsdl:types>
<xs:schema ..>...</xs:schema>
</wsdl:types>
<wsdl:service>..</wsdl:service>
<wsdl:portType name="..">
<wsdl:operation name="AAA">
<wsdl:input message="tns:in"/>
<wsdl:output message="tns:out"/>
<wsdl:fault name="fault1" message="tns:Error"/>
</wsdl:operation>
<wsdl:operation name="BBB">
<wsdl:input message="tns:in"/>
<wsdl:output message="tns:out"/>
<wsdl:fault name="fault1" message="tns:Error"/>
</wsdl:operation>
<wsdl:operation name="CCC">
<wsdl:input message="tns:in"/>
<wsdl:output message="tns:out"/>
<wsdl:fault name="fault1" message="tns:Error"/>
</wsdl:operation>
......
......
</wsdl:portType>
...
This is my WSO2 ESB code to call SOAP Endpoint
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope
xmlns:app="...xsd"
xmlns:com=".....xsd"
xmlns:ser="...xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ser:...Request>
<app:ApplicationHeader>
<app:...>$1</app:...>
<app:...>$2</app:...>
</app:ApplicationHeader>
<ser:DataHeader>
<ser:....>$3</ser:...
<ser:...>$4</ser:...>
</ser:DataHeader>
</ser:...Request>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg value="1"/>
<arg value="2"/>
<arg value="3"/>
<arg value="4"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="AAA"/>
<call blocking="true">
<endpoint>
<address uri="http:/URL/>
</endpoint>
</call>
<respond/>
When I call this code, i will get above entire WSDL response instead of operation "AAA"
But I should get this operation
It looks like you specified wsdl url as an address of endpoint. That's why you receive wsdl file and an error that instead of Soap envelope it gets definitions.
You should use wsdl endpoint.
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="Service">
<wsdl uri="https://yourServer/yourService?wsdl" service="yourService" port="yourServiceSoap">
<suspendOnFailure>
<progressionFactor>1.0</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
<retryDelay>0</retryDelay>
</markForSuspension>
</wsdl>
</endpoint>
Or you may use address endpoint, but take the URI from wsdl file in wsdl:port section,
for this example, take https://yourServer/service/yourService.asmx as an URI:
<service name="yourService">
<port name="yourServiceSoap" binding="yourServiceSoapBinding">
<soapbind:address location="https://yourServer/service/yourService.asmx"/>
</port>
</service>

WSDL Complex Type Request Clarification

I am breaking my head to configure a complex type in a WSDL file and see that complex type in SOAP UI client.
Find below the WSDL file.
<?xml version ='1.0' encoding ='UTF-8' ?>
<wsdl:definitions name='Catalog'
targetNamespace='http://website.net/websitesmsmobile'
xmlns:tns='http://website.net/websitesmsmobile'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<types>
<xsd:complexType name="xsd:parameter">
<xsd:sequence>
<xsd:element name="key" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="xsd:parameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="1" name="parameter" type="tns:parameter"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</types>
<message name='callServerRequest'>
<part name='methodName' type='xsd:string'/>
<part name='parameter' type='paramters'/>
</message>
<message name='callServerResponse'>
<part name='response' type='xsd:string'/>
</message>
<portType name='websitePortType'>
<operation name='callServer'>
<input message='tns:callServerRequest'/>
<output message='tns:callServerResponse'/>
</operation>
</portType>
<binding name='websiteBinding' type='tns:websitePortType'>
<soap:binding
style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'
/>
<operation name='callServer'>
<soap:operation soapAction='urn:website-net-websitesmsmobile#callServer'/>
<input>
<soap:body
use='encoded'
namespace='urn:website-net-websitesmsmobile'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body
use='encoded'
namespace='urn:website-net-websitesmsmobile'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<service name='websiteService'>
<port name='websitePort' binding='websiteBinding'>
<soap:address location='http://localhost/smsmobile/server/smsmobile.php'/>
</port>
</service>
</wsdl:definitions>
When I create a request in SOAP UI I see the below.
<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:urn="urn:website-net-websitesmsmobile">
<soapenv:Header/>
<soapenv:Body>
<urn:callServer soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<methodName xsi:type="xsd:string">?</methodName>
</urn:callServer>
</soapenv:Body>
</soapenv:Envelope>
The 'methodName' which is a string type got successfully generate. Why the complex type 'parameter' is not generated in the request?
Whats wrong in the WSDL file?
http://www.w3.org/TR/2001/NOTE-wsdl-20010315
(Example 5. SOAP binding of request-response RPC operation over HTTP)
GO through above link at example 5. Your schema definition is not correct at binding, thats why it is not showing your request message properly.

SoapUI uses mesagename and not operationname in message

I have a problem with a service wsdl that is delivered by a third party. Let my try to explain. Take this wsdl part:
<wsdl:portType name="IBestelService">
<wsdl:operation name="PlaatsOrder">
<wsdl:input message="tns:PlaatsOrderRequest"/>
<wsdl:output message="tns:PlaatsOrderResponse"/>
<wsdl:fault message="tns:BestelServiceFault" name="BestelServiceFault"/>
</wsdl:operation>
<wsdl:operation name="PlaatsOrderThreeShips">
<wsdl:input message="tns:PlaatsOrderRequestThreeShips"/>
<wsdl:output message="tns:PlaatsOrderResponseThreeShips"/>
<wsdl:fault message="tns:BestelServiceFault" name="BestelServiceFault"/>
</wsdl:operation>
</wsdl:portType>
For the request soapui (and .net to) generates the following request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sambo-ict:basetypes:1.0" xmlns:urn1="urn:sambo-ict:bestelservice:types:1.0">
<soapenv:Header>
<urn:AuthenticationHeader xmlns="urn:sambo-ict:basetypes:1.0"/>
</soapenv:Header>
<soapenv:Body>
<urn1:PlaatsOrderRequest>
<EAN>9789490998394</EAN>
<DistributorOrderId>13188</DistributorOrderId>
<DeliveryMethod>Tegoed</DeliveryMethod>
<Amount>1</Amount>
</urn1:PlaatsOrderRequest>
</soapenv:Body>
</soapenv:Envelope>
However the service at the third party site expects this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sambo-ict:basetypes:1.0" xmlns:urn1="urn:sambo-ict:bestelservice:types:1.0">
<soapenv:Header>
<urn:AuthenticationHeader xmlns="urn:sambo-ict:basetypes:1.0"/>
</soapenv:Header>
<soapenv:Body>
<urn1:PlaatsOrder>
<EAN>9789490998394</EAN>
<DistributorOrderId>13188</DistributorOrderId>
<DeliveryMethod>Tegoed</DeliveryMethod>
<Amount>1</Amount>
</urn1:PlaatsOrder>
</soapenv:Body>
</soapenv:Envelope>
When I search the internet on soap. The "plaatsorder" instead of "plaatsorderrequest" seems to be the right way. However I do not believe that both soapui/java and .net have it wrong. So can anyone explain the difference to me?
The element:
<wsdl:input message="tns:PlaatsOrderRequest"/>
will have an associated message entry that looks like:
<wsdl:message name="PlaatsOrderRequest">
<wsdl:part element="urn1:PlaatsOrderRequest" name="parameters" />
</wsdl:message>
That element name is what dictates the wrapped request element, assuming this is a document/literal wrapped service (which they usually are). I would need the full WSDL and schema to be more definitive.
You can make this change by yourself in wsdl. It's easy just replace that tag whichever is required. It would work.
by the way you can directly ask your client by providing right wsdl with this change. It would be easy for them to generate wsdl with required request tag.

soapUI - Use WSDL from Websphere Message Broker

I'm doing a project with WebSphere Message Broker which results in 2 BAR files. One the client and the other the server. Both are deployed in a broker in a remote location (a server upstairs). The WSDL that the server flow uses is inside an Message Set Project. Here is the wsdl structure:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3.1-hudson-749-SNAPSHOT. -->
<definitions targetNamespace="http://ws.interact.bytesw.com/" name="TvPagaInteractWebService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.interact.bytesw.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<types>
<xsd:schema>
<xsd:import namespace="http://ws.interact.bytesw.com/" schemaLocation="TvPagaInteractWebServiceService.xsd"/>
</xsd:schema>
</types>
<message name="ejecutarTransaccion">
<part name="parameters" element="tns:ejecutarTransaccion"/>
</message>
<message name="ejecutarTransaccionResponse">
<part name="parameters" element="tns:ejecutarTransaccionResponse"/>
</message>
<message name="consultarOperacion">
<part name="parameters" element="tns:consultarOperacion"/>
</message>
<message name="consultarOperacionResponse">
<part name="parameters" element="tns:consultarOperacionResponse"/>
</message>
<message name="consultarServicio">
<part name="parameters" element="tns:consultarServicio"/>
</message>
<message name="consultarServicioResponse">
<part name="parameters" element="tns:consultarServicioResponse"/>
</message>
<portType name="TvPagaInteractWebService">
<operation name="ejecutarTransaccion">
<input message="tns:ejecutarTransaccion"/>
<output message="tns:ejecutarTransaccionResponse"/>
</operation>
<operation name="consultarOperacion">
<input message="tns:consultarOperacion"/>
<output message="tns:consultarOperacionResponse"/>
</operation>
<operation name="consultarServicio">
<input message="tns:consultarServicio"/>
<output message="tns:consultarServicioResponse"/>
</operation>
</portType>
<binding name="TvPagaInteractWebServicePortBinding" type="tns:TvPagaInteractWebService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="ejecutarTransaccion">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="consultarOperacion">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="consultarServicio">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="TvPagaInteractWebService">
<port name="TvPagaInteractWebServicePort" binding="tns:TvPagaInteractWebServicePortBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
</port>
</service>
</definitions>
Once deployed I want to use it from soapUI. But I don't know which endpoint configure it. I've been trying some combinations including the IP and port of the broker connection. But doesn't work, can someone help me, please?
At the bottom of your WSDL you have this
<service name="TvPagaInteractWebService">
<port name="TvPagaInteractWebServicePort" binding="tns:TvPagaInteractWebServicePortBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
</port>
</service>
In REPLACE_WITH_ACTUAL_URL goes the address where WMB should bind this particular service so its accesible from the outside
The port which the broker is listening on is a property of the listener. The SOAP nodes use the EG level embedded listener by default so you can find this by executing the command:
mqsireportproperties -e -o HTTPConnector -r
This port can be found in this information but also the current URL registrations are displayed.
The path that the service is bound to is defined by the URL property on the SOAP node itself which you can find from the toolkit.

Hand rolled SOAP request

I am trying to construct a hand rolled HTTP request in order to return a response from what I thought was a fairly simple SOAP web service call. However, I am having trouble constructing the request properly, and am not getting the response I expect.
Applicable wsdl statements:
wsdl Target Namespace:
targetNamespace="http://tempuri.org/"
wsdl Service
<wsdl:service name="TrackerService">
<wsdl:port name="BasicHttpBinding_ITrackerService" binding="tns:BasicHttpBinding_ITrackerService">
<soap:address location="http://mydomain.com/TrackerServiceSite/wctest2.TrackerService.svc"/>
</wsdl:port>
</wsdl:service>
wsdl Message
<wsdl:message name="ITrackerService_GetStub_InputMessage">
<wsdl:part name="parameters" element="tns:GetStub" />
</wsdl:message>
<wsdl:message name="ITrackerService_GetStub_OutputMessage">
<wsdl:part name="parameters" element="tns:GetStubResponse" />
</wsdl:message>
wsdl Binding and SOAP Operation
<wsdl:binding name="BasicHttpBinding_ITrackerService" type="tns:ITrackerService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
.
. <!—- Omitted for brevity -->
.
<wsdl:operation name="GetStub">
<soap:operation soapAction="http://tempuri.org/ITrackerService/GetStub" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
EXPECTED Return Response
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<GetStubResponse xmlns="http://tempuri.org/">
<GetStubResult xmlns:a=http://schemas.datacontract.org/2004/07/wctest2 xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Password>SOMEPASS</a:Password>
<a:Username>SOMEUSER</a:Username>
</GetStubResult>
</GetStubResponse>
</s:Body>
</s:Envelope>
HTTP request thus far:
POST http://mydomain.com/TrackerServiceSite/wctest2.TrackerService.svc HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: 297
Host: mydomain.com
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetStub xmlns="http://tempuri.org/"/>
</soap:Body>
</soap:Envelope>
HTTP Response
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</faultcode>
<faultstring xml:lang="en-US">
The message with Action '' cannot be processed at the receiver, due to a
ContractFilter mismatch at the EndpointDispatcher. This may be because of
either a contract mismatch (mismatched Actions between sender and receiver)
or a binding/security mismatch between the sender and the receiver. Check
that sender and receiver have the same contract and the same binding
(including security requirements, e.g. Message, Transport, None).
</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
I am pretty sure that I need to include a soapAction from the wsdl file somewhere in my request, but I'm not sure where to include it. What else am I missing? Any help would be greatly appreciated.
Place your soap action in the SOAPAction HTTP header