I have a proxy service which is exposed on http. After receiving the request the service validates it against its schema. Now if a validation fails, the service should send back client an error response and should also send that error message to a queue.
<validate [source="xpath"]>
<property name="validation-feature-id" value="true|false"/>*
<schema key="string"/>+
<on-fail>
mediator+
</on-fail>
</validate>
Problem:
I am making a custom message in "Validate" mediator "on-fail" sequence. I am sending back that message by using "Response" mediator. After sending back the response I want to send this same error message to a jms queue. But the problem is that after "Respond" mediator, no mediator works and if I put "Call" mediator" before the "Respond" mediator, only message is sent to queue, no response is sent back to client.
Things to achieve:
To summarize, I need to do following two things in a validate mediator fault sequence.
Send Back the Response to client.
Send the response to a queue.
how can I achieve that or is there any alternative approach to achieve this task?
When you say
I am making a custom message in "Validate" mediator "on-fail" sequence
I assume you are using payloadFactory. So , once you have built you're custom message , you can use the < clone > mediator to send the message to 2 destinations like so :
<clone>
<target>
<sequence>
<respond/>
</sequence>
</target>
<target>
<sequence>
<send>
<endpoint>
<address uri=""/> <!-- Specify the JMS connection URL here -->
</endpoint>
</send>
</sequence>
</target>
</clone>
Hope that works for you!
Related
I'm trying to use recipientList to send to multiple JMS endpoints. I'm using ActiveMQ as message broker. My problem is: Whether I set the URL as a one single node of ActiveMQ it works perfectly when I set a failover endpoint comma separated I just get that it splits the comma inside the failover URL. Is there a way I can skip this split of commas character inside the failover?
This works:
jms:/myQueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://myIP:61616&transport.jms.DestinationType=queue
But this doesn't work because it splits the comma.
jms:/myQueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=failover:(tcp://myIP:61616,tcp://myIP2:61616)&transport.jms.DestinationType=queue
In my case I concatenate multiple uris like the ones above with ',' for making the recipientList work, but the comma inside the failover is making it fail.
Is there a work-around?
Thanks,
Antonio
You can try like below instead of comma
<send>
<endpoint key="jmsMBendpoint1"/>
</send>
<send>
<endpoint key="jmsMBendpoint2"/>
</send>
or you can use Recipienlist endpoint to send a single message to multiple endpoints. After defining recipient list store taht as localentry and provide that as endpoint key.
for more
WSO2 ESB send to multiple endpoints
I don't know what is the workaround with recipientlist but an other way to achieve your need is :
<property name="EIP_LIST" type="OM">
<list xmlns="">
<epr>jms:/myQueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=failover:(tcp://myIP:61616,tcp://myIP2:61616)&transport.jms.DestinationType=queue</epr>
<epr>jms:/myQueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=failover:(tcp://myIP3:61616,tcp://myIP4:61616)&transport.jms.DestinationType=queue</epr>
</list>
</property>
<iterate expression="$ctx:EIP_LIST//epr">
<target>
<sequence>
<header name="To" expression="$body/epr"/>
<send/>
</sequence>
</target>
</iterate>
You just have to dynamically compose the content of EIP_LIST
I tried to implement a validation with FAULT in it something like this
<on-fail>
<makefault version="soap11">
<code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
<reason value="Invalid Request!!!"/>
<role/>
</makefault>
<log level="full"/>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<send/>
<drop/>
</on-fail>
therefore I added DROP after SEND what function just as I wanted (without DROP I just recived FAULT message but the process did not stop what resulted into invoking some End points with incorrect inputs)
Then I needed to check on something and I open the same sequence in Eclipse and discovered that DROP got removed.
I tried to drag and drop DROP but got an error message that the SEND mediator cannot be followed by another mediator.
why?
do you happen to know a better way how to implement SEND + DROP so there is not a risk that I lose this when I open it in Eclipse?
thx a lot!
You do not need to add a Drop Mediator after a Send. It is invalid to add any mediators after the Send mediator, since the message context will be dropped after the send. May be instead of a SEND mediator you can try adding a Respond Mediator. Your use case is not so clear.
In Eclipse Developer Studio, we cannot specify any mediator after SEND mediator/ RESPOND mediator/ DROP mediator. This is because, ideally mediation flow should not continue after those mediators.
For your case, can you try CALL mediator[1] instead of SEND mediator followed by DROP mediator as follows
<on-fail>
<makefault version="soap11">
<code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
<reason value="Invalid Request!!!"/>
<role/>
</makefault>
<log level="full"/>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<call/>
<drop/>
</on-fail>
https://docs.wso2.com/display/ESB490/Call+Mediator
We´re getting this error:
The endpoint reference (EPR) for the Operation not found is [OUR ENDPOINT] and the WSA Action = . If this EPR was previously reachable, please contact the server administrator.
Our SOAPActions are declared as "", as allowed by specification.
The following answer explains why it´s happening: https://stackoverflow.com/a/15556669/1553243. However, we can´t afford the suggested workarounds, 1 and 3. We can´t have our vendors declare their SOAPActions, and we can´t have our clients always append the operation name. Workaround 2 doesn´t work when SOAPAction = "", either.
The answer also states they were in a process of fixing this limitation, but I´m using a one year later release and nothing.
Is there any other workaround?
Our proxy is defined like:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TEST"
transports="https,http"
statistics="enable"
trace="enable"
startOnLoad="true">
<target>
<inSequence>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence>
<log/>
</faultSequence>
<endpoint>
<wsdl service="TESTService"
port="TESTServicePort"
uri="http://localhost:8080/test?wsdl"/>
</endpoint>
</target>
<publishWSDL uri="http://localhost:8080/test?wsdl"/>
<description/>
</proxy>
Since ESB v4.8, using pass-through http transport, you can add this parameter to your proxy def :
<parameter name="disableOperationValidation" locked="false">true</parameter>
In your webservice implementation class add the annotation #WebMethod to define the SOAP Action for individual operations. for example
#WebService
#SOAPBinding(style=Style.RPC)
public class BookingServiceWS {
#WebMethod(action="getBooking",operationName="getBooking")
public BookingServiceResponse getBooking(String pnr){
}
This will generate the WSDL with SOAP Action defined as
<operation name="getBooking">
<soap:operation soapAction="getBooking"/>
<input>...</input>
<output>...</output>
</operation>
This should be able to resolve the issue
Then you have control at ESB level? If so, you define the SOAPAction property at ESB level.
That is, when request hits the sequence, if you are sure where to route the request, at that time set SOAPAction property before the send mediator
<property name="SOAPAction" value="urn:OPERATION NAME"
scope="transport"/>
Workaround 2: You can specify the SOAPAction in the client side code. Specify it in the options as shown below.
options.setAction("urn:SOAPAction");
I am going to receive the url(Ex:- www.google.com) into my WS02 ESB and send response back to them.
How can we receive the url's(Ex:- www.google.com) into wso2 esb and give sucess response back to them.
If you want to response back to calling party with success HTTP response. Please set below property on your receiving path.
<property action="set" name="OUT_ONLY" value="true"/>
<property action="set" name="FORCE_SC_ACCEPTED" scope="axis2" value="true"/>
Does the ESB receive the URL as a property in the message context or are you referring to the URL where the request message is originated?
I have a string in a custom mediator in the inSequence . I want this string to be the final response from the esb . I want to sent this string back to the client as response.How can i do this?
After adding what ever the string you have inside the custom mediator you can send the current payload back to the client using the following config.
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>