Artificial intelligence, machine learning, neural networks. We're in the midst of a wave of excitement around AI such as hasn't been seen for a few decades. But those previous periods of inflated expectations led to troughs of disappointment. This time is (mostly) different. Applications of AI such as predictive analytics are already decreasing costs and improving reliability of industrial machinery. Pattern recognition can equal or exceed the ability of human experts in some domains. It's devel...| By Parameswaran Seshan | Article Rating: |
|
| August 24, 2006 10:00 AM EDT | Reads: |
28,047 |
Unlike the HTTP protocol there's no stable default JMS listener for invoking the Web Services exposed in Apache Axis 1.x using JMS (Java Message Service) as the transport protocol - other than the one provided merely for demo purposes.
This article describes a fully working generic JMS listener that can act as a JMS transport receiver handler for Axis and allow service clients to uniquely address individual Web Services in a JMS way and invoke them over JMS.
Apache Axis is a popular Java-based Open Source platform for exposing Web Services. It has native support for handling invocations into Web Services based on the SOAP (Simple Object Access Protocol) application protocol. By default, the Axis server supports HTTP as the protocol for transporting the SOAP payload and provides an HTTP transport listener to do the same on its own. The HTTP transport listener accepts the SOAP requests coming over HTTP and then hands off the SOAP payload to the Axis engine for application-level handling of the request (like SOAP parsing, extracting input parameters, invoking the right service implementation, etc.), and gets the response SOAP message from the Axis engine and sends it back to the caller in the HTTP response.
For those enterprise applications where reliable invocation and guaranteed delivery of invocation messages are important, JMS, rather than HTTP, is the preferred protocol for transporting SOAP messages. JMS implementation providers, with built-in reliability features like re-try mechanisms, ensure that messages reach the message consumer application whatever the case. JMS is also the best way to handle asynchronous invocations of Web Services.
However, what Axis 1.x provides for JMS transport protocol use is only a basic demo listener that's not really meant for production-level use. This listener is also not easy to use and isn't flexible enough to be able to specify and handle unique endpoint addresses for each individual Web Service exposed. So, for client applications that need to invoke the Axis Web Services over JMS a flexible, stable, and easy-to-use JMS transport listener and handler is required.
This article implements a generic JMS listener and describes how it is to be used along with the Axis server. For purposes of this paper, I've considered the Open Source frameworks Apache Axis 1.2 and JMS provider OpenJMS 0.7.6.1. However, this should be largely applicable to the higher versions of Axis in the 1.x series too.
The Addressing Model
In an Axis server, each Web Service is described in the server-config.wsdd file and the service name mentioned there becomes part of the concrete HTTP URL (concrete port binding) for accessing the Web Service. For example, to access a "StockQuoteService" defined in the server-config.wsdd of the Axis server running in host www.samplehost.com, the default HTTP URL would be www.samplehost.com/axis/Services/StockQuoteService. Each Web Service similarly defined in server-config.wsdd will have a unique access URL like the one above with the first portion of the URL, i.e., http://www.samplehost.com/axis/Services/, remaining the same. In this sense, each Web Service will be addressed with a unique HTTP destination.
We can choose to follow a similar model for exposing the same Web Services over the JMS transport protocol. In other words, each service endpoint will be available at a unique JMS destination (aka a queue). So for each Web Service defined in the Axis server, we define a separate queue in the JMS provider - in our case OpenJMS - and update the openjms.xml file in the config folder of the OpenJMS home for defining one queue for each Axis-deployed Web Service that's meant to be accessible over JMS. In this article, the approach taken is to use the service name defined in Axis itself as the queue name (similar to the HTTP concrete binding mentioned above). For example, for the sample Web Service called "MessageService" provided in the Axis distribution, we can define a queue with the same name putting the entry <AdministeredQueue name="MessageService"/> in openjms.xml.
This addressing model applies uniformly to both RPC-style and message-style Axis services. It's more straightforward and standards-compatible with the WSDL specs. The JMS destination for each Web Service becomes the address in the concrete port binding for the service and the Web Service clients can directly use this concrete JMS destination mentioned in the WSDL file for invoking the service.
This is a better model than the non-standard way of specifying the Axis Web Service name as the prefix in the request SOAP message body's first XML element. For example, for the invocation of the method "getQuote" in the Axis sample Web Service named "urn:xmltoday-delayed-quotes," which is an RPC-style service, the basic JMS listener provided in the Axis distribution expects the client to create the SOAP body element <urn:xmltoday-delayed-quotes:getQuote> containing the service name as the XML prefix.
The client does this through code similar to call.setOperationName(new QName("urn:xmltoday-delayed-quotes:getQuote", "getQuote")). This fact doesn't appear in the WSDL definition of the service hence interoperability with different external service clients could become an issue. It's best to stick to the details given in the WSDL file and with the new service endpoint addressing scheme introduced here, all the clients can, in a standard way, just keep the first SOAP body element as <getQuote> following the WSDL details alone, thereby improving interoperability.
The Role of JMS Listener
The JMS listener is a server-side component that needs to listen to incoming JMS messages containing SOAP messages at the defined JMS queue. These SOAP messages are request messages coming from service clients that are trying to invoke the Web Service(s). Once the JMS message is received, the onMessage() method in the listener needs to get the message content which is the SOAP XML payload, and invoke the Axis engine supplying the SOAP XML message and also specifying to Axis the name of Web Service that's being invoked. This handing over of the SOAP message to Axis server is the key responsibility of this listener.
Then, if the client expects a response back from the Web Service (such as in a pseudo-synchronous call), the JMS listener needs to get the SOAP response message from the Web Service and put it as the payload in a new JMS message and send this message to the JMS queue destination the client is waiting on. This JMS listener can be used for receiving requests of both RPC-style and document-style Web Services invocations since it doesn't read and interpret the SOAP message at all; it just sticks to its role as a transport-level handler.
Implementing the Listener
Now we'll look at the implementation of the JMS listener. To realize the addressing model described above, the approach is to have one instance of the listener class GenericJMSSOAPListenerForAxis for each Axis Web Service. This class that implements javax.jms.MessageListener is a generic listener for JMS Web Service requests. I'll explain the salient parts of this class in this section and the next. The full source code of this and other classes discussed here is available for download in the resources section.
First the constructor of this class needs to register with OpenJMS for receiving messages in the queue defined for this Web Service. The constructor takes the Web Service name as an input argument. A static initialization block is used to instantiate the Axis engine and this gets executed when the Java Virtual Machine (JVM) loads the GenericJMSSOAPListenerForAxis. All the instances of this class have to use the same Axis engine instance.
...
public GenericJMSSOAPListenerForAxis(String webserviceName)
{
...
this.webserviceName = webserviceName;
...
}
AxisJMSListenersStarter class's main method starts the listeners by reading the XML file "jmswebsvcs.xml" that contains the list of Axis Web Services, creating and starting one instance of GenericJMSSOAPListenerForAxis for each service in the list by passing the name of the Web Service as an argument to the constructor. In effect this dynamically creates the concrete service endpoint destinations for the JMS protocol, since each Web Service now gets a unique concrete address.
public static void main(String[] args)
{
// Read the JMS Web Services names from the xml file.
...
org.w3c.dom.Document servicesListDoc = db.parse(inFileFullPath);
org.w3c.dom.NodeList servicesList = servicesListDoc.getDocumentElement().getElementsByTagName("service");
for (int k = 0; k < servicesList.getLength(); k++)
{
String webSvcName = ((org.w3c.dom.Element) servicesList.item(k)).getFirstChild().getNodeValue();
new GenericJMSSOAPListenerForAxis(webSvcName);
}
...
Now let's look at the message-handling logic in the GenericJMSSOAPListenerForAxis that's instantiated for a particular Web Service, say, "MessageService." Its onMessage() method is called once the message arrives in the queue named "MessageService." After creating the Axis MessageContext for the message the onMessage method sets the serviceHandler field of the MessageContext to tell Axis that the Web Service being invoked is "MessageService" and that for executing service-specific functionality, the service implementation class, as defined in the server-config.wsdd, for service name "MessageService" should be invoked.
public void onMessage(javax.jms.Message inMsg)
{
...
axisMsgCtxt.setRequestMessage(axisSoapMessage);
// Set the target Web Service in the Axis message context to indicate that this message should
// go to the Axis webservice named <webserviceName> for which this queue is receiving messages.
axisMsgCtxt.setTargetService(webserviceName);
...
}
This method then sends the response SOAP message to the JMS client. However, at this point no correlation id is used. For simplicity's sake it's assumed here that the client, after sending the message, waits on a receive queue expecting to get a response message for the Web Service invocation it just made. This listener class can easily be extended to refer to and use a client-specified JMS correlation id to send a correlated response to the client.
Invoker-side implementation
Now let's look at some key aspects on the client side of the invocation. The classes written for the client side are JMSTestClientRPC, MyJMSTransportForAxis, JMSTestClientMessageStyle - which are client classes that invoke RPC- and message-style services respectively, for example they respectively invoke the services "urn:xmltoday-delayed-quotes" of samples.stock and "MessageService" of samples.message packages, the samples available in the Axis distribution - and MyJMSSender - which are the JMS transport handlers for the client side. JMSTestClientRPC makes a call using the Axis Call object to a given RPC Web Service using JMS as the transport. Hence it specifies the unique target endpoint JMS address defined for that particular Web Service, for example, here "urn:xmltoday-delayed-quotes." Please note that the RPC operation name is set with just the method name as given in the WSDL file and no service name prefix. The Axis Call object has to be told that a JMS transport handler needs to be used for this invocation. This handler class is instantiated and attached to the call here. If this value isn't set, Axis will use the HTTP transport handler by default. For both RPC- and message-style invocation, the same MyJMSTransportForAxis and MyJMSSender classes are used and connected via an entry made in the client-config.wsdd file available in the client classpath. MyJMSTransportForAxis class helps Axis locate this entry in the client-config.wsdd. MyJMSSender's job is to actually send the SOAP message as a JMS message to the Web Service queue destination specified here and get the response from the response queue.
...String webSvcJMSDestination = "urn:xmltoday-delayed-quotes";
axisCall.setProperty(org.apache.axis.transport.jms.JMSConstants.DESTINATION, webSvcJMSDestination);
axisCall.setOperationName("getQuote");
...org.apache.axis.client.Transport transport = new MyJMSTransportForAxis();
axisCall.setTransport(transport);
...
Published August 24, 2006 Reads 28,047
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Parameswaran Seshan
Parameswaran Seshan performs the role of an independent educator/trainer, architect, researcher, and architecture consultant, in Information Technology (IT). He teaches architecture, design and technology related courses. Prior to this, he worked as Principal (Education and Research) with E-Comm Research Lab, Infosys Technologies Limited, Bangalore, India. He has more than 15 years of work experience in the IT industry, involving teaching, architecture, research, and programming. His areas of interest include Enterprise Architecture, Process-centric architecture, Intelligent software systems, Intelligent agents, software architecture, Business Process Management systems, Web services and Java. You can reach Parameswaran at, contact {at} bitsintune [dot] com.
Artificial intelligence, machine learning, neural networks. We're in the midst of a wave of excitement around AI such as hasn't been seen for a few decades. But those previous periods of inflated expectations led to troughs of disappointment. This time is (mostly) different. Applications of AI such as predictive analytics are already decreasing costs and improving reliability of industrial machinery. Pattern recognition can equal or exceed the ability of human experts in some domains. It's devel...Mar. 17, 2019 03:15 AM EDT |
By Courtney Abud Where many organizations get into trouble, however, is that they try to have a broad and deep knowledge in each of these areas. This is a huge blow to an organization's productivity. By automating or outsourcing some of these pieces, such as databases, infrastructure, and networks, your team can instead focus on development, testing, and deployment. Further, organizations that focus their attention on these areas can eventually move to a test-driven development structure that condenses several l...Mar. 17, 2019 03:00 AM EDT |
By Liz McMillan The term "digital transformation" (DX) is being used by everyone for just about any company initiative that involves technology, the web, ecommerce, software, or even customer experience. While the term has certainly turned into a buzzword with a lot of hype, the transition to a more connected, digital world is real and comes with real challenges.
In his opening keynote, Four Essentials To Become DX Hero Status Now, Jonathan Hoppe, Co-Founder and CTO of Total Uptime Technologies, shared that ...Mar. 17, 2019 02:00 AM EDT |
By Yeshim Deniz Mar. 16, 2019 10:00 PM EDT |
By Elizabeth White Mar. 16, 2019 09:00 PM EDT |
By Liz McMillan Mar. 16, 2019 03:45 PM EDT |
By Liz McMillan Mar. 16, 2019 03:00 PM EDT |
By Yeshim Deniz Mar. 16, 2019 01:00 PM EDT |
By Zakia Bouachraoui The Japan External Trade Organization (JETRO) is a non-profit organization that provides business support services to companies expanding to Japan. With the support of JETRO's dedicated staff, clients can incorporate their business; receive visa, immigration, and HR support; find dedicated office space; identify local government subsidies; get tailored market studies; and more.Mar. 16, 2019 12:15 PM EDT |
By Zakia Bouachraoui Mar. 16, 2019 12:00 PM EDT |


Where many organizations get into trouble, however, is that they try to have a broad and deep knowledge in each of these areas. This is a huge blow to an organization's productivity. By automating or outsourcing some of these pieces, such as databases, infrastructure, and networks, your team can instead focus on development, testing, and deployment. Further, organizations that focus their attention on these areas can eventually move to a test-driven development structure that condenses several l...
The term "digital transformation" (DX) is being used by everyone for just about any company initiative that involves technology, the web, ecommerce, software, or even customer experience. While the term has certainly turned into a buzzword with a lot of hype, the transition to a more connected, digital world is real and comes with real challenges.
In his opening keynote, Four Essentials To Become DX Hero Status Now, Jonathan Hoppe, Co-Founder and CTO of Total Uptime Technologies, shared that ...
The Japan External Trade Organization (JETRO) is a non-profit organization that provides business support services to companies expanding to Japan. With the support of JETRO's dedicated staff, clients can incorporate their business; receive visa, immigration, and HR support; find dedicated office space; identify local government subsidies; get tailored market studies; and more.
"Calligo is a cloud service provider with data privacy at the heart of what we do. We are a typical Infrastructure as a Service cloud provider but it's been des...
As software becomes more and more complex, we, as software developers, have been splitting up our code into smaller and smaller components. This is also true for the environment in which we run our code: going from bare metal, to VMs to the modern-day Cloud Native world of containers, schedulers and micro services. While we have figured out how to run containerized applications in the cloud using schedulers, we've yet to come up with a good solution to bridge the gap between getting your containers from your laptop to the cloud.
How do we build software for containers? How do we ship containe...
DevOps with IBMz? You heard right. Maybe you're wondering what a developer can do to speed up the entire development cycle--coding, testing, source code management, and deployment-? In this session you will learn about how to integrate z application assets into a DevOps pipeline using familiar tools like Jenkins and UrbanCode Deploy, plus z/OSMF workflows, all of which can increase deployment speeds while simultaneously improving reliability. You will also learn how to provision mainframe system as cloud-like service.
Bill Schmarzo, author of "Big Data: Understanding How Data Powers Big Business" and "Big Data MBA: Driving Business Strategies with Data Science" is responsible for guiding the technology strategy within Hitachi Vantara for IoT and Analytics. Bill brings a balanced business-technology approach that focuses on business outcomes to drive data, analytics and technology decisions that underpin an organization's digital transformation strategy.
Bill has a very impressive background which includes CTO at Dell EMC, Vice President of Advertiser Analytics at Yahoo! and Vice President of Analytic App...
Serverless Computing or Functions as a Service (FaaS) is gaining momentum. Amazon is fueling the innovation by expanding Lambda to edge devices and content distribution network. IBM, Microsoft, and Google have their own FaaS offerings in the public cloud. There are over half-a-dozen open source serverless projects that are getting the attention of developers.
DevOps solutions are tying together increasingly complex tools that can be hard to manage and monitor. To check on the health of your processes you need to be dialed in to your source code, artifact management, continuous integration, delivery and deployment, static code analysis, security analysis, monitoring health, infrastructure and test automation, just to name a few. Come see how to aggregate your view of the DevOps world in practice.
Modern software design has fundamentally changed how we manage applications, causing many to turn to containers as the new virtual machine f...


















