How to call an asynchronous BPEL process? - web-services

I've got an asynchronous BPEL process and I wanna call it from my Java EE web application. How can I do this? I'm using Oracle SOA-Suite 11g PS3.

An Asynchronous SOAP/HTTP sender is basically the same as a Synchronous SOAP/HTTP client, just it throws away the response. Only check the HTTP status of the response to verify that the receiver understood your message.
An Asynchronous receiver is basically a SOAP/HTTP server listening on the address sent in the "ReplyTo/Adress" field of the request. After receiving the message it sends an empty response with a "200" status code.
The sent and received messages are correlated using the WS-Addressing SOAP header fields "MessageID" (request) and "RelatesTo" (response).
If you are happy with a "low-tech" solution, you can send/receive Asynch SOAP requests just as XML over HTTP. The following HTTP Request will be understood by the BPEL process "AsynchDummy" as an asynchronous request. AsynchDummy is the default asynchronous BPEL process generated with JDeveloper:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" env:encodingStyle="">
<env:Header>
<ReplyTo xmlns="http://schemas.xmlsoap.org/ws/2003/03/addressing">
<Address>http://localhost:3333/my/j2ee/servlet</Address>
<PortType xmlns:ptns="http://xmlns.oracle.com/AsynchDummy">ptns:AsynchDummyCallback</PortType>
<ServiceName xmlns:snns="http://xmlns.oracle.com/AsynchDummy">snns:AsynchDummyCallbackService</ServiceName>
</ReplyTo>
<MessageID xmlns="http://schemas.xmlsoap.org/ws/2003/03/addressing" ans1:rootId="610005" xmlns:ans1="http://schemas.oracle.com/bpel" ans1:parentId="160005" ans1:priority="0">ABC123</MessageID>
</env:Header>
<env:Body>
<AsynchDummyProcessRequest xmlns="http://xmlns.oracle.com/AsynchDummy">
<input>this is the request</input>
</AsynchDummyProcessRequest>
</env:Body>
</env:Envelope>
Don't forget to set the SOAPAction HTTP header to "initiate" (including the quotation marks).
You can expect a similar message from the callback client step of the BPEL process:
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:add="http://schemas.xmlsoap.org/ws/2003/03/addressing" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<add:RelatesTo>ABC123</add:RelatesTo>
<add:MessageID ans1:rootId="" ans1:parentId="" ans1:priority="0" xmlns:ans1="http://schemas.oracle.com/bpel">ABC456</add:MessageID>
</soap-env:Header>
<soap-env:Body>
<AsynchDummyProcessResponse xmlns="http://xmlns.oracle.com/AsynchDummy">
<result>this is the result</result>
</AsynchDummyProcessResponse>
</soap-env:Body>
</soap-env:Envelope>

Related

How to make SOAP Client for requests/responses in a C program

I have a C program that needs to send continuous requests and receive responses from a SOAP Server.
Shall I wrap the C program to in a C++ class and perform C# interface?
Or is there a way to code a C SOAP Client directly?
I have a custom HTTP headers to be included in the request.
Here is an example test from the SOAP Server documentation on how to call it but I can't figure out how to integrate it to my C program:
POST /otd HTTP/1.1
User-Agent: OT
Host: localhost:9002
Content-Length: 196
Connection: Close
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<doSome/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

SOAP Web Service Auth Headers issue

I am currently trying to use a web service from a Flex client, and hitting a small issue. The service reads a SOAP header called 'AuthHeader' for credentials, and it works from a test client (using Storm from CodePlex) using this request:
<?xml version="1.0" encoding="utf-8"?>
<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:Header>
<AuthHeader xmlns="http://ns.stickykiwi.com/">
<Username />
<Password />
</AuthHeader>
</soap:Header>
<soap:Body>
<Authenticate xmlns="http://ns.stickykiwi.com/" />
</soap:Body>
</soap:Envelope>
The service returns true (Boolean) if the credentials are ok, false if not. Now when I call the service from Flex it sends this:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header>
<ns0:AuthHeader xmlns:ns0="https://stickykiwi01">
<ns0:Password/>
<ns0:Username/>
</ns0:AuthHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<tns:Authenticate xmlns:tns="http://ns.stickykiwi.com/"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This returns,
'System.NullReferenceException: Object reference not set to an instance of an object'
because for some reason, probably best known to someone with better eyesight than me, there is a serious difference between these 2 requests, I am just not seeing it.
So, how do I create the headers in Flex? I have this code in the web service definition file:
var qname:QName = new QName("https://stickykiwi01","AuthHeader");
var header:SOAPHeader = new SOAPHeader(qname,{Username:"",Password:""});
_serviceControl.addHeader(header);
Which is in a file called _Super_AuthenticationServices.as. I pulled the Flex request from the network monitor.
A couple of points to note,
The service isn't mine, but I assume it works as I can test it from another client successfully.
Yes I know SOAP services are now depreciated and we should be moving all our code to WCF, it is in progress and will be brought in house eventually.
We wanted to use Basic auth for the service but Flex doesn't allow me to add the HTTP headers to a SOAP request so that is out.
All of this is run over HTTPS, because I know it is not secure as credentials are passed as plain text, once we have this running we will pass a single hashed string (same as basic auth) and unhash it on the server too, this way is just MUCH easier to debug.
Thank you for your advice.
EDIT
This is what the service is expecting, and I think I am meeting that criteria, I cannot see an issue here at all.
POST /services/_authentication/authenticationservices.asmx HTTP/1.1
Host: stickykiwi01
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://ns.stickykiwi.com/Authenticate"
<?xml version="1.0" encoding="utf-8"?>
<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:Header>
<AuthHeader xmlns="http://ns.stickykiwi.com/">
<Username>string</Username>
<Password>string</Password>
</AuthHeader>
</soap:Header>
<soap:Body>
<Authenticate xmlns="http://ns.stickykiwi.com/" />
</soap:Body>
</soap:Envelope>
No, it works.
Not sure what was going on, but I changed nothing, but this morning the headers are working exactly as expected, here is the request
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header>
<tns:AuthHeader xmlns:tns="http://ns.stickykiwi.com/">
<tns:Username></tns:Username>
<tns:Password></tns:Password>
</tns:AuthHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<tns:Authenticate xmlns:tns="http://ns.stickykiwi.com/"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The only difference I can see is that now the prefix is tns on everything instead of ns0. But anyway, issue resolved, possibly via magic.
Thanks

Call Web Service and Return Error in Delphi 7

I have import a WSDL in Delphi 7 and Call a function on it and an error message will be displayed:
Project Project1.exe raised exception class ERemotableException with message 'Server was unable to process request. ---> Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.'. Process stopped. Use Step or Run to continue.
When I call WebService method (in Delphi 7), with Fiddler software I got the message contents(XML) posted :
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><NS1:Save xmlns:NS1="http://tempuri.org/"><from xsi:type="xsd:string">1</from><to xsi:type="xsd:string">2</to><body xsi:type="xsd:string">ServiceTest</body></NS1:Save></SOAP-ENV:Body></SOAP-ENV:Envelope>
And then I call the same method and web service in Delphi XE5 with no error and this XML content :
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><Save xmlns="http://tempuri.org/"><from>1</from><to>2</to><body>ServiceTest</body></Save></SOAP-ENV:Body></SOAP-ENV:Envelope>
SOAP Server Response :
SOAP Web Service write in .NET framework and support SOAP 1.1 and 1.2
Any ideas?
I have use THTTPRIO.OnBeforeExecute for change SOAPResponse.Then delete unnecessary attribute and type in XML source and packing again and assign it to SOAPResponse and send it.
In this method the problem was solved.

Error in WSO2 ESB when calling service without Header element

I believe I found bug in WSO2 ESB.
I defined proxy service for our customer.
With security turned off I always get expected result, but when I enable security (scenario 1 - UsernameToken), then I get error "SOAP Envelope can not have children other than SOAP Header and Body".
I'm able to reproduce this bug with 'echo' service.
Here is request:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:echo="http://echo.services.core.carbon.wso2.org">
<soap:Body>
<echo:echoString>
<in>ABC</in>
</echo:echoString>
</soap:Body>
</soap:Envelope>
Turning security off or adding <soap:Header /> element before <soap:Body> element provides expected response again.
I'm using WSO2 ESB version 4.8.1, SoapUI 5.0.0 as client.
The SOAP headers contain application specific information related to the SOAP message. They typically contain routing information, authentication information, transaction semantics etc.
If you removed <soapenv:Header/> SoapUI will not send your user name and password to rampart.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org">
<soapenv:Header/>
<soapenv:Body>
<echo:echoString>
<!--Optional:-->
<in>ABC</in>
</echo:echoString>
</soapenv:Body>
</soapenv:Envelope>
So your error was return by org.apache.axiom.soap.SOAPProcessingException due to AxisEngine System error.
When your sending request to secured one header is must..

Move namespace declaration from payload to envelope on an axis created web service

I just created a web service client using axis and eclipse that does not work with my web service provider. The message created by the web service client looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<enviarMensajeRequest
xmlns="http://www.springframework.org/spring-ws/Imk-Zenkiu-Services">
<usuario>someuser</usuario>
<clave>somepassword</clave>
<mensaje>somemessage</mensaje>
<contacto>
<buzonSMS>somenumber</buzonSMS>
<primerNombre>somefirstname</primerNombre>
<primerApellido>somelastname</primerApellido>
</contacto>
</enviarMensajeRequest>
</soapenv:Body>
</soapenv:Envelope>
I see nothing wrong with the message but my provider insists the message should be:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:imk="http://www.springframework.org/spring-ws/Imk-Zenkiu-Services">
<soapenv:Body>
<imk:enviarMensajeRequest>
<imk:usuario>someuser</imk:usuario>
<imk:clave>somepassword</imk:clave>
<imk:mensaje>somemessage</imk:mensaje>
<imk:contacto>
<imk:buzonSMS>somenumber</imk:buzonSMS>
<imk:primerNombre>somefirstname</imk:primerNombre>
<imk:primerApellido>somelastname</imk:primerApellido>
</imk:contacto>
</imk:enviarMensajeRequest>
</soapenv:Body>
</soapenv:Envelope>
Notice the namespace declaration moving from the enviarMensajeRequest to the soapenv:Envelope and the qualification with imk: on the parameters. I've tried many combinations on the process but my web service, wsdl and xml knowledge is very limited. The provider says that they can't help beyond telling me this. Any ideas? Perhaps a different framework that I can use to create the correct client.
Your provider is wrong, the messages are semantically equivalent; yours is unqualified, theirs is qualified. Are you using Axis or Axis2? If you're using Axis, I suggest you switch to Axis2 for a more robust, standards-compliant SOAP stack (both products are bad, but Axis2 is less-bad).
I assume you are creating your client with wsdl2java? If you can't get this tool to generate the message the way you like, then your best bet is to generate the message programmatically.
With Axis2, you can do this with the AXIOM API. See this link for some example API usage. Note that with most of the methods, e.g. createOMElement, you optionally pass the namespace prefix. So, if your provider requires it, then you could pass a String containing "imk" as the namespacePrefix parameter.
If you end up doing this programmatically and you are only going to be writing a simple client, then I STRONGLY suggest you abandon the Axis/Axis2 approach and use the JAX-WS stack instead, as it is part of Java since 1.6. The API is cleaner and the documentation is better. For example, following is a very simple client I wrote to send a SOAP request to our JIRA server. The sample code creates both qualified and unqualified elements.
QName port = new QName(endpoint, "subversionsoapservice-v2");
QName serviceName = new QName(endpoint, "ISubversionSoapServiceService");
Service service = Service.create(serviceName);
service.addPort(port, SOAPBinding.SOAP11HTTP_BINDING, endpoint);
Dispatch<SOAPMessage> dispatch = service.createDispatch(port, SOAPMessage.class, Service.Mode.MESSAGE);
MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
SOAPMessage request = factory.createMessage();
SOAPBody body = request.getSOAPBody();
SOAPElement reindexRepository = body.addChildElement("reindexRepository", "jira", "http://soap.ext.plugin.jira.atlassian.com");
SOAPElement in0 = reindexRepository.addChildElement("in0");
in0.addTextNode("test");
request.saveChanges();
dispatch.invoke(request);
The XML sent by the client looks like this:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<jira:reindexRepository xmlns:jira="http://soap.ext.plugin.jira.atlassian.com">
<in0>test</in0>
</jira:reindexRepository>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>