How to get real result from AxisEngine - axis2

I'm trying to implement my specific transport for WSO2 ESB based on some proprietary binary protocol. From protocol specification I need acknowledge every packet I receive only if I'm 100% sure that it will be processed in future. For those reasons some persistent store must be used.
I want to implement that protocol logic via WSO2 ESB sequence that gets protocol packets/messages and stores them to temporary messageStore which is used as a queue in producer/consumer pattern (where producer is transport itself and consumer is my packet processor).
I have to be sure that my packet got to the messageStore before sending acknowledge to the client. But AxisEngine.receive() does always return CONTINUE even if message store is not available.
The configuration of the proxy is:
<proxy name="MyProxyService">
<target>
<inSequence>
<store messageStore="MyStore" sequence="onStoreSequence"/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence>
<makefault version="soap11" response="true">
<code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
<reason expression="get-property('ERROR_MESSAGE')"/>
</makefault>
<send/>
</faultSequence>
</target>
</proxy>
The code I use in transport is:
MessageContext msgContext = confContext.createMessageContext();
AxisConfiguration axisConf = confContext.getAxisConfiguration();
try {
msgContext.setTransportIn(axisConf.getTransportIn(transportName));
msgContext.setTransportOut(axisConf.getTransportOut(transportName));
msgContext.setIncomingTransportName(Constants.TRANSPORT_LOCAL);
msgContext.setAxisService(axisConf.getService("MyProxyService"));
msgContext.setEnvelope(TransportUtils.createSOAPMessage(msgContext));
msgContext.setServerSide(true);
Handler.InvocationResponse response = AxisEngine.receive(msgContext);
log.error(String.valueOf(response));
} catch (Exception e) {
log.error("ERROR", e);
}
The behaviour I want to have is what I see in HTTP transport: http request from the client (SOAP UI) is translated to Axis2 MessageContext and delivered to MyProxyService. If everything is ok - I get positive response, otherwise - error code and SOAP fault.

After additional investigation I can say that idea behind HTTP transport request/response is that for sending response the HttpSender not HttpReceiver is used. HttpReceiver gets request from HTTP connection, sets link to HTTP connection to the message context, uses AxisEngine.receive() to deliver message to the ESB and returns.
HTTP response itself is received via HttpSender, identified as response to the previous request (via empty To header) and sent to the connection referenced from the message context.

Related

Error handling in spring integration

I have three different systems. I am using Spring integration to sync data in all these system.
System 1 calls --- > System 2 via http:inbound gateway
<int-http:inbound-gateway id="gateway"
path="/save" supported-methods="POST, PUT"
request-channel="requestChannel" reply-channel="replyChannel"
request-payload-type="com.model.Request"
mapped-request-headers="source" error-channel="errorChannel" />
System 2 will call service method to persist data which returns response if request is valid else throws exception
<int:service-activator ref="serviceMethod"
method="saveIfValid" input-channel="requestChannel"
output-channel="serviceOutput" />
<int:recipient-list-router id="id1"
input-channel="serviceOutput">
<int:recipient channel="system1" />
<int:recipient channel="system3" />
</int:recipient-list-router>
I need to send service method response to system 1 and system 3 only if operation is successful.
After calling service method, based on service method response, request for system 3 will be generated using transformer. After transformer I am putting request in mq queue.
<int:transformer id="transformer1"
method="convert" input-channel="system3"
output-channel="jmsInput">
<bean
class="com.transformer.System3Transformer" />
</int:transformer>
<int-jms:outbound-channel-adapter id="adapter"
channel="jmsInput" destination-name="queueName">
</int-jms:outbound-channel-adapter>
Updated JMS outbound code
<int-jms:outbound-channel-adapter id="jms1"
channel="jmsIn" destination-name="queueName">
<int-jms:request-handler-advice-chain>
<bean
class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
<property name="onSuccessExpression" value="T(Boolean).TRUE" />
<property name="successChannelName" value="afterSuccessDeleteChannel" />
<property name="onFailureExpression" value="T(Boolean).FALSE" />
<property name="failureChannelName" value="afterFailRenameChannel" />
</bean>
</int-jms:request-handler-advice-chain>
</int-jms:outbound-channel-adapter>
My question is
if service class fails I need to send error response and stop the flow
if service method successful persisted data, but transformation fails, system 1 should get success response and error should be logged.
Here as I am using error channel in outbound adapter, even if error occurs in transformer it is returned to system 1.
please suggest how can i handle error without using global error channel and how to handle error in jms outbound adapter.
thank you for answering my quesion
For the first case you should really just rely on the exception propagation - the flow stops and error is sent to the system1 as an HTTP response.
For the second (transformer) case you should take a look into the ExpressionEvaluatingRequestHandlerAdvice and use it with the <request-handler-advice-chain> for the <transformer>.
The same can be applied for the <int-jms:outbound-channel-adapter>, if you should acknowledge to the system1.
http://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#expression-advice
https://github.com/spring-projects/spring-integration-samples/tree/master/intermediate/retry-and-more

WSO2 - Forward response from REST (called from WSO2) to JMS queue

I've faced an issue, with trying to forward message, returned from my custom REST end-point, into JMS queue.
I wanted to implement something like:
SMTH CUSTOM IS PUSHING MESSAGE TO WSO2 JMS QUEUE called testQueue
WSO2 is retrieving this message, and once there is an message, it's pushing this message next to custom REST service:
Becasue I've defined receive to testResponse inside send section, I'm able to log reponse from REST API inside testResponse.
Now I'm stuck, as I'm trying to somehow push response from REST API next, to let say second JMS queue, called testQueue2.
I've already tried with call tags inside my custom sequence (called testReponse), but it's just not executing at all (I've also tried for test, just to execute second REST API inside, to be just sure, if it's not something with executing of JMS itself...):
Any ideas, how I can move response from called REST API on to JMS queue?
Thanks.
<proxy name="testQueue" startOnLoad="true" transports="jms">
<target>
<inSequence>
<send receive="testResponse">
<endpoint>
<http format="rest" method="POST" uri-template="http://localhost/customRestAPI?message=test" />
</endpoint>
</send>
</inSequence>
<outSequence />
</target>
</proxy>
<sequence name="testResponse">
<log level="full" />
</sequence>
Try adding an "Out Flow" mediation extension as explained here.

WSO2 ESB: Proxy Service - how to use faultsequence

I wish all my Proxy Services to log a standard ERROR when the endpoint publishes a soapfault. Setting faultSequence to a valid logging sequence doesn't seem to be doing anything. I know the endpoint is publishing fault responses & the faultlogger sequence is a simply FULL log.
<SOAP-ENV:Fault...> </SOAP-ENV:Fault>
<proxy ... >
<target faultSequence="faultlogger" endpoint="conf:/myService>
...
</target>
</proxy>
How does faultSequence work?
I also tried to use a out, filter + log but wasn't sure what the xpath expression I should use to filter for faults.
faultSequence is executed when there is a technical error (in your xpath for exemple, or can't connect to an address configured in an endpoint)
A SOAPFault is not a technical problem and the out sequence is executed : you can verify response message to find potentials soap faults.
An other solution is to set the property named FORCE_ERROR_ON_SOAP_FAULT :
<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>

Wso2esb rest to soap - uri-template is appended to receiving esb

I have two wso2esb instances:
1) receives a rest uri-template and sends it as a soap request.
Example request: http://myipadd:8280/restcontext/mypath
2) receives and process the soap request from #1.
When I log the request from #1, it logs that my header "To: /services/MyService" is set correctly as expected. But when I receive it from #2, it appends the path: "To: /services/MyService/mypath".
Now, my proxy service is not able to resolve this.
Use this before sending soap request to remove your REST_URL_POSTFIX:
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>

Error accesing published WS proxy in WSO2 ESB 4.6: EPR not found

I deployed exactly the same WS-proxy in 4.5.1 and 4.6. With 4.5.1 it works correctly, but with 4.6 I get:
ERROR - AxisEngine The endpoint reference (EPR) for the Operation not found is /services/registro.registroHttpSoap11Endpoint and the WSA Action = . If this EPR was previously reachable, please contact the server administrator.
The source is the following:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="registro" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="http://localhost:15080/SIGEM_RegistroPresencialWS/services/ServicioRegistroWebService"/>
</endpoint>
</target>
<publishWSDL uri="http://localhost:15080/SIGEM_RegistroPresencialWS/services/ServicioRegistroWebService?wsdl"/>
<description></description>
</proxy>
What do I have to do for 4.6. to make it work?
Thanx.
To enhance ESB performance pass-through transport has been enabled by default starting from ESB 4.6.0 version that is not the case for ESB 4.5.1. It seems your proxy service depends on SOAP body based dispatching but pass-through transport does not support for SOAP body based dispatching. SOAP body based dispatching build the message body and use first element's local name for dispatching which effect to proxy performance badly that is the reason it was not supported in pass-through transport. We are in a process to fix this limitation for future ESB releasees without loosing any advantage of pass-through transport.
BTW for the moment you can use one of the following workarounds.
When sending a messages to the proxy service append operation name to the endpoint URL
e.g - http://serverName/app/serviceName/operationName
Modify client level code to send expected SOAPAction value ( like Try-It case)
I'm not sure your backend service's WSDL defined "" as the value of SOAPAction if that is the case you may modified the backend service to have value other than "" per each operation. AS an example for JAX-WS services you can use #WebMethod annotation for this.
e.g - #WebMethod(action="XXXX")
Note : In case if your backend WSDL defining a value other than "" for SOAPAction while your client send message with SOAPAction="" then it's a violation of service contract by the client and need to be fixed on client level.
I have faced the same problem with wso2 ESB 4.7 and the web service is also developed by me for the company.
What worked for me is adding soapAction attribute to wsdl soap:operation element like below.
<soap:operation soapAction="http://localhost:8080/MyWebApp/services/hello" style="document"/>