blob: f409b4e36c8dfc77d2f2c682ff7370cbc4d352e6 [file] [log] [blame]
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<document>
<properties>
<title>Apache Synapse - Sample 471</title>
</properties>
<body>
<section name="Sample 471: Introduction to the EJB Mediator II - Invoking Stateful Session Beans">
<div class="xmlConf">&lt;definitions&gt;
&lt;proxy name=&quot;BuyAllProxy&quot; transports=&quot;https http&quot; startOnLoad=&quot;true&quot; trace=&quot;disable&quot;&gt;
&lt;target&gt;
&lt;!-- Iterate over all items in the request and call addItem() on the ShoppingCart EJB for each item. --&gt;
&lt;inSequence&gt;
&lt;property name=&quot;SESSION_ID&quot; expression=&quot;get-property(&apos;MessageID&apos;)&quot;/&gt;
&lt;iterate xmlns:m0=&quot;http://services.samples&quot; preservePayload=&quot;false&quot;
expression=&quot;//m0:buyItems/m0:items/m0:item&quot;&gt;
&lt;target&gt;
&lt;sequence&gt;
&lt;ejb class=&quot;samples.ejb.ShoppingCart&quot; beanstalk=&quot;demo&quot; method=&quot;addItem&quot; sessionId=&quot;{get-property(&apos;SESSION_ID&apos;)}&quot; jndiName=&quot;ShoppingCartBean/remote&quot;&gt;
&lt;args&gt;
&lt;arg value=&quot;{//m:item//m:id}&quot; xmlns:m=&quot;http://services.samples&quot;/&gt;
&lt;arg value=&quot;{//m:item//m:quantity}&quot; xmlns:m=&quot;http://services.samples&quot;/&gt;
&lt;/args&gt;
&lt;/ejb&gt;
&lt;sequence key=&quot;collector&quot;/&gt;
&lt;/sequence&gt;
&lt;/target&gt;
&lt;/iterate&gt;
&lt;/inSequence&gt;
&lt;/target&gt;
&lt;/proxy&gt;
&lt;!-- Prepare the response once all addItem() calls are finished. --&gt;
&lt;sequence name=&quot;collector&quot;&gt;
&lt;aggregate&gt;
&lt;onComplete&gt;
&lt;ejb class=&quot;samples.ejb.ShoppingCart&quot; beanstalk=&quot;demo&quot; method=&quot;getItemCount&quot; sessionId=&quot;{get-property(&apos;SESSION_ID&apos;)}&quot; target=&quot;ITEM_COUNT&quot;/&gt;
&lt;ejb class=&quot;samples.ejb.ShoppingCart&quot; beanstalk=&quot;demo&quot; method=&quot;getTotal&quot; sessionId=&quot;{get-property(&apos;SESSION_ID&apos;)}&quot; target=&quot;TOTAL&quot; remove=&quot;true&quot;/&gt;
&lt;payloadFactory&gt;
&lt;format&gt;
&lt;buyAllResponse xmlns=&quot;&quot;&gt;
&lt;itemCount&gt;$1&lt;/itemCount&gt;
&lt;total&gt;$2&lt;/total&gt;
&lt;/buyAllResponse&gt;
&lt;/format&gt;
&lt;args&gt;
&lt;arg expression=&quot;get-property(&apos;ITEM_COUNT&apos;)&quot;/&gt;
&lt;arg expression=&quot;get-property(&apos;TOTAL&apos;)&quot;/&gt;
&lt;/args&gt;
&lt;/payloadFactory&gt;
&lt;respond/&gt;
&lt;/onComplete&gt;
&lt;/aggregate&gt;
&lt;/sequence&gt;
&lt;/definitions&gt;</div>
<subsection name="Objective">
<p>
Demonstrate the usage of the EJB mediator for invoking EJB Stateful
Session Beans hosted on a remote EJB Container.
</p>
</subsection>
<subsection name="Pre-requisites">
<p>
<ul>
<li>
Follow steps 1 to 5 in <a href="sample470.html">Sample 470</a> to host the EJBs
in an EJB Container of your choice and to configure the <i>demo</i> beanstalk.
</li>
<li>
If the JNDI names assigned to the EJBs by your EJB Container differ from
the JNDI names specified in the sample 471 configuration file
(repository/conf/sample/synapse_sample_471.xml), edit the <i>jndiName</i>
attribute of all &lt; ejb /&gt; mediator invocations in the
<i>synapse_sample_471.xml</i> accordingly.
</li>
<li>
Start Synapse using the configuration numbered 471
(repository/conf/sample/synapse_sample_471.xml):
<div class="command">
Unix/Linux: sh synapse.sh -sample 471<br/>
Windows: synapse.bat -sample 471
</div>
</li>
</ul>
</p>
</subsection>
<subsection name="Executing the Client">
<p>
Send the following request to http://localhost:8280/services/BuyAllProxy
using a tool such at <a href="http://ws.apache.org/tcpmon/">TCPMon</a> or curl.
</p>
<div class="xmlConf">&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
&lt;soapenv:Body&gt;
&lt;buyItems xmlns=&quot;http://services.samples&quot;&gt;
&lt;items&gt;
&lt;item&gt;
&lt;id&gt;2150&lt;/id&gt;
&lt;quantity&gt;1&lt;/quantity&gt;
&lt;/item&gt;
&lt;item&gt;
&lt;id&gt;1189&lt;/id&gt;
&lt;quantity&gt;2&lt;/quantity&gt;
&lt;/item&gt;
&lt;item&gt;
&lt;id&gt;890&lt;/id&gt;
&lt;quantity&gt;4&lt;/quantity&gt;
&lt;/item&gt;
&lt;/items&gt;
&lt;/buyItems&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</div>
<p>
Each instance of the <i>ShoppingCart</i> stateful session bean hosted on the remote EJB container
maintains a state which keeps track of the number and the total price of the items
added via its <i>addItem(String itemId, int count)</i> method. The <i>float getTotal()</i> and
<i>int getItemCount()</i> methods are used to retrieve this state.
</p>
<p>
When the <i>BuyAllProxy</i> receives the above request, it iterates over all &lt;item&gt; elements
in the request and calls the <i>addItem()</i> method on the <i>ShoppingCart</i> bean,
once per each &lt;item&gt;, using the EJB mediator. Since the <i>sessionId</i> used for these
invocations is actually the message ID, each request works on a new <i>ShoppingCart</i> instance
which is created at the first EJB mediator invocation in that request's flow.
</p>
<p>
When all <i>addItem()</i> method calls are finished, <i>getItemCount()</i> and <i>getTotal()</i> methods
are invoked on the same <i>ShoppingCart</i> instance within the <i>collector</i> sequence and
results are stored in two message context properties named <i>ITEM_COUNT</i> and <i>TOTAL</i>.
The last EJB call on the shopping cart sets the EJB mediator attribute <i>remove = "true"</i>
instructing the current stateful bean stub to be removed from the beanstalk. This is because the
same stateful bean instance will not be used again (each request uses a new bean instance). If the
user does not explicitly remove the stub using this attribute, it will be removed automatically
upon timeout as specified by the beanstalk configuration.
</p>
<p>
Finally, the PayloadFactory mediator is used to build the response message which is sent back to the
client.
</p>
<p>A sample response is shown below.</p>
<div class="xmlConf">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
&lt;soapenv:Body&gt;
&lt;buyAllResponse&gt;
&lt;itemCount&gt;7&lt;/itemCount&gt;
&lt;total&gt;807.0&lt;/total&gt;
&lt;/buyAllResponse&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</div>
</subsection>
</section>
<p><a href="../samples.html">Back to Catalog</a></p>
</body>
</document>