How to handle endpoint failure in wso2esb and wso2dss - wso2

I created proxy services using wso2dss for data insertion, so services working fine I am quite happy with this. But while any data duplication errors occurred in wso2dss I need to handle it in wso2esb so I kept this property in wso2esb for dss level error handle:
<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
So its working fine I am getting 50000 code using this I am able to handle error while this error my esb showing this message:
[2014-03-07 11:22:40,778] INFO - LogMediator To: /services/GeoLocationInsertion, MessageID: urn:uuid:b51629e2-934e-4227-8f50-65fd9f719b8e, Direction: request, userid = -1212807836, username = sa|214057357158656, password = sa
[2014-03-07 11:22:40,783] INFO - LogMediator To: /services/ServiceLogin, MessageID: urn:uuid:1967bde1-d820-46f9-957d-55fbb6f7ea9e, Direction: request, usercode = sa, clientid = 214057357158656
[2014-03-07 11:22:40,833] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:24aea5ed-f4e2-4214-809b-b3101031edf7, Direction: response, faisal = true
[2014-03-07 11:22:40,838] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:42a17360-cd04-43bc-83ef-1f53b639de11, Direction: response, kk = true
[2014-03-07 11:22:40,853] WARN - EndpointContext Endpoint : endpoint_71f1485e740c2b97ec407fe4d3bf86929122480f208b6642 will be marked SUSPENDED as it failed
[2014-03-07 11:22:40,853] WARN - EndpointContext Suspending endpoint : endpoint_71f1485e740c2b97ec407fe4d3bf86929122480f208b6642 - last suspend duration was : 30000ms and current suspend duration is : 30000ms - Next retry after : Fri Mar 07 11:23:10 IST 2014
[2014-03-07 11:22:40,856] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:42a17360-cd04-43bc-83ef-1f53b639de11, Direction: response, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 500000, ERROR_MESSAGE = null
[2014-03-07 11:22:40,857] INFO - LogMediator To: , WSAction: , SOAPAction: , MessageID: urn:uuid:42a17360-cd04-43bc-83ef-1f53b639de11, Direction: response, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ResponseJSON><Body><Data><Exception>duplicate key value violates or The system is attempting to access an inactive service </Exception></Data></Body><Status>500000</Status></ResponseJSON></soapenv:Body></soapenv:Envelope>
Above error message means my endpoint gone into suspend mode after 30sec it will automatically in active mode.
If any user tries on the same time he is unable to insert his correct data and he is losing the data due to endpoint nonavailability. So how we can keep endpoint in active mode?
If any other error will come this issue is not raising:
[2014-03-07 11:22:40,853] WARN - EndpointContext Suspending endpoint : endpoint_71f1485e740c2b97ec407fe4d3bf86929122480f208b6642 - last suspend duration was : 30000ms and current suspend duration is : 30000ms - Next retry after : Fri Mar 07 11:23:10 IST 2014
So how would I do this?
If I remove the property I am unable to handle DSS level message and I am getting error like this even my user not getting any response:
[2014-03-07 11:20:51,816] ERROR - NativeWorkerPool Uncaught exception
java.lang.ClassCastException: org.apache.axiom.om.impl.llom.OMElementImpl cannot be cast to org.apache.axiom.soap.SOAPFault
at org.apache.axiom.soap.impl.llom.SOAPBodyImpl.getFault(SOAPBodyImpl.java:120)
at org.apache.synapse.util.POXUtils.convertSOAPFaultToPOX(POXUtils.java:46)
at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:91)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:308)
at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:92)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:71)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:114)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:232)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:443)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:166)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:222)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:679)
So that 30sec are so important, it causes my client's data loss. How could I avoid this endpoint failure?
The actual error in wso2dss is:
Nested Exception:-
org.postgresql.util.PSQLException: ERROR: column "deviceid" is of type bigint but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 81
at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.execute(DSOMDataSource.java:105)
at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.serialize(DSOMDataSource.java:110)
at org.wso2.carbon.dataservices.core.engine.DSOMDataSource.getReader(DSOMDataSource.java:116)
at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.getDirectReader(OMSourcedElementImpl.java:225)
... 41 more
I handle it in wso2esb fault and working fine also but endpoint failure is uncatchble

If you want to configure your DSS endpoint's suspension behavior in the ESB, please refer to the Endpoint Error Handling documentation.
If you drop the FORCE_ERROR_ON_SOAP_FAULT property, you should still be able to handle a soap fault from your DSS response in the out sequence of an ESB proxy.

yo can disable that config with this configuration in your endpoint:
<?xml version="1.0"?>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService">
<timeout>
<duration>30000</duration>
<responseAction>fault</responseAction>
</timeout>
<suspendOnFailure>
<errorCodes>-1</errorCodes>
<initialDuration>0</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<errorCodes>-1</errorCodes>
</markForSuspension>
</address>
</endpoint>

I came up with this error myself and it was terrible to identify it and find a way to work with it. It seems there is a bug in older versions of WSO2 ESB (we have this problem with version 4.8.1) when dealing with a returned soap fault.
You can see the answer of #JorgeInfanteOsorio to disable the endpoint suspension, but you will need an workaround for the "Uncaught exception" issue. What I found is that it is possible to retrieve the parameters from the fault message and then "clear" the current payload, so any subsequent calls wont return the exception issue.
Example:
<!--
After we call a webservice on DSS or other webservice we check if the message contains a fault message
-->
<property xmlns:s="http://www.w3.org/2003/05/soap-envelope"
name="return_fault"
expression="/s:Envelope/s:Body/s:Fault"/>
<filter source="boolean(get-property('return_payzen_fault'))" regex="true">
<then>
<!--
There is a fault message on the payload...
-->
<!--
Retrieve the information from the fault message. How you will access it and which information you will retrieve may be different depending if the answer comes from a third part webservice or from your own DSS.
-->
<property xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" name="code" expression="/s:Envelope/s:Body/s:Fault/s:Code/s:faultcode"/>
<property xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" name="code" expression="/s:Envelope/s:Body/s:Fault/s:Code/s:faultstring"/>
<!--
Clear the payload containing the fault message
-->
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body/>
</soapenv:Envelope>
</format>
<args/>
</payloadFactory>
<!--
Now you can proceed and process the message as usual without getting the exception. You may probably use the parameters stored in the properties at the beginning to determine which error occured and what you are going to do next.
-->
</then>
</filter>
<!--
There is no fault message, you can proceed with the message processing here.
-->

Related

capturing endpoint timeout in WSO2 EI 6.2

I have an API in EI 6.2 that calls a backend endpoint. Sometimes this EP is offline, and therefore the call timeouts. I want to capture this timeout and encapsulate it in a customized response before sending it back to the client. The idea seems simple enough, but I'm having a hard time implementing it.
I've tried adding the following section to the EP declaration. As I understand it, the action=fault property should make the EP raise a fault when the request timeouts (and therefore be caught by the fault handler sequence) but that is not happening. Anyone has any suggestion on how to handle this situation?
Thanks.
Pedro
My EP:
<?xml version="1.0" encoding="UTF-8"?>
<endpoint name="wacs_parameters.endpoint" xmlns="http://ws.apache.org/ns/synapse">
<loadbalance algorithm="org.apache.synapse.endpoints.algorithms.RoundRobin">
<endpoint name="WACS_CpeGm_Parameters_Master">
<http method="GET" uri-template="http://xpto
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1.0</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
<timeout>
<duration>3000</duration>
<action>fault</action>
</timeout>
</http>
</endpoint>
</loadbalance>
<description/>
</endpoint>
And this is the log from the request, edited for clarity:
[2020-02-26 16:38:33,962] [EI-Core] WARN - TimeoutHandler Expiring message ID : urn:uuid:8b9c9632-ef0b-423d-9827-84eee517b75d; dropping message after ENDPOINT_TIMEOUT of : 3 seconds for Endpoint [WACS_CpeGm_Parameters_Master], URI : xpto, Received through API : ClientEquipmentsAPI
[2020-02-26 16:38:41,318] [EI-Core] WARN - ConnectCallback Connection refused or failed for : /10.217.49.10:8280
[2020-02-26 16:38:41,318] [EI-Core] WARN - SynapseCallbackReceiver Synapse received a response for the request with message Id : urn:uuid:8b9c9632-ef0b-423d-9827-84eee517b75d But a callback is not registered (anymore) to process this response
[2020-02-26 16:40:33,967] [EI-Core] WARN - TimeoutHandler Expiring message ID : urn:uuid:2a928d56-cf7f-4950-a5f4-8033798e205e; dropping message after GLOBAL_TIMEOUT of : 120 seconds for Endpoint [API_ClientEquipments_Endpoint_Master], URI : xpto, Received through API : ClientEquipmentsAPI
[2020-02-26 16:41:20,394] [EI-Core] INFO - SourceHandler Writer null when calling informWriterError
[2020-02-26 16:41:20,394] [EI-Core] WARN - SourceHandler Connection time out after request is read: http-incoming-10 Socket Timeout : 180000 Remote Address : /127.0.0.1:53092
[2020-02-26 16:41:20,408] [EI-Core] INFO - SourceHandler Writer null when calling informWriterError
[2020-02-26 16:41:20,408] [EI-Core] WARN - TargetHandler Connection time out after while in state : REQUEST_DONE Socket Timeout : 180000 Remote Address : localhost/127.0.0.1:8280
[2020-02-26 16:41:20,408] [EI-Core] WARN - SourceHandler Connection time out after request is read: http-incoming-11 Socket Timeout : 180000 Remote Address : /127.0.0.1:53093
[2020-02-26 16:41:20,409] [EI-Core] WARN - SynapseCallbackReceiver Synapse received a response for the request with message Id : urn:uuid:2a928d56-cf7f-4950-a5f4-8033798e205e But a callback is not registered (anymore) to process this response
So, just to inform others that might have the same problem: when an endpoint timeouts, EI activate the fault sequence. There you can catch the fault and treat it properly. The property ERROR_MESSAGE details the kind of error, as explained here
https://docs.wso2.com/display/EI640/Error+Handling
This example sequence catches timeouts and returns a customized error code (with HTTP 502):
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="faultSequence_ClientEquipmentsAPI" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<switch source="get-property('ERROR_CODE')">
<case regex="101503|101504">
<call-template target="faultTemplate_clientEquipmentsAPI">
<with-param name="res_messageCode" value="801"/>
<with-param name="res_message" value="Timeout waiting answer of backend system"/>
</call-template>
<property name="HTTP_SC" scope="axis2" type="STRING" value="502"/>
<respond/>
</case>
</switch>
</sequence>

WSO2 Api Manager log Http request in log mediator

Is there a way to include the http request remote host in the log mediator being used for a specific api?
Having followed the instructions, i can log the soap message, but i have no info regarding the caller of the service.
I currently use the following sequence definition:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="WSO2AM--Ext--In">
<log level="full">
<property name="TRACE" value="Gunet Mediation Extension"/>
</log>
</sequence>
And the result i get when having a call is the following:
INFO - LogMediator To: /SmartSearch/1, WSAction: urn:SearchStudentStatus, SOAPAction: urn:SearchStudentStatus, MessageID: urn:uuid:36f9a5cd-c8cb-4e1e-97a6-f3ebd3303589, Direction: request, TRACE = Gunet Mediation Extension, Envelope: <?xml version='1.0' encoding='utf-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><SearchStudentStatus xmlns="gunet.gr"><SSN>12312312312</SSN><institution>aueb</institution></SearchStudentStatus></S:Body></S:Envelope>
I would like to have information about the remote host that made the specific call. Is that possible, using the log mediator, or should i use a combination of log4j configs?
Thanks!
You can get the remote IP which call the API using following property mediator.
<log level="full">
<property name="Actual Remote Address" expression="get-property('axis2','REMOTE_ADDR')"/>
</log>

WSO2: using a property to save the current message

I'm a WSO2 newbie, so sorry in advance if my answer seems a stupid one ...
In a sequence I've the following code ....
<property name="InitialMessage" expression="$body" scope="operation" type="STRING"/>
<log level="full">
<property name="INITIAL MESSAGE" expression="get-property('InitialMessage')"/>
</log>
In the server logs I've the following ...
TID: [0] [ESB] [2014-07-04 11:27:46,569] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: process, SOAPAction: process, MessageID: urn:uuid:0D6752DAEC5AA438C92484199554844771301894479, Direction: request, **INITIAL MESSAGE = null**,..............
What am I doing wrong?
Thank you very much in advance .. .
Cesare
Please never think that your questions are stupid ones :). I think scope value that you have defined in the property mediator is invalid. Scoped must be default. It means you do not want to configure it and please tryout by removing it You can find detail about using $body from WSO2 ESB doc

WSO2 ESB work with MB

I'm trying to send a message from a local client to ESB and redirect it to MB on the same server.
The message delieved MB. The client is waiting for response until application server throws error.
My environment as below
WSO2 ESB 4.8.0 (port offset 1)
WSO2 MB 2.1.1 (port offset 2)
IBM WebSphere Application Server 8.5.5.1
The proxy service configuration of ESB
<proxy name="SMSQProdProxy" transports="http" startOnLoad="true" trace="enable">
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<send>
<endpoint>
<address uri="jms:/SMSQ?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.wso2.andes.jndi.PropertiesFileInitialContextFactory&java.naming.provider.url=repository/conf/jndi.properties&transport.jms.DestinationType=queue"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL key="gov:/trunk/services/SendToSMSQProxy.wsdl">
<resource location="SMSWSService_schema1.xsd"
key="gov:/trunk/services/SMSWSService_schema1.xsd"/>
</publishWSDL>
</proxy>
jndi.properties
connectionfactory.QueueConnectionFactory = amqp://admin:admin#carbon/carbon?brokerlist='tcp://localhost:5674'
connectionfactory.TopicConnectionFactory = amqp://admin:admin#carbon/carbon?brokerlist='tcp://localhost:5674'
queue.SMSQ = SMSQ
wso2-esb-errors.log
2014-03-21 14:18:54,276 [-] [HTTP-Listener I/O dispatcher-1] WARN SourceHandler Connection time out after request is read: http-incoming-3
wso2-esb-trage.log
INFO TRACE_LOGGER Proxy Service SMSQProdProxy
received a new message from : xx.xx.xx.xx
INFO TRACE_LOGGER Message To: /services/SMSQProdProxy
INFO TRACE_LOGGER SOAPAction:
INFO TRACE_LOGGER WSA-Action:
INFO TRACE_LOGGER Using the anonymous in-sequence of the proxy service for mediation
INFO TRACE_LOGGER Start : Sequence <anonymous>
INFO TRACE_LOGGER Sequence <SequenceMediator> :: mediate()
INFO TRACE_LOGGER Mediation started from mediator position : 0
INFO TRACE_LOGGER Start : Property mediator
INFO TRACE_LOGGER Setting property : OUT_ONLY at scope : default to : true (i.e. constant : true)
INFO TRACE_LOGGER End : Property mediator
INFO TRACE_LOGGER Start : Send mediator
INFO TRACE_LOGGER Sending message through endpoint : null resolving to address = jms:/SMSQ?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.wso2.andes.jndi.PropertiesFileInitialContextFactory&java.naming.provider.url=repository/conf/jndi.properties&transport.jms.DestinationType=queue
INFO TRACE_LOGGER SOAPAction:
INFO TRACE_LOGGER WSA-Action:
INFO TRACE_LOGGER End : Send mediator
INFO TRACE_LOGGER End : Sequence <anonymous>
error log of application server
java.io.IOException: Async IO operation failed (3), reason: RC: 55
Thanks for any idea.
After added <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/> I get another error message
2014-03-26 22:17:23,354 [-] [http-nio-9443-exec-15] WARN AuthenticationHandler Illegal access attempt at [2014-03-26 22:17:23,0353] from IP address null while trying to authenticate access to service StatisticsAdmin
2014-03-26 22:17:23,354 [-] [http-nio-9443-exec-15] ERROR AUDIT_LOG Illegal access attempt at [2014-03-26 22:17:23,0353] from IP address null while trying to authenticate access to service StatisticsAdmin
2014-03-26 22:17:23,355 [-] [http-nio-9443-exec-15] ERROR StatisticsAdminClient Cannot get service stats for service SMSQProdProxy. Backend server may be unavailable.
org.apache.axis2.AxisFault: The input stream for an incoming message is null.
There is a similar problem https://wso2.org/jira/browse/WSAS-1214
You can add the following after the OUT_ONLY property to your in sequence to return back to the client. This property will force the ESB to respond back to the client with HTTP 202.
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
Yohan,
It seems the new error you are experiencing is not related to the MB integration flow. Have you accessed the management console after session timed out? Can you reproduce this problem continuously? OR is this just one time occurrence?
When you set the OUT_ONLY property to true you are saying that, you are not waiting the response after the proxy end. So, in outSequence remove the send mediator.
If you want to force the proxy to send the response to the client, remove the
Out_Only property and, in inSequence section set this after endPoint mediator.
property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"
In outSequence section keep the <send/> mediator...

WSO2 ESB message id

Do I have any possibility to find message on WSO2 ESB by MessageId, like urn:uuid:e11893c5-b033-4e99-9473-a43d66b65fbb ? For example if some flow failed and server logged such ID.
Maryan,
ESB itself doesn't log messages anywhere until you tell it to.
a) The first approach is to write incoming and outgoing messages into the log using log mediator:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="YourProxyService" transports="https http" startOnLoad="true">
<target>
<inSequence>
<log level="full">
<property name="MESSAGE_ID" expression="get-property('MessageID')"/>
</log>
...
</inSequence>
<outSequence>
<log level="full">
<property name="MESSAGE_ID" expression="get-property('MessageID')"/>
</log>
...
</outSequence>
</target>
</proxy>
Then you'll be able to find your incoming and outgoing messages in log files as the logs would contains something like following:
INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: http://localhost:9763/services/YourProxyService, From: 127.0.0.1, WSAction: urn:mediate, SOAPAction: urn:mediate, Direction: request, MESSAGE_ID = urn:uuid:e11893c5-b033-4e99-9473-a43d66b65fbb , Envelope: <ENVELOPE_GOES_HERE>
b) Another approach would be to create table in the database and store message id and envelope to it.
Hope this helps.
Vladimir.
UPD: You can also use built in SOAP tracer, but enable it with caution - it hits ESB performance. So I suggest use it only for short term debugging activities.
Yes, you can get the message ID using property mediator,
<property name="MessageID" expression="get-property('MessageID')"/>
As others pointed out, you can use log statements in WSO2 ESB to log the messages and search and find later.
But it becomes complex when the message flow fails at some point, as the message IDs will be different across different message flows.
A simple approach would be to read the incoming messagID and use it till the final response message.
Have a look here for detailed explanation.