login button

HTTP to JMS, and synchronous request with response.

Forums :

Sample 251 shows an example of switching from http to jms using the SimpleStockQuoteService proxy.  The ESB configuration forwards messages to JMS, but only responds to the client if axis2 server is online and via callback



I have a need to setup a similar scenario, but with only the ESB, and JMS services running (no end service that can do an http response like that being done with axis2 server).



Looking over the sample client, and the placeorder mode, Sample 251 can partially work without the axis2 server running.  It uses fireAndForget, and a client controlled Thread.sleep call to wait 5 seconds and effectively "hope" the message got there.  Without sleeping (or if the sleep time is too low), the message being sent over http can't make its way to the queue as the client prematurely terminates.  No success/failure message is given.  Ideally though, I would like to allow as much time as necessary, and make use of serviceClient.sendReceive.  To do so, the client needs to receive something back from the ESB.  But without a response coming back through JMS, no response is ever received by ESB to forward on back to the client over HTTP.



Is there any way to setup a synchronous call over HTTP, to the ESB, which transforms to save to a JMS queue, and respond back that the message was stored on the queue?



-Lucas

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Hi Lucas, Well, a good

Hi Lucas,

Well, a good question and this is possible. What you need to do is to clone the message with using the clone mediator before sending and use the cloned message to send back the response.

Please have a look at the following configuration;

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <proxy name="StockQuoteProxy" transports="http">
        <target>
            <endpoint>
                <address uri="jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&
                   java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616"/>
            </endpoint>
            <inSequence>
                <clone continueParent="true">
                    <target>
                        <sequence>
                            <property name="RESPONSE" value="true" action="set"/>
                            <header name="To" action="remove"/>
                            <send/>
                        </sequence>
                    </target>
                </clone>
                <property action="set" name="OUT_ONLY" value="true"/>
            </inSequence>
            <outSequence>
                <send/>
            </outSequence>
        </target>
        <publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
    </proxy>

</definitions>

Further if you need a nice message to be sent back to the client you may do an XSLT transformation to specify the message "Successfully delivered the message" to the SOAP body.

But this doesn't guarantee the delivery to the JMS queue but just the receiving the message into the service in the ESB layer.

Thanks,
Ruwan

guarantee the delivery

Ruwan,

This is an interesting answer and very good that the ESB can do this... But it brings up some more questions..

Say you are passing a large message to the ESB and the ESB is adding it to the queue. Lets say a 2mb document.

1. Does cloning the message clone the entire message or are you able to only clone a portion.. If it clones the entire message does that create another 2mb foot print on the server.

2. Is there way to pass an HTTP(s) request to the ESB.. Have the ESB add it to the queue.. and then send a success or fail message back... basically guaranteeing the delivery.

Thanks,
J

For the question 1 answer is

For the question 1 answer is YES, we had to do this because if you get a partial copy then there is going to be references to the original message and upon doing mediation the original message is also going to be affected.

Being said that I must say that there is a possibility to add an option to the clone mediator asking it to not to clone the SOAP Envelope but just the properties associated with that particular message with a new blank envelope, this way we can avoid the issue of memory foot prints.

Answering question 2;
I am in the process of writing a guaranteed delivery pattern implementation which is an extended mediator of the send mediator and once it is done this will be possible.

Thanks,
Ruwan
Ruwan Linton

awesome

Ruwan,

Thanks excellent news that you are writing one already..

Will that be available via the SVN repo or will that be posted to the esbsite.org?

Thanks,
J

Picking up mc property after endpoint, but before outSequence?

ruwan,



I was able to get cloning to work as you described, but as jdholmes1978 mentioned, it will consume more memory, but more importantly, it doesn't guarantee that the message ever got to the queue.



I was looking at the source for org.apache.synapse.transport.jms.JMSSender, and noticed that JMS_MESSAGE_ID property is getting set.  Further searches reveal that another user may be struggling with this same issue as I.  See j0na's post on April 18 here: http://wso2.org/forum/thread/3498  and more explanation on nabble,  http://www.nabble.com/How-take-the-JMS_MESSAGE_ID-td17536304.html



What I need to do is figure out a way to take that property, and return it to the client that made the initial request.  At first I was hoping to apply some quick scripting in an outSequence (http://esbsite.org/resources.jsp?path=/summaries/wkeenan/Groovy%20Script%20stored%20in%20a%20Repository%20snippet), but apparently, the outSequence never runs, ostensibly because there is no message to apply the outSequence to get it started?!



So if the inSequence is finished, and the outSequence is 'waiting', then that leaves me with trying to apply some change to my endpoint.  Is there some way to configure my endpoint to pick up that JMS_MESSAGE_ID after the message is sent to the queue?  Here is my basic proxy:



  <syn:proxy name="ResponseProxy" transports="http" startOnLoad="true">

    <syn:target>

      <syn:endpoint>

        <syn:address uri="jms:/testQueue?transport.jms.ConnectionFactory=myQueueConnectionFactory">

          <syn:timeout>

            <syn:duration>10</syn:duration>

            <syn:action>fault</syn:action>

          </syn:timeout>

        </syn:address>

      </syn:endpoint>

      <syn:inSequence>

        <syn:property name="OUT_ONLY" value="true"/>

        <syn:property name="RESPONSE" value="true"/>

        <syn:header name="To" action="remove"/>

      </syn:inSequence>

      <syn:outSequence>

        <syn:script language="groovy">

          <![CDATA[

              static void mediate(mc)

              {

                def payloadXML = "<response>";

                payloadXML += "Message received for processing and given the following id: ";

                payloadXML += mc.getProperty("JMS_MESSAGE_ID")

                payloadXML += "</response>";

                mc.setPayloadXML(payloadXML);

                mc.setResponse(true);

              }

              ]]>

        </syn:script>       

        <syn:send/>

      </syn:outSequence>

    </syn:target>

  </syn:proxy> 





-K

First of all, what you have

First of all, what you have done in the inSequence seems to be wrong;

<syn:inSequence>
    <syn:property name="OUT_ONLY" value="true"/>
    <syn:property name="RESPONSE" value="true"/>
    <syn:header name="To" action="remove"/>
</syn:inSequence>

there you should not put the OUT_ONLY property because otherwise there is not going to be a response at all and even the timeout action will not be valid.

Secondly, you should not mark the message as a RESPONSE because inSequencec specifies the mediation for the message before sending it out and hence this is wrong, and of course there is no value in removing the To header as well. So in effect the full inSequence is optional and can be removed.

Then, if you look at the guaranteed delivery, you need to make sure the message has been received by the JMS queue to which you are posting the message and without the transport support to get the delivery status you cannot guarantee the delivery, not even using the timeout action.

Last but not least, the outSequence will not get invoked because there is no response, but the sequence named fault defined in the synapse configuration as a top level sequence will get triggered and you may put the script mediator there to send the message back, with the RESPONSE property and removal of the To header. Further you need to put a send mediator after the as the last mediator in the fault sequence in-order to send the message back to client. Please note that this send mediator is a default send mediator and should not contain any endpoints so that the message will be sent back to the client.

But, even this will not guarantee the delivery to the JMS queue, because the timeout may occur before sending the message to the queue or even when there is a network failure.

Thanks,
Ruwan Linton
http://ruwansblog.blogspot.com

Lucas I tried what you

Lucas

I tried what you proposed, but the problem here is that you are doing a one way send via JMS, and the MessageID property will not be returned back to you, as whats sent by JMS is a copy of the original message context of Synapse.

Can you reopen https://wso2.org/jira/browse/ESBJAVA-462 and state your requirement and we will make this modification

asankha

Asankha, I've added a

Asankha,

I've added a comment, but I'm not sure how to actually reopen that JIRA.

-Lucas

Thanks Lucas.. I think its a

Thanks Lucas.. I think its a permission issue.. I've reopened it now..

asankha

Thanks asankha. This will

Thanks asankha. This will really help with what I'm trying when its working. Do you have any projections on when a fix could be available in the nightly builds?

Hi Lucas Unfortunately this

Hi Lucas

Unfortunately this will not be possible in the next couple of weeks are I am busy with another set of enhancements right now. However, updating the JMS transport for JTA support is on my TODO list, so I will get to this before the 2.0 release

asankha

RE: Hi Lucas Unfortunately this

asankha,

That is fine... Is the next release of the ESB going to be 2.0 or are we looking at 1.8.. 1.9.. 2.0..?

Thanks,
J

Jon It will be 2.0..

Jon

It will be 2.0..

asankha

Re: Jon It will be 2.0..

asankha,

I really didn't mean for my question to come off rude in fact I am sorry if it did. Just as you are trying to architect the ESB I am architecting a solution around the ESB that you all are providing and I am very happy with what we are able to do.

The reason why I was asking what I asked is because I have a requirement that states reliable messaging. If I do not get that in 1.8 thats ok but I need to plan for that. What I meant to ask to ask was is the next release going to be 1.8 or is the upcoming release going to move into the 2.0 range. Any answer is ok it more for me so that I know how to set the expectations of my customer.

once again sorry if I sounded rude,
J

Hi Jon Oh no .. not at all..

Hi Jon

Oh no .. not at all.. I never even thought your question sounded even a bit rude.. I was just replying to your question in short since I am yet unable to fully commit to the release date of the ESB 2.0 at this point in time - although we planned it for end October.

Is your requirement based on JMS? If so, letting us know could help us prioritize our work. For example, you may recall that we have done major improvements over the last months when users were depending or waiting for features.. having this level of relationship to "know" what our users need and the timelines helps us give more priority to certain things, sometimes more than just with a JIRA.

asankha

Re: Hi Jon Oh no .. not at all..

Asankha,

Thank you for your response. Lucas is actually on my team and we are extending a content management system. With that said we are already using WSAS and we are currently working on incorporating the ESB to help us deal with “data” (documents) coming into and out of the system. Our focus now is to enable documents to be submitted into the system which is why JMS is very important to us. Being able to take HTTP(s) request (say a upload web service) and switching the transport to JMS is huge because it allows to truly separate the backend component, business logic, form the front-end tier. It also allows us to scale more easily..

So far the ESB has been able to do almost everything needed.. Some of the pieces were not there… like the PKI security components which I have contributed back and Indika integrated which was VERY helpful. The last piece for the use case above is JMS reliable messaging. As you probably can see.. Because we are extending a content management system knowing that the documents being submitted are actually getting into the JMS queue’s is a very important requirement for us. It allows us to get instant feedback so that we are able to handle the what if scenarios in case something goes wrong and it also allows us to notify the external systems implementing our service. As Lucas mentioned the ideal situation would be to allow us to return the message ID back to the external system if all goes well and be able to handle if something goes wrong.

We do have tight deadlines on our end and I was hoping you would have been able to incorporate this feature in by the middle of September which gives us time to integrate it into our solution so that when the October build comes out we are ready to go but again if that doesn’t match up with the improvements on the plate already that is ok I just have to know this so that I can manage my customers expectations.

Once again thank you,
J

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.