I am trying to invoke a service/ API asynchronously and I noticed the thread get blocked when I invoke the service which behaves like a synchronous.
How can I call a service/ API asynchronously?
Assuming you are referring to API Manager, all the API invocations are, by default, asynchronous. Once the Gateway receives a request, it passes it to the backend and releases the thread for accepting other requests.
If you are referring to ESB/ Integrator, then you can use the Call mediator to invoke services/ APIs either asynchronously or synchronously. The Call mediator has a properly called, Blocking which can be used to control the mode - asynchronously or synchronously. Blocking set to true means it behaves in synchronous mode.
For more information - https://apim.docs.wso2.com/en/4.0.0/reference/mediators/call-mediator/
This depends on what you are tring to achieve. If you want to do multiple calls at the same time. You can use the Clone Mediator.
<clone xmlns="http://ws.apache.org/ns/synapse">
<target>
<endpoint name="endpoint_urn_uuid_73A47733EB1E6F30812921609540392-849227072">
<default />
</endpoint>
</target>
<target sequence="test1" />
</clone>
Related
I am newbie to WSO2 ESB, so far everything is OK.
I started exploring fire and forgot feature, looks like this can be used as below to invoke async calls to end points.
<property name="CHANNEL_COD" value="999"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="OUT_ONLY" value="true"/>
But when tested the API with above code, still ESB invoking the end point in syncronous. Tried this approach with call and send mediators.
Would anybody please help me is there any link I am missing here.
With ESB 4.8.1 :
If ClientApiNonBlocking property is not set, send mediator should be asynchronous.
Because of FORCE_SC_ACCEPTED, 202 http status code will be sended back at the end of IN mediation (ie : the message has been delivered to your endpoint, without waiting for the response)
If it takes several seconds to send the message to the endpoint, the caller will receive 202 status code AFTER that.
If you want this status code to be sent ASAP, you can use clone mediator and move send mediator inside clone's target
I create and subscribe new APIs through an automated process that uses WSO2 API Manager's Publisher and Store HTTP APIs respectively. I have custom handlers that I then map to my APIs by editing the XML files in <APIM_HOME>/repository/deployment/server/synapse-configs/default/api.
Is there a way to programmatically map the handlers to the newly created APIs so that I don't have to edit the XML manually? In other words, an API or other method to see the current handlers for an API, and add/remove?
I assume you do not want to edit API XML manually for all the APIs to engage a custom handler. Instead, you want to be able to engage a handler to all the APIs automatically when you publish the APIs. You can do it by editing the $APIM_HOME/repository/resources/api_templates/velocity_template.xml. This is the template file which decides which handlers to be engaged with APIs by default. In this file, at the end, you will find a handlers section. You need to edit this file and add your handler there, as shown below.
## print the handlers
#if($handlers.size() > 0)
<handlers xmlns="http://ws.apache.org/ns/synapse">
<handler class="org.wso2.carbon.samples.handlers.MyCustomHandler"/>
#foreach($handler in $handlers)
<handler xmlns="http://ws.apache.org/ns/synapse" class="$handler.className">
#if($handler.hasProperties())
#set ($map = $handler.getProperties() )
#foreach($property in $map.entrySet())
<property name="$!property.key" value="$!property.value"/>
#end
#end
</handler>
#end
</handlers>
#end
As you can see, I have added my handler org.wso2.carbon.samples.handlers.MyCustomHandler. That's it you should do. If you create and publish an API now, MyCustomHandler will be engaged with your API automatically. However, already published APIs won't have an effect even if you update velocity_templates.xml. You need to republish them in order to get the effect.
In my case, I have many handlers and many APIs. Not all handlers apply to all APIs and no handler is applicable to all APIs.
I solved this by creating a standalone HTTP API in a WAR file that I deployed to API Manager's Carbon instance. The same service that calls the WSO2 Publisher API calls my HTTP API afterward. The API takes in handler class names as parameters, and injects the appropriate elements into the API definition XML files on the local filesystem (I used JDOM). API Manager automatically detects and reloads the modified XML and it's good to go.
I'm trying to setup a proxy for my RESTful API using WSO2 API Manager. My problem is that the responses from the backend API are left untouched so all the urls that connect to other endpoints still reference the backend server rather than the proxy. I need a way to replace those url values in the response body to point to the proxied api. I understand this can be accomplished via Mediation Extensions, using ESB Mediators.
I'm not familiar enough with them to pick the one better suited for the job. URLRewrite mediator looks pretty straightforward, but it doesn't seem to apply to the message body but the headers. Payload Factory seems to require a fixed structure for the message, which is not very convenient for me, since I need it to work on the different responses that my API provides (and I wouldn't want to maintain those structures in the mediator definition).
I've managed to solve it by setting the headers my application checks to build its urls:X-Forwarded-Host and X-Forwarded-Proto.
So I've created a Header Mediator that looks like:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="WSO2AM--Ext--In">
<header name="X-Forwarded-Host" expression="get-property('transport','Host')" scope="transport"/>
<header name="X-Forwarded-Proto" value="https" scope="transport"/>
</sequence>
And that did the trick.
As near as I can tell, the WSO2 ESB does not properly handle proxying a service operation that does not return a response message.
Here's the scenario:
We've got a code-first, axis2 generated web service sitting on WSO2 application server 4.1.0.
The java class that the service is based on has some methods like:
public void updateMyObject(MyObject obj) throws MyServiceException
Axis2 generates a WSDL that does not contain a response message, so this is essentially one-way.
NB: An axis2 generated client stub operating against this operation works fine. When invoking the stub in client code, the client blocks until the operation is successfully processed by the server. If an error occurs on the server, then the custom fault is raised and an exception is thrown on the client side.
But, we want to make this invocation via the ESB. Setting up a simple, basic proxy server will not work. When invoking the service via the ESB, the client code blocks indefinitely even though the remote service was successfully invoked.
I read somewhere that this can be fixed by adding the following to my inSequence:
<property action="set" name="OUT_ONLY" value="true"/>
<property action="set" name="FORCE_SC_ACCEPTED" scope="axis2" value="true"/>
This does the trick in the case that the remote service successfully processes the response. The client code no longer blocks.
However, if there is an error processing the request, the client doesn't know. The ESB basically "eats" the error.
This is no doubt because there is no call-back handler registered for the operation because of the OUT_ONLY setting. Search for OUT_ONLY in the link below for more info:
http://techfeast-hiranya.blogspot.ca/2009/12/wso2-esb-tips-tricks-03-transport.html
The FORCE_SC_ACCEPTED setting seems to be the thing that will keep the client from blocking on the success condition, presumably because that forces a 202 http response to the client so it stops waiting for a response.
Since the client operates as it should against the service for both success and error conditions but I am unable to configure a proxy service that yields the same behavior, in my opinion, the ESB is deficient in this way and that is a bug.
Of course, if there is a way I can configure it so that it does what I want, then I'd love to hear it.
But as near as I can tell, I think not registering a call-back is the wrong thing to do here, even if there is no response. I do not wish to implement a fire and forget here. Executions should still happen synchronously from the client side. My client is expecting an HTTP 200 response but with no body for success.
By examining the WSDL, the ESB should realize that the service has no response message but still register a call back. When the 200 OK is received on success, it should propagate this back to the client and unregister the call-back. When a Fault occurs, it should also relay that back to the client.
So, is there a way to accomplish what I want with the ESB or is it deficient in this way?
However, if there is an error processing the request, the client doesn't know. The ESB basically "eats" the error
What is happening to your client if you define a fault sequence for your proxy in this case?
If we register a call-back fro an outonly operation, what will happen is ESB will wait forever for the response and will run out of threads..
In oneway message;
If it is a successcase use these two properties;
<property action="set" name="OUT_ONLY" value="true"/>
<property action="set" name="FORCE_SC_ACCEPTED" scope="axis2" value="true"/>
For a failure case handle that in the fault sequence. I would like to know, what is happens in the fault scenario.
We are using WSO2 ESB 4.0.3 with Data services feature on MAC OSX 10.7.4.
I have proxy service which forwards the message to Data Service. When there is any fault in Data service the fault is returned to calling proxy service in OUTSEQUENCE. Now if there is any error I forward this to common error handler from proxy service which happens in OUTSEQUENCE. This common error handler is another proxy service only.
Now when the Error handling is completed the control returns back to original proxy service which called the error handling proxy service. But what happens is when the control returns to original proxy service from error handler it AGAIN starts executing the OUTSEQUENCE of proxy service.
So for me it is executing the OUTSEQUENCE of proxy service twice in case of fault from Data Service.
Is it standard behavior? I used to Java kind of executing where when the call from method returns it starts executing the next line. But here looks like it again starts executing the OUTSEQUENCE from beginning.
To avert executing the OUTSEQUENCE from beginning again I populate the value at "transport" scope in Error hanlder proxy which will used in filter mediator to avoid executing the logic in OUTSEQUENCE twice.
I am trying to find if there are any SOAP headers I can use instead of setting the property. I see no SOAP headers being set like "From" or "ReplyTo" and I believe message co-ordination happens with MessageId. How can we use these SOAP headers instead of property to divert the flow logic.
Please help.
thanks
Abhijit
In this case instead of using send mediator to invoke the web service you can use the call out mediator. Which makes a blocking call to error handling service and returns to the same place.
And also with esb 4.0.3 you can specify the receive sequence at the send mediator level. By default the response is received at the outsequence level.
eg. <send receive="fundTransferSequence">
<endpoint>
<address encoding="UTF-8" statistics="disable"
uri="http://10.1.23.11:8888/EgateValidWS/EgateValidWSSoapHttpPort" >
</address>
</endpoint>
</send>