nmukhi 2002/12/27 09:52:07 Modified: java/samples/jms README.html Added: java/samples/jms ServiceAvailability.wsdl java/samples/jms/client/dynamic README.html java/samples/jms/client/stub README.html Run.java java/samples/jms/client/stub/org/apache/xml CheckAvailabilityPortType.java java/samples/jms/service README.html ServiceAvailabilityBean.java java/samples/jms/service/deploy/jboss ejb-jar.xml jboss.xml serviceavailability.jar Log: Files for JMS sample Revision Changes Path 1.3 +7 -1 xml-axis-wsif/java/samples/jms/README.html Index: README.html =================================================================== RCS file: /home/cvs/xml-axis-wsif/java/samples/jms/README.html,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- README.html 20 Dec 2002 14:41:22 -0000 1.2 +++ README.html 27 Dec 2002 17:52:06 -0000 1.3 @@ -10,6 +10,12 @@ <h1> Web Services Invocation Framework:<br> JMS Sample</h1> -<p>Coming soon!</p> +<p>In this sample shows how we can invoke systems implemented using message-oriented middleware (MoM) using JMS through the WSIF API. As always, the WSIF API hides all the protocol-specific (in this case, JMS) details; we use the same, WSDL-driven consistent view of the software. The key here is the WSIF defines a <a href="../../doc/wsdl_extensions/jms_bindings.htm">JMS binding</a> that lets us maps abstract messages to JMS messages, use JMS headers, properties, etc. The <tt><port></tt> section of the WSDL will then refer to a message queue as the target of the request messages, along with the required JNDI information to locate the queue dynamically.</p> +<p>Our particular example is a very simple service. The purpose of the service is to inform users whether DSL service is available at a particular zip code or not. It exposes a single port type which offers one operation called <tt>checkAvailability</tt>. This operation takes as input a message with a single part (a string), representing the zip code, and returns as output a string whose value will be either true or false, depending on whether DSL service is available or not.</p> +<p>The JMS binding for the service uses JMS text messages for communication. The WSIF JMS provider handles conversion of the abstract invocation to the sending of a JMS message to the desired destination queue, as specified in the WSDL. The return message is received over a temporary queue and returned to the application that made the invocation. From the application's viewpoint, it looks like a synchronous invocation; at the lower (JMS) level, it is really asynchronous.</p> +<p><a href="ServiceAvailability.wsdl">Here</a> is the service WSDL. Note the JMS binding and the endpoint details for the service. The endpoint information specifies that the service will listen for messages sent to a queue; the queue can be looked up using the JNDI name <tt>queue/A</tt>. The initial context factory specified is vendor-specific. So you may need to edit these fields dependong on how you deploy your service.</p> +<p><a href="service/README.html">Here</a> are details on how the service is implemented and deployed so that it is accessible using JMS. These details include instructions on how to deploy the service in your favorite J2EE server.</p> +<p>Once your service is deployed and available using JMS, you can use WSIF's dynamic invocation API to use it, as described <a href="client/dynamic/README.html">here</a>.</p> +<p><a href="client/stub/README.html">Here</a> is how you can pregenerate stubs to access the same service using a stub API, resulting in a client application that deals with a simple service interface instead of WSIF-specific code.</p> <hr width="100%"> </body></html> 1.1 xml-axis-wsif/java/samples/jms/ServiceAvailability.wsdl Index: ServiceAvailability.wsdl =================================================================== <?xml version='1.0' encoding='UTF-8'?> <definitions name='ServiceAvailability' targetNamespace='http://xml.apache.org/axis/wsif/samples/jms/ServiceAvailability' xmlns:tns='http://xml.apache.org/axis/wsif/samples/jms/ServiceAvailability' xmlns:format="http://schemas.xmlsoap.org/wsdl/formatbinding/" xmlns:jms='http://schemas.xmlsoap.org/wsdl/jms/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='checkAvailabilityRequest'> <part name='zipCode' type='xsd:string'/> </message> <message name='checkAvailabilityResponse'> <part name='result' type='xsd:string'/> </message> <portType name='CheckAvailabilityPortType'> <operation name='checkAvailability'> <input message='tns:checkAvailabilityRequest'/> <output message='tns:checkAvailabilityResponse'/> </operation> </portType> <binding name='CheckAvailabilityJMSBinding' type='tns:CheckAvailabilityPortType'> <jms:binding type="TextMessage"/> <format:typeMapping encoding="XML" style="Java"> <format:typeMap typeName="xsd:string" formatType="java.lang.String"/> </format:typeMapping> <operation name='checkAvailability'> <input> <jms:input parts="zipCode"/> <jms:property message="Request" part="myInt" /> <jms:propertyValue name="myLiteralString" type="xsd:string" value="Hello World" /> </input> <output> <jms:output parts="result"/> </output> </operation> </binding> <service name='CheckServiceAvailability'> <port name='CheckAvailabilityPort' binding='tns:CheckAvailabilityJMSBinding'> <jms:address destinationStyle="queue" jndiDestinationName="queue/A" jndiConnectionFactoryName="ConnectionFactory" initialContextFactory="org.jnp.interfaces.NamingContextFactory" jndiProviderURL="localhost"/> </port> </service> </definitions> 1.1 xml-axis-wsif/java/samples/jms/client/dynamic/README.html Index: README.html =================================================================== <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Nirmal Mukhi"> <meta http-equiv="Content-Style-Type" content="text/css"> <title>Web Services Invocation Framework: Samples</title> <link rel="stylesheet" href="wsif.css" type="text/css"></head> <body alink="#0000ff" bgcolor="#ffffff" leftmargin="2" topmargin="2" marginwidth="2" marginheight="2"> <h2> Web Services Invocation Framework:<br> Invoking the JMS Sample using WSIF's dynamic invocation interface</h2> <p>After you have <a href="../../../../doc/samples.html">set up the CLASSPATH in your environment</a>, to invoke this sample using WSIF's DII, run the DynamicInvoker class. Specify as command line arguments the location of the WSDL file for the jms sample followed by the operation you wish to invoke and the zip code you are interested in. For example, <br><tt>java clients.DynamicInvoker samples/jms/ServiceAvailability.wsdl checkAvailability 10050</tt></p> <p>To see details of how the WSIF API is used to make invocations dynamically, take a look at the code for the <a href="../../../clients/DynamicInvoker.java">DynamicInvoker class</a>.</p> <hr width="100%"> </body></html> 1.1 xml-axis-wsif/java/samples/jms/client/stub/README.html Index: README.html =================================================================== <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Nirmal Mukhi"> <meta http-equiv="Content-Style-Type" content="text/css"> <title>Web Services Invocation Framework: Samples</title> <link rel="stylesheet" href="wsif.css" type="text/css"></head> <body alink="#0000ff" bgcolor="#ffffff" leftmargin="2" topmargin="2" marginwidth="2" marginheight="2"> <h2> Web Services Invocation Framework:<br> Invoking the JMS Sample through a high level stub interface</h2> First, you must <a href="../../../../doc/samples.html">set up the CLASSPATH in your environment</a>. <p>This directory contains a file called <tt>Run.java</tt> that contains the <tt>main</tt> method. This is the logic that uses the generated stub interface to run the sample. So you can run this class, specifying on the command line the location of the WSDL file for the sample and the zip code you are interested in. For example, <br> <tt>java jms.client.stub.Run samples/jms/ServiceAvailability.wsdl 10050</tt></p> <p>To generate the stub interface, you can use any tool that generates Java interfaces for WSDL services using their port type descriptions. WSDL2Java, which is packaged with Axis, unfortunately does not work since the presence of a JMS binding in the WSDL confuses it, so we actually wrote our stub interface by hand. It is available <a href="org/apache/xml/CheckAvailabilityPortType.java">here</a>. Note that WSIF assumes a correspondence between the generated Java interface and the WSDL port type that has its abstract description as specified in the JAX-RPC specification.<br> <hr width="100%"> </body></html> 1.1 xml-axis-wsif/java/samples/jms/client/stub/Run.java Index: Run.java =================================================================== package jms.client.stub; import org.apache.wsif.WSIFService; import org.apache.wsif.WSIFServiceFactory; import org.apache.wsif.WSIFException; import java.rmi.RemoteException; import jms.client.stub.org.apache.xml.CheckAvailabilityPortType; /** * Class that runs the jms sample using a pregenerated stub interface. * To use this class, provide a zip code on the command line. WSIF * should then invoke the JMS service with this information, returning with a * true or false to indicate whether DSL service is avaiulable or not in that * zip code. * @author Nirmal K. Mukhi ([EMAIL PROTECTED]) */ public class Run { public static void main(String[] args) { try { if (args.length != 2) { System.out.println( "Usage: java jms.client.stub.Run <wsdl location> <zip code>"); System.exit(1); } // create a service factory WSIFServiceFactory factory = WSIFServiceFactory.newInstance(); // parse WSDL WSIFService service = factory.getService( args[0], null, null, "http://xml.apache.org/axis/wsif/samples/jms/ServiceAvailability", "CheckAvailabilityPortType"); // create the stub CheckAvailabilityPortType stub = (CheckAvailabilityPortType) service.getStub( CheckAvailabilityPortType.class); // do the invocation // args[1] is the zip code String serviceAvailable = stub.checkAvailability(args[1]); System.out.println(serviceAvailable); } catch (WSIFException we) { System.out.println( "Error while executing sample, received an exception from WSIF; details:"); we.printStackTrace(); } catch (RemoteException re) { System.out.println( "Error while executing sample, received an exception due to remote invocation; details:"); re.printStackTrace(); } } } 1.1 xml-axis-wsif/java/samples/jms/client/stub/org/apache/xml/CheckAvailabilityPortType.java Index: CheckAvailabilityPortType.java =================================================================== package jms.client.stub.org.apache.xml; public interface CheckAvailabilityPortType extends java.rmi.Remote { public String checkAvailability(java.lang.String zipCode) throws java.rmi.RemoteException; } 1.1 xml-axis-wsif/java/samples/jms/service/README.html Index: README.html =================================================================== <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Nirmal Mukhi"> <meta http-equiv="Content-Style-Type" content="text/css"> <title>Web Services Invocation Framework: Samples</title> <link rel="stylesheet" href="wsif.css" type="text/css"></head> <body alink="#0000ff" bgcolor="#ffffff" leftmargin="2" topmargin="2" marginwidth="2" marginheight="2"> <h1> Web Services Invocation Framework:<br> Implementing the JMS service</h1> <p>The JMS service is implemented as a message driven bean (MDB). In case you need to learn more about MDBs, you can refer to various guides and tutorials available for free online; I found <a href="http://www.onjava.com/pub/a/onjava/excerpt/ejb3_ch13/index.html">this excerpt from Richard Monson-Haefel's EJB book</a> useful.</p> <p>The bean implementation is very simple. It acts as a message listener (the queue is determined by the deployment files). When a message is delivered, it extracts the body (recall that we are using JMSTextMessages to communicate back and forth since we are just exchanging strings). This is presumably a valid zip code, so the bean makes it an integer in an unsafe and intrepid manner. Here is applies some logic to determine whether DSL service is available at this zip code or not. A real-world implementation would invariably refer to some backend database using JDBC or do something similarly smart. Our implementation, being just a sample, returns true for all zip codes < 5000, and false otherwise. The return message is sent to the queue specified in the <tt>replyTo</tt> field of the request message. Note that the bean must encode the correct <tt>JMSCorrelationID</tt> in the return message in order for it to be picked up by WSIF. <a href="ServiceAvailabilityBean.java">Here</a> is the code for our MDB.</p> <p>The <tt><a href="deploy">deploy</a></tt> subdirectory contains the things necessary to deploy this MDB to your favorite application server. Generally to deploy your MDB you will need to compile the code for this sample, then package it into a JAR along with the <tt><a href="deploy/jboss/ejb-jar.xml">ejb-jar.xml</a></tt> file. Your application server may need other files. We have included under the <tt>deploy/jboss</tt> directory a pre-packaged jar that contains the compiled beans and the configuration files required by JBoss. All you need to deploy to JBoss is to drop this <a href="deploy/jboss/serviceavailability.jar">serviceavailability JAR file for JBoss</a> (assuming you use the default server configuration) into server/default/deploy under your JBoss server installation, and start your server. This has been tested with JBoss version 3.0.4 running on Windows 2000, with the sample client running on Windows 2000 and using WSIF in a Java 1.4.1 environment.</p> <p>Remember that you may need to modify the <a href="../ServiceAvailability.wsdl">service WSDL</a> once you have completed your deployment so that the endpoint information settings correspond to your deployment (this is not necessary if you use JBoss in its default configuration).</p> <hr width="100%"> </body></html> 1.1 xml-axis-wsif/java/samples/jms/service/ServiceAvailabilityBean.java Index: ServiceAvailabilityBean.java =================================================================== package jms.service; import javax.ejb.MessageDrivenBean; import javax.ejb.MessageDrivenContext; import javax.ejb.EJBException; import javax.jms.*; import javax.naming.NamingException; import javax.naming.InitialContext; /** * This is a simple MDB that processes a message containing an integer * that represents a zip code, and returns a message containing a * boolean indicating whether DSL service is available at that zip code * or not. * Internally the bean just returns true for zip codes < 5000 and * false otherwise. */ public class ServiceAvailabilityBean implements MessageDrivenBean, MessageListener { MessageDrivenContext context = null; public void setMessageDrivenContext(MessageDrivenContext context) { this.context = context; } public void ejbCreate() throws EJBException { } public void ejbRemove() { context = null; } public void onMessage(Message msg) { try { TextMessage message = (TextMessage)msg; // assume we have an integer int zipCode = new Integer(message.getText()).intValue(); // return true if zip code < 5000, false otherwise if (zipCode<5000) sendMessage(message,"true"); else sendMessage(message,"false"); } catch(Exception e) { // aargh - this should not happen usually System.out.println(e); e.printStackTrace(); } } public void sendMessage(TextMessage requestMsg, String serviceAvailable) throws NamingException, JMSException { // wait for some time InitialContext jndiContext = new InitialContext(); QueueConnectionFactory factory = (QueueConnectionFactory) jndiContext.lookup("ConnectionFactory"); QueueConnection connect = factory.createQueueConnection(); QueueSession session = connect.createQueueSession(false,Session.AUTO_ACKNOWLEDGE); Queue queue = (Queue)requestMsg.getJMSReplyTo(); QueueSender sender = session.createSender(queue); TextMessage message = session.createTextMessage(); // set the correlation ID message.setJMSCorrelationID(requestMsg.getJMSMessageID()); // set the text message.setText(serviceAvailable); sender.send(message); sender.close(); session.close(); connect.close(); } } 1.1 xml-axis-wsif/java/samples/jms/service/deploy/jboss/ejb-jar.xml Index: ejb-jar.xml =================================================================== <?xml version="1.0"?> <!DOCTYPE ejb-jar> <ejb-jar> <enterprise-beans> <message-driven> <ejb-name>ServiceAvailabilityBean</ejb-name> <ejb-class>jms.service.ServiceAvailabilityBean</ejb-class> <message-selector></message-selector> <transaction-type>Bean</transaction-type> <acknowledge-mode>Auto-acknowledge</acknowledge-mode> <message-driven-destination> <destination-type>javax.jms.Queue</destination-type> </message-driven-destination> </message-driven> </enterprise-beans> </ejb-jar> 1.1 xml-axis-wsif/java/samples/jms/service/deploy/jboss/jboss.xml Index: jboss.xml =================================================================== <?xml version="1.0"?> <jboss> <enterprise-beans> <message-driven> <ejb-name>ServiceAvailabilityBean</ejb-name> <configuration-name>Standard Message Driven Bean</configuration-name> <destination-jndi-name>queue/A</destination-jndi-name> </message-driven> </enterprise-beans> </jboss> 1.1 xml-axis-wsif/java/samples/jms/service/deploy/jboss/serviceavailability.jar <<Binary file>>