I am migrating a service that was built to run on WSO2 ESB 4.0 to WSO2 ESB 4.7 and have run into a problem. The service I am migrating is a custom proxy with a SOAP 1.2 binding interface. This proxy makes outbound calls to a SOAP 1.1 based service.
The ESB 4.0 server is using the Http NIO transport and it appears that transport would use a message formatter (I'm guessing) to manage the SOAP message conversion in the ESB between SOAP 1.1 and 1.2 when sending a response message back to the client.
The ESB 4.7 is using the Http PassThrough transport, which does not have the SOAP message conversion capabilities, so SOAP envelope namespaces and HTTP header information has to be changed manually in a sequence.
Is it possible to configure both Http PassThrough and Http NIO to be active on the same ESB and configure individual services to use one or the other? I've tried, and have been unsuccessful, and my research so far seems to indicate one or the other.
EDIT1 - Response to RaviU:
Thanks RaviU. The ESB 4.7.0 will support automatic conversion of SOAP 1.1 to 1.2 if it is configured to use the HTTP NIO transport. In other words, it behaves like the ESB 4.0 server. The automatic conversion of SOAP 1.1 to 1.2 does not appear to occur when the ESB 4.7.0 is configured to use HttpPassThrough transport. This makes sense because that transport does not care about content type. The problem I have when using HttpPassThrough is that I have to manually change the SOAP envelope to 1.2 and set the appropriate http headers before sending back to the client. This is because they are changed when the service calls the SOAP 1.1 service. If I use the HTTP NIO transport, the manual steps are taken care of automatically by the ESB. I'm assuming this is done by a message formatter before the message is returned to the client.
Apologies with the late response. You can fix your conversion issue doing something like:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TestProxy"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<filter xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
source="namespace-uri(/*)"
regex="http://www.w3.org/2003/05/soap-envelope">
<then>
<property name="incomingSOAPVersion" value="soap12"/>
</then>
<else>
<property name="incomingSOAPVersion" value="soap11"/>
</else>
</filter>
<log level="custom">
<property name="SOAP_VERSION_LOG" expression="$ctx:incomingSOAPVersion"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:8280/services/echo.echoHttpSoap11Endpoint"
format="soap11"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<filter source="$ctx:incomingSOAPVersion" regex="soap11">
<then>
<send>
<endpoint>
<default format="soap11"/>
</endpoint>
</send>
</then>
<else>
<send>
<endpoint>
<default format="soap12"/>
</endpoint>
</send>
</else>
</filter>
</outSequence>
</target>
<publishWSDL uri="http://localhost:8280/services/echo?wsdl"/>
<description/>
</proxy>
You can also set the messageType instead of using default endpoint. This is also a possible solution:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="soapVersion">
<filter xmlns:ns="http://org.apache.synapse/xsd" source="$axis2:messageType" regex="application\/soap\+xml">
<then>
<property name="incomingSOAPVersion" value="soap12"/>
</then>
<else>
<property name="incomingSOAPVersion" value="soap11"/>
</else>
</filter>
</sequence>
Either should work, but the second solution should be slightly better performing since it does not evaluate xPath.
Related
Use Case: I recently came upon a problem while creating an integration in WSO2 Integration Studio,
I have an API with 2 resources, one is a POST, the other is a GET
Problem: when I run the integration to test it, the POST request works fine while the GET request gives me the code 202 accepted without even calling the endpoint
Code: this is my code, in the second sequence the log is printed alright but the call isn't executed
<api context="/flow" name="companyflow" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/createIssues">
<inSequence>
<call>
<endpoint key="IssueEndpoint"/>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
<resource methods="GET" uri-mapping="/getIssues">
<inSequence>
<log>
<property name="text" value="HelloThere"/>
</log>
<call>
<endpoint key="issuesList"/>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Tip:: I suspect the problem may be related to uri-template and uri-mapping but I'm not sure
There is no issue with your integration configurations or syntax. Normally you get a 202 when you have an error in the flow. So I'm suspecting your Endpoint reference is wrong. Double check whether the key is correct and the endpoint is deployed to MI. (Make sure it's selected in the Capp pom file)
<call>
<endpoint key="issuesList"/>
</call>
In wso2 ESB after calling an endpoint I am getting the response as number(ex: 78) with header application/json, if without processing the response if i send in out sequence it works fine i'll get the same response. But if I include any mediators for processing in between it'll throw exceptions like Could not save JSON payload. Invalid input stream found. A single string or number is not valid in some cases So, it may throwing the exception but this bug is resolved in wso2 EI 6.2.
So now I am able to process the response but if I use script mediator to get that value it shows {}. If i use json-eval($.) then also i am not able to get the value, also with xpath i am not able to get.
So how to get that response(the value in number) for further processing in wso2 ei, by using script mediator or by using json path.
If you are certain that the response only contains a number with the content-type header with application/json. you can take the value to a property as below.
<property name="RESPONSE_NUMBER" expression="//jsonValue" scope="default" type="INTEGER"/>
When you need this value somewhere else in the mediation flow you can take the value from the property(in this case RESPONSE_NUMBER) as below.
$ctx:RESPONSE_NUMBER
Here is a sample API which demonstrates how you can take the response value and use it in the mediation flow.
<api xmlns="http://ws.apache.org/ns/synapse" name="SampleAPI" context="/getNumber">
<resource methods="GET">
<inSequence>
<send>
<endpoint>
<http method="GET" uri-template="http://www.mocky.io/v2/5b02cc2c3000006600cee384"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<property name="RESPONSE_NUMBER" expression="//jsonValue" scope="default" type="INTEGER"/>
<payloadFactory media-type="json">
<format>{"Id": $1}</format>
<args>
<arg evaluator="xml" expression="$ctx:RESPONSE_NUMBER"/>
</args>
</payloadFactory>
<send/>
</outSequence>
</resource>
</api>
You can call the API with below curl command:
curl -v http://localhost:8280/getNumber
When I create proxy with send mediator with Rest service Post HTTP Method in HTTP endpoint url. Selected the endpoint as HTTP endpoint on proxy and post the request xml without soap envelop, this perfectly works and get the response in the response window.
But when I use the call mediator with the same HTTP end point url configuration, this does not works. I would like to know can we use call mediator for Post HTTP method? When I use Call mediator for the GET HTTP method which require only query parameters and does not require any request xml this works absolutely fine.
Here is the further information:
However issue is resloved by using the address endpoint in callmediator. When I Invoke the proxy from external Restt client ot Soap UI, it does works. If I use the Try this Service option in wso2 ESB will fail with the results 1. When Soap12 endpoint is selected and 2 when HTTP end point is selected as shown below.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="postIDMPCall"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<property name="ContentType" value="text/xml" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<organizationList xmlns="">
<xml content>
</organizationList>
</format>
<args/>
</payloadFactory>
<header name="_user" scope="transport" value="username"/>
<header name="_password" scope="transport" value="Password"/>
<call blocking="true">
<endpoint>
<address uri="http://<ip-address>:<port>/<resource-path>/UpdateOrganization"
format="rest"/>
</endpoint>
</call>
</inSequence>
</target>
</proxy>
Output: When soap12 endpoint is selected
Though posted the correct xml service does not recorgonize the correct xml format for soap12 endpoint.
FAILURE
Record is not processed successfully. Please Provide valid Request XML
When Http end point is selected
[2016-04-21 12:07:50,179] INFO - HTTPSender Unable to sendViaPost to url[http://://UpdateOrganization/mediate]
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
I think we can't use call mediator for this purpose because call mediator is context unaware mediator.
Your call should already perform a post out the box.
Did you try to set format="pox" if you expect simple xml as a response
I have to mapping query params to send request to endpoint in API resource in WSO2 ESB.
Those query params are optional. For example, the following are examples of calls to resource:
http://server:port/service?q1={q1}
http://server:port/service?q2={q2}&q3={q3}
I need to have a single resource to do this.
How can I do this?
Basically, I have to read query params in request and put it in the call to endpoint uri.
You can have dynamic URIs using url-mapping attribute.
Here is an example:
<api xmlns="http://ws.apache.org/ns/synapse" name="test_api" context="/testService">
<resource methods="GET" url-mapping="/*">
<inSequence>
<log level="full">
<property name="paramQ1" expression="$ctx:query.param.q1"></property>
<property name="paramQ2" expression="$ctx:query.param.q2"></property>
<property name="paramQ3" expression="$ctx:query.param.q3"></property>
</log>
<send>
<endpoint>
<address uri="http://localhost:9766/services/"></address>
</endpoint>
</send>
</inSequence>
<outSequence>
<send></send>
</outSequence>
</resource>
</api>
To validate the presence of those query params its possible to use Filter Mediator. A good example of it can be found here.
Hope it helps.
I am trying to access external web services (outside of intranet) using WSO2 ESB 4.0.3 but I do not know how to configure the proxy to let the request go outside. I can send SOAP messages over HTTP from my basic Java client app without issues; I could specify teh proxy details using Apache HttpComponents. So, connection details are OK.
I tried:
Editing <transportSender name="http" ... > and specifying parameters like "http.proxyHost" and "http.proxyPort".
Setting up a global parameter <parameter name="Proxy"> ...
Configuring the HTTP Transport Sender and specifying the appropriate parameters.
The best I got was:
ERROR_CODE = 101503, ERROR_MESSAGE = Connection refused or failed for : ...
So, what did I wrong and what should I do instead? Thanks.
Does your proxy server has any authentication? If yes and it uses Basic Auth you need to specify followoing properties before sending out the request..
<property name="Proxy-Authorization" expression="fn:concat('Basic', base64Encode('userName:password'))" scope="transport"/>
<property name="POST_TO_URI" value="true" scope="axis2"/>
The first property sets the Proxy-Authorization HTTP transport header with the base64 encoded user name and password as expected by the HTTP basic authentication.
The second property makes the out-going URL a complete URL understandable by the Proxy Server.
Following is an example proxy config...
<proxy name="StockQuoteProxy" startOnLoad="true">
<target>
<inSequence>
<property name="Proxy-Authorization" expression="fn:concat('Basic ', base64Encode('udayanga:test123'))" scope="transport"/>
<property name="POST_TO_URI" value="true" scope="axis2"/>
<send>
<endpoint>
<address uri="http://www.wso2.com:9000/services/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>