Failover configuration in wso2 esb - esb

We have a proxy service that does the following
1. calls a backend service to get the client id
2. use the endpoint (client endpoint) configured for that client id and forward the original request to that endpoint.
3. return a response to the request
Earlier we were setting OUT_ONLY property to true while forwarding the request to the client endpoint (step 2).
But we now have to use a failover endpoint configuration for the client endpoint. So we removed the OUT_ONLY property and used
the following failover configuration. The client endpoint does not return any response for the forwarded requests.
Due to this the callback that gets registered does not get any response and it gets cleared by the Timeouthandler subsequently.
Recently we are facing some CPU spikes and OutOfMemory errors getting thrown by ESB.
We suspect that the synapse callback handler is utilizing most of the system resources and unable to recover.
Could this configuration create any OutOfMemory errors (if stress tested) as there is no response returned by the client endpoint?
Please suggest.
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="client_forward_endpoint_110">
<failover>
<endpoint name="primary">
<address uri="--primary endpoint--">
<enableAddressing />
<timeout>
<duration>30</duration>
<action>discard</action>
</timeout>
<markForSuspension>
<errorCodes>101504, 101505, 101500</errorCodes>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1</retryDelay>
</markForSuspension>
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2</progressionFactor>
<maximumDuration>64000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
<endpoint name="secondary">
<address uri="--secondary endpoint--">
<enableAddressing />
<timeout>
<duration>30</duration>
<action>discard</action>
</timeout>
<markForSuspension>
<errorCodes>101504, 101505, 101500</errorCodes>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1</retryDelay>
</markForSuspension>
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2</progressionFactor>
<maximumDuration>64000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</failover>

If your endpoint doesn't return any response, how can you tell if it is active?
If there is any kind of response from the endpoint to any kind of request, you may be able to do a more complicated mediation using first a 'call' mediator to check endpoint availability, then a send mediator with the OUT_ONLY property. You may use a switch mediator for evaluating the result of the 'call' mediator, and set a very short timeout for that mediator to make the throughput acceptable even if the first endpoint is inaccessible. It would not be an ideal solution, but it should work.

Related

How to host and transform SOAP message in WSO2

I am relative new in WSO2 to create services, and i have to do a project in the enterprise where i work. First i had to take a message in, for example, json and send xml. I was able to do so, with this code:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/Test" name="JsonToXmlApi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/xml/">
<inSequence>
<property name="messageType" scope="axis2" type="STRING" value="text/xml"/>
<header action="remove" name="To" scope="default"/>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<send/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Now i need to do the following, i have to send a message in SOAP, XML format, consume it in SOAP and receive back with JSON or XML format.
Someone could help me? I am asking because i am searching for tutorials, for beginners, about it for more than a week, and wasn't able to solve my problem.
Another question, would be possible to do this in REST API project?
If someone could help me, with a detailed tutorial or good video teaching that, i would be grateful.
Thank you.
Your post is a bit unclear but I will try to summarise the typical common combinations of input interface, wso2 component and backend services when you are developing web services.
Web services are services you can invoke over http or https - you might have three types of interfaces for these and you might use two types of WSO2 ESB components - proxy and API - to develop these.
1) Input/Output: JSON
WSO2 component: API
Backend: Any (JSon/XML/SOAP)
2) Input/Output: Plain XML
WSO2 component: API
Backend: Any (JSon/XML/SOAP)
3) Input/Output: SOAP
WSO2 component: Proxy
Backend: Any (JSon/XML/SOAP)
One of the key components of any SOAP service is the WSDL - the WSO2 proxy allows you to publish a WSDL so that your caller knows what sort of data and operations your service provides.
See more here: https://docs.wso2.com/display/EI611/Working+with+Proxy+Services
Adding this note only because you asked:
Technically, you might be able to receive a SOAP message in an API component because SOAP is just an XML document - but it would be really pointless. The purpose of the API component is to expose resources and allow you to perform HTTP operations (GET, POST etc) on those resources (this model can be called REST).
The purpose of a SOAP based web service is to expose data and operations as defined in a WSDL and the WSO2 proxy component is what allows you to do that.

Mule - How to respond after receiving a request collection. (Mule Requester )

I am using the Mule Requestor to receive a collection of files via FTP.
In order to do this with a collection I am using the Collection Splitter which works great. The only problem is that when I am returning to the HTTP Connector it throws the following exception:
java.lang.UnsupportedOperationException: getPayloadAsBytes(), use
getPayload(DataType.BYTE_ARRAY_DATA_TYPE)
I am guessing this has something to do with the payload type that is trying to be inserted into the response, but I am fairly new in the Mule arena. Any idea what could be causing this and what I should do to resolve the issue?
I have tried setting the payload after the logger, that didn't work.
Code:
<flow name="fileGetter">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP" allowedMethods="GET"></http:listener>
<mulerequester:request-collection config-ref="Mule_Requester" resource="ftp_For_Requester_Dependent" doc:name="Mule Requester</mulerequester:request-collection>
<collection-splitter doc:name="Collection Splitter"></collection-splitter>
<logger level="INFO" doc:name="Logger" message="#[message.inboundProperties.originalFilename]"></logger>
</flow>
The reason you are getting java.lang.UnsupportedOperationException: getPayloadAsBytes(), use getPayload(DataType.BYTE_ARRAY_DATA_TYPE) is obvious, since you are splitting the payload, at the end your HTTP in causing the issue as there will be a split response .
One solution would be, use an aggregator at the end of your flow and that will prevent this exception.
A <collection-aggregator/> at the end will be a good choice and help to prevent this
UPDATE
Keep it under <async> block and it will run successfully

Coldfusion SOAP Exception Error Handling

How can I customize a SOAP error message in ColdFusion? Most languages like PHP, Java, .NET etc. have this capability. While I've seen this question asked on other sites, none of the threads contained an answer. If this isn't possible, I think Adobe should add a patch to support this feature.
Here is an example of the SOAP error in ColdFusion:
SOAP Request:
<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/">
<soapenv:Header/>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>
SOAP Response:
<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>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>java.lang.Exception: Body not found.</faultstring>
<detail>
<ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/">java.lang.Exception: Body not found.
at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:121)
...</ns1:stackTrace>
<ns2:hostname xmlns:ns2="http://xml.apache.org/axis/">Coldfusion Error</ns2:hostname>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
In other languages you can customize the error message like so:
SOAP Response:
<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>
<soapenv:Fault>
<faultcode>BODY_NOT_FOUND</faultcode>
<faultstring>Body is missing in your request</faultstring>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
But I haven't found a way to achieve this in ColdFusion. We are planning to upgrade to ColdFusion 11. Does ColdFusion 11 (or below) have a way to do this?
I would need to know how the application is generating and receiving requests to begin with. With ColdFusion, to create a request, you would start by creating the SOAP Packet you want to send:
<cfsavecontent variable = "variable name">
<XML></XML>
</cfsavecontent>
Next, use CFHTTP to send your SOAP request out:
https://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7ffc.html
When your response comes back and you have assigned it to a variable (set up in your CFHTTP request) you can use this response variable to determine how to parse the response. So for example, you might use XMLParse or XMLSearch to find the elements and process them.
See:
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-by-category/xml-functions.html
Note that special configuration might be required if network protocols are to be observed - for instance, SSLv3/TLS. Consult your network administrator to determine if any configuration of ColdFusion needs to be done to support network architecture. Also validate that your endpoints can see each other through any firewalls. For more connection information consult either the ColdFusion documentation or threads relevant to your situation such as:
Does cfhttp for coldfusion 10 only supports up to TLS 1.0?

Terminating send mediator with mailto transport wso2 esb

There are numerous examples of using the mailto transport in WSO2 ESB to send emails (based on filter mediator, fault sequence etc.). However, I have attempted this a number of ways all with the same result i.e. that the proxy service never terminates. I am testing this using SOAPUi.
This is my proxy service
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TMCService" transports="https,http" statistics="enable" trace="enable" startOnLoad="true">
<target inSequence="gov:/trunk/sequences/seqGetTMCData">
<outSequence>
<filter xmlns:trac="http://mynamespaceuri" xpath="//trac:SaveIncidentsResponse">
<then>
<log level="full"/>
<property name="Subject" value="CEP Event" scope="transport"/>
<property name="OUT_ONLY" value="true"/>
<send>
<endpoint>
<address uri="mailto:conrad.crampton#gmail.com"/>
</endpoint>
</send>
</then>
<else>
<send/>
</else>
</filter>
</outSequence>
</target>
<description></description>
</proxy>
the email sends no problem with the response from the inSequence - no problem, it just never terminates. I have to manually stop it in SOAPUi to stop.
I've tried putting drop after the send in the then element, that doesn't work either.
I guess I am missing something fundamental in how I am understanding the out sequence to work, but this is pretty much lifted from the many examples out there and no one else appears to be having the same issue as me.
Any suggestions/ pointers??
WSO2 ESB v4.5.1
I have resolved this by cloning the response message, sending one to the mailto transport and sending the other one as a default send (no endpoint) which returns back to the client.
Kind of makes sense as the OUT_ONLY property is explicitly saying there will be no response, so have ensure that the client receives one by cloning the message.
Still welcome any other comments if there is another way of doing this without clone mediator.
So why doesn't the examples show this!

WSO2 ESB service orchestration

Hello WSO2 community and hello Stackoverflow,
my testing of the SOA suite starting from the ESB is going good: now the ESB recognises external services, create correct proxies that return correct results.
SOLVED
About that, I have two issues: the first is that the "try it"
functionality raises the exception:
"Cannot find dispatch method for {http://schemas.xmlsoap.org/soap/envelope/}Envelope
[tagOpened]/soapenv:Text[tagClosed]"
when i try to send a SOAP enveloped created for the mock service of
the web service proxied.
Anyway, if I try the proxy service from an external client (created on
Netbeans) it works great.
ANSWER
For the first part, the reason is most probably the cross domain issue as try-it is sending messages through a java script stub from
the browser. You will notice that this works great when the service
itself is hosted in the ESB itself, because the request passes through
the same domain. This is why, although, it works perfectly through a
normal client invocation, it does not work through try-it.
The second issue is that I'm not able to orchestrate two services. My objective is sending the input of the first service to the second service, and then to the user.
I'm working on the tutorial Tharindu Mathew suggested: everything now makes sense to me except on one thing: the XSLT transformation.
Here is the out sequence the tutorial suggests you to create:
<outSequence xmlns="http://ws.apache.org/ns/synapse">
<switch source="get-property('STATE')">
<case regex="PERSON_INFO_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - response from PersonInfoService" />
</log>
<xslt key="xslt">
<property name="amount" expression="get-property('ORG_AMOUNT')" />
</xslt>
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - request for CreditService" />
</log>
<property name="STATE" value="CREDIT_REQUEST" />
<send>
<endpoint key="CreditEpr" />
</send>
</case>
<case regex="CREDIT_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 02 - response from CreditService" />
</log>
<send />
</case>
</switch>
</outSequence>
Now, focusing on the XSLT node of the first case of the switch, you can see that there's just a get for the amount property.
So that I think we have an XML from the in sequence that states the ID, and this get on the amount property (and I don't know what it does).
The tutorial then suggests:
To create the request to this CrediService, we use the following XSLT with the XSLT mediator. Note, we are using the ORG_ID that we stored in this XSLT as a XSLT parameter and using the XSLT mediator as well.
And here is the XSLT showed in the tutorial:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:ns="http://samples.esb.wso2.org"
xmlns:ax21="http://samples.esb.wso2.org/xsd"
exclude-result-prefixes="ns fn">
<xsl:param name="amount"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//ns:getResponse" />
</xsl:template>
<xsl:template match="ns:getResponse" xmlns:ns="http://samples.esb.wso2.org">
<sam:credit xmlns:sam="http://samples.esb.wso2.org" xmlns:xsd="http://samples.esb.wso2.org/xsd">
<sam:info>
<xsd:amount><xsl:value-of select="$amount"/></xsd:amount>
<xsd:personInfo>
<xsd:address><xsl:value-of select="ns:return/ax21:address"/></xsd:address>
<xsd:id><xsl:value-of select="ns:return/ax21:id"/></xsd:id>
<xsd:name><xsl:value-of select="ns:return/ax21:name"/></xsd:name>
</xsd:personInfo>
</sam:info>
</sam:credit>
</xsl:template>
</xsl:stylesheet>
I was asked to put a similar file into the resources directory of WSO2 ESB, but this file is never used in the tutorial:
Copy the personToCredit.xslt in the sample zip to resources directory of WSO2 ESB.
---------LITTLE PARENTHESIS-----------
The WSDL file was not used either after it was stated:
Copy the CreditProxy.wsdl in the sample zip to the resources directory of the WSO2 ESB.
I cannot find the WSDL file in the Configuration/Governance Registry, and I don't know how to address it, so I chose to specify it inline instead.
---------LITTLE PARENTHESIS END-----------
This sentence is followed by the XSLT file text. My main question now is:
Where should I put this XSLT? I do not know where to put the XSLT mediator, neither how to build it.
Should I rely on registries?
A perfect answer could be the code of the out sequence, and the specified connection with the XSLT mediator suggested.
OverTheBitStair
Hi OverTheBitStair (nice nick!),
For the first part, the reason is most probably the cross domain issue as try-it is sending messages through a java script stub from the browser. You will notice that this works great when the service itself is hosted in the ESB itself, because the request passes through the same domain. This is why, although, it works perfectly through a normal client invocation, it does not work through try-it.
For the second part, the short answer is yes, it is possible. In terms of the ESB, we refer to it as a light-weight orchestration engine in addition to being a mediation engine. This means for light-weight and short-lived (<1 day) processes we can solve the orchestration requirements using the ESB without bringing in the Business Process Server.
To do this, we use this method called service chaining. What it does is introduce a method to get some output out of the initial service invocation and use it in a subsequent invocation. The article WSO2 ESB by example - Service Chaining should help you with implementation details on what you are looking for.
Hope this helps.
If you create a service chaining scenario where your proxy service calls two other services and return the result to the caller of the proxy service, it would look something like this:
Caller --> Proxy Service -- seq_A --> Service1 -- seq_B --> Service2 -- seq_C --> (proxy serviced response) --> Caller
In this case, seq_A would be the in sequence of the proxy service, seq_C the out sequence of the proxy service and seq_B another named sequence.
Input, i.e. the message body, to seq_A would be the input to proxy service. seq_A would contain a send mediator at the end and at that point in the sequence the message context would be the input to Service1. The send mediator also points to seq_B to be executed for the reply.
At start of seq_B the message body contains the output from Service1. If you want to keep some message data from before the service call you need to save that in properties in the context.
At the end of seq_B you would have a send mediator; at that point the message body should contain the input to Service2, The send mediator would in this case not need to point to an explicit reply sequence, if seq_C is the out sequence of the proxy service - that one will be used by default then.
When seq_C is executing the message body at that point is the response from Service2. Again, if you need to use/combine with some data prior to the call to Service2, you need that to be saved into properties.
Depending on the particular needs for the input and transformations needed at each step it can be fairly straightforward or a bit cumbersome to handle.
What also should taken into consideration is what needs to happen in error scenarios, as this may add some additional complexity, depending on the requirements.