This MA0R SupportPac contains demonstrations of WebServices that use WebSphere MQ as a reliable transport mechanism. It has been tested and packaged for installation on Windows 2000, Windows XP and Linux systems only. It provides plugin transport for the Apache Axis WebServices framework and for the Microsoft .NET WebServices framework. It permits interoperation over a WebSphere MQ transport between clients and services written in either of these environments.
MQ brings reliability to WebServices, while still allowing the use of standard WebServices interfaces and development tools.
A WebSphere MQ service is identified by a uri containing 'wmq:xxx'. A client program calls the appropriate WebServices framework in the usual way. The framework marshalls the call into a SOAP request message exactly as for SOAP/HTTP. When the framework identifies the 'wmq:xxx' uri, it calls the WebSphere MQ transport sender code provided in MA0R. This is then transported to a listener also provided with MA0R. This listener reads the incoming SOAP request, and hands it to the appropriate WebServices infrastructure. This infrastructure parses the SOAP request message and invokes the service, exactly as it would have done for a message that arrived on an HTTP transport. It then marshalls the response into a SOAP response message and returns it to the MA0R listener. The listener returns the message over WebSphere MQ to the MA0R sender, which passes it to the client WebServices infrastructure. The client infrastructure parses the response SOAP message and hands the result back to the client application.
MA0R provides a simple demonstration that shows the use of the transport. It also provides helper functions for deployment of user written services with a WebSphere MQ transport.
'WebSphere', 'WebSphere MQ' and 'WebSphere Application Server' are trademarks of IBM Corporation.
'.NET', '.NET framework', '.NET framework SDK', 'Visual Studio .NET', 'Internet Information Server', 'IIS' are trademarks of Microsoft Corproation.
'Apache', 'Xerxes' and 'Axis' are trademarks of the Apache Foundation.
'Java' is a trademark of Sun Corporation.
Installation order in significant. Microsoft's Internet Information Services should be installed before the .NET framework. Please refer to http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/829/msdncompositedoc.xml for more information. If the .NET framework has been installed before IIS, problems can be resolved by running the 'aspnet_regiis' utility.
%SystemRoot%\Microsoft .NET\Framework\v1.0.3705 aspnet_regiis -i
If you do have to install IIS as part of this process you should reapply your Windows 2000 Service Pack immediately afterwards.
The Microsoft .NET Framework SDK and IIS are required to deploy and run .NET services; to modify or customize the demonstrations or build separate services. Microsoft Visual Studio .NET provides a useful IDE environment for such development but is not mandatory.
The Linux version of the SupportPac has been tested on Redhat Linux version 7.3, server installation.
MA0R requires around 6MB of space, plus extra during installation.
To install MA0R, unpack the downloaded distribution file into an appropriate directory. It will unpack into the 'ma0r' subdirectory, within which the SupportPac will be totally contained.
In addition to its own code, MA0R includes a copy of runtime components required execute WMQ/JMS, Apache Xerces (XML support) and Axis (WebServices support). These are provided to limit the number of prerequisites, and to ensure that the MA0R demonstration runs with a compatible collection of code. They should not be used for other purposes. They will not pollute any other programs running on the system using other copies of these executables, whether the same or different versions. To use 'standard' installed versions of these with MA0R, edit ma0r\bin\setcp.bat or ma0r/bin/setcp.sh as appropriate.
Before running any MA0R code, ensure that the prerequisites are properly set up,
To setup the user in Linux might be done by first using the id command to find the groups to which the user belongs and then using the usermod command to add the mqm group. For example:
# id jerry uid=200(jerry) gid=100(users) groups=100(users) # # usermod -g users -G users,mqm jerry # # id jerry uid=200(jerry) gid=100(users) groups=100(users),500(mqm) #
Some of the examples of script invokation in the remainder of the documentation the Windows syntax, where the '.bat' is not required. that
Execute ma0r\demos\runivt.bat or ma0r/demos/runivt.sh.
This will
The preparation will not be repeated if runivt is repeated. Preparation entails:
The Windows tests consist of:
The Linux version is the same as the above but with the .NET tests removed (i.e. the bottom 7 tests in the above list).
The source for the clients and services involved in the demonstration are in the ma0r/demos/javaDemos and ma0r/demos/dotnetDemos directories.
runivt runs one or all of the tests defined in the test configuration file. Separate test configuration files are provided for Windows (ivttests.txt) and Linux (ivttests_linux.txt). The test configuration file can be directly edited by any standard text editor.
runivt can be invoked with no arguments, in which case all tests are run. Alternatively it can be invoked with a list of required tests on the command line.
runivt DotNet DotNet2Axis
runivt automatically starts the servers that the tests require in separate (minimized) command windows. The default behaviour is that these servers are automatically closed down when runivt completes, but specification of an additional argument "hold" will cause runivt to hold the servers that it starts. Alternatively the argument "killall" requests runivt to attempt to kill all servers, even ones it did not create on this particular run. When runivt is executed, it polls to see if required servers are already running before attempting to start them. In this way multiple invocations of individual servers is avoided.
runivt lists the commands used for the clients and servers, and shows the replies from the servers to the clients. eg:
C:\temp\ma0rrun\ma0r\demos>runivt DotNet DotNet2Axis ----- [Dotnet] -------------------------------- WMQ transport test: C# to .NET (Asmx) +++ server: helpers\listen_StockQuoteDotNet --- client: SQCS2DotNet RPC reply is: 88.88 DOC reply is: 77.77 OK. ----- [Dotnet2Axis] -------------------------------- WMQ transport test: C# to Axis +++ server: helpers\listen_javaDemos.server.StockQuoteAxis --- client: SQCS2Axis SQCS2Axis RPC reply is: 55.25 OK. ---------------------------------- Service SimpleJMSListener: kill request accepted. Service DotNet: kill request accepted. endMQ.bat not implemented for Windows ... MQ left running. =========================================== 2 tests run, of which 0 failed.
runivt also checks the result of the call with the expected result and highlights any problems.
This section covers what is necessary to define and call you own WebServices using the WebSphere MQ transport for SOAP.
We have prepared of couple of additional directories that give extra illustration of running multiple WebSphere MQ hosted services: ma0r\demos\deployAxis and ma0r\demos\deployASMX. ma0r\demos\deployAxis\testDeployAxis.bad (or .sh) will lead you through the steps explained in this section. It will generally pause after each step; code a 'nopause' options to let the script run to completion without interaction.
Services are written as for SOAP/HTTP. See the documentation for the appropriate environment.
For java, any simple class may be used. See ma0r\demos\javaDemos\server\StockQuoteAxis.java for an example.
For .NET, the source must use the [WebService] and [WebMethod] attributes. See ma0r\demos\StockQuoteDotNet.asmx for an example.
There are currently some limitations
[WebMethod] [SoapRpcMethodAttribute("http://testThis");
Services are deployed by running deployWMQService.bat or deployWMQService.sh from the directory holding the source code for the service. This is also the directory in which the service will execute.
For Axis services, give the name of the Java source file. For .NET services, give the name of the .ASMX file. eg, the demos may be redeployed from running the following in the ma0r\demos directory.
..\bin\deployWMQService -m MQSOAP.DEMO.QM javaDemos\server\StockQuoteAxis.java ..\bin\deployWMQService -m MQSOAP.DEMO.QM StockQuoteDotNet.asmx
Deployment performs several actions. Most of the generated result is placed in the helpers subdirectory, which is created if necessary. See later sections for more details, or how to perform independent steps from the deployment process. Look at ma0r\demos\helpers (after runIvt, which will have performed deployment) for an example of the result of deployment.
ma0r\demos\helpers\classes\javaDemos\server\StockQuoteAxis.class
ma0r\demos\helpers\javaDemos.server.StockQuoteAxis_Wmq.wsdl
ma0r\demos\helpers\javaDemos\server\StockQuoteAxis_deploy.wsdd ma0r\demos\helpers\javaDemos\server\StockQuoteAxis_undeploy.wsdd ma0r\demos\helpers\server-config.wsdd
various Java files in ma0r\demos\helpers\javaDemos\server ma0r\demos\helpers\StockQuoteAxisService.cs ma0r\demos\helpers\StockQuoteAxisService.vb
various Java files in ma0r\demos\helpers\classes\javaDemos\server
SOAP.javaDemos.server.StockQuoteAxis
ma0r\demos\helpers\listen_javaDemos.server.StockQuoteAxis.bat
WMQ Process: SOAP.javaDemos.server.StockQuoteAxis WMQ Trigger Initiation Queue: SOAP.INITQ
The WSDL and the proxies generated from it will have the appropriate uri burned in call the service. eg:
wmq:SOAP.javaDemos.server.StockQuoteAxis@MQSOAP.DEMO.QM?connectQueueManager=MQSOAP.DEMO.QM
Now the proxies have been generated, clients can be written to call the services via the proxies. These clients can be written almost exactly as 'standard' SOAP/HTTP clients would be written in the environment; refer to documentation for the environment. The exception is that a single line must be coded in the client to register the WMQSOAP transport sender, so that the WebServices framework at the client environment is willing to accept the 'wmq:xxx' uri. The call must be
com.ibm.mq.ma0r.usage.Util.registerExtensions(); // for Java MQSOAP.MQWebRequest.Register(); // for C# MQSOAP.MQWebRequest.Register() ' for VB
Examples can be seen in the ma0r\demos\javaDemos\clients and ma0r\demos\dotnetDemos\clients subdirectories.
It is not necessary to use the proxies. Lower level calls can be used as appropriate to the environment. Examples of lower level Axis clients are included in
References to the MA0R and SOAP framework runtimes are always needed. To compile clients that use the proxies, it is necessary that the proxies are included.
For Java this involves ensuring that the appropriate helpers\classes is included at the front of the classpath. Also, the necessary MA0R and Axis classes must be defined. This is conveniently arranged by calling setcp. The following sequence (taken from regenDemos.bat, where the clients run in the same directory as the server is deployed) rebuilds the Java clients on Windows.
call ..\bin\setcp set classpath=helpers\classes;%classpath% javac -d classes javaDemos\clients\*.java
The following sequence (again taken from regenDemos.bat, where the clients run in the same directory as the server is deployed) rebuilds the C# and Visual Basic clients. In these cases we have chosen to compile the proxies as we compile the clients.
csc /lib:..\bin /r:MQSOAP.dll dotNetDemos\clients\SQCS2DotNet.cs helpers\*.cs vbc /libpath:..\bin /r:MQSOAP.dll /r:System.Web.Services.dll /r:System.XML.dll /r:System.dll dotNetDemos\clients\SQVB2DotNet.vb helpers\*.vb
(The vbc call should be on a single line. For some reason csc automatically includes required references, but vbc does not.)
Before clients are executed, listeners for the appropriate servers should be prepared. This may either achieved either
helpers\listen_javaDemos.server.StockQuoteAxis
start "MQ SOAP trigger monitor" runmqtrm -m MQSOAP.DEMO.QM -q SOAP.INITQ OR deployWMQService -m MQSOAP.DEMO.QM -c startWMQMonitor silly
For Java clients, you must make sure the Axis framework is aware of WMQ by calling clientConfig.bat (or .sh). This will create or update client-config.wsdd in the client directory. clientConfig is only required once for each client directory. Ensure that the correct classpath, including the . eg:
call ..\bin\clientConfig call ..\bin\setcp set classpath=helpers\classes;%classpath% java javaDemos.clients.SQAxis2Axis
MA0R provides a utility runJavaClient.bat to simplify this for the demos. eg.
runJavaClient SQAxis2Axis
For C# and Visual Basic clients, the appropriate .EXE file may be invoked directly, eg.
SQVB2DotNet
It is necessary to be very careful using our current deployment conventions when calling an Axis service from an Axis client, and where both client and service execute in the same directory. A sample service (eg javaDemos.service.StockQuoteAxis) will generate proxies in the same package as the service, and one of the proxy files has the same class name as the original service. It is essential that the classpath is set up correctly so that the client sees the proxy (eg ???\helpers\classes in the classpath will find ma0r\demos\helpers\classes\javaDemos\server\StockQuoteAxis.class), and that the server sees the orignal implementation (eg ???\classes in the classpath will find ma0r\demos\classes\javaDemos\server\StockQuoteAxis.class).
The current SupportPac is not complete. We are aware of various limitations, including those listed below. Inclusion of an item in this list does not necessarily imply that the limitation will be removed in later versions; but it may save you wasting time trying to get something working that is not supported.
We anticipate the release of compatible service support by a future release of WebSphere Application Server. This will host the listeners as Message Driven Beans (MDBs), and use the conventional J2EE application context framework. This coherent application server framework will be more convenient for large scale deployments, and should give more control over details such as the number of instances of each service, and transactional support.
The WebSphere MQ Transport for SOAP uses a URI of the format
WMQ names within the URI are case sensitive, but the keywords are case insensitive. The queueName and queueManagerName are used at the client to open the queue for sending the request message. Normal WMQ MQOPEN conventions are used. If the queueManagerName is not specified, the queueName must be defined at the queue manager to which the client is connected.
Future releases may add to the list of options: for example to support Priority and similar features. Clients should tolerate unexpected options, and will not flag them.
Connection using a WebSphere MQClient is not currently implemented for .NET clients, and has not been tested for Axis clients.
The demonstration is most easily run on a single machine, with both client and service using the same queue manager. That is they way it will run using the simple 'out of the box' demonstrations.
To make this operate over machine (or even queue manager) boundaries requires standard JMS/MQ configuration. The simplest option is to make all queue managers part of a single MQ cluster. Define the service queue (eg SOAP.javaDemos.server.StockQuoteAxis) for request messages as a cluster queue at the server machine, so that it can be seen by each requesting client. Define the response queues (MQSOAP.DEMO.RESPONSE) as local queues at the client machines, so that each client machine has its own local reply queue.
This is best where all queue managers are set up as default queue managers. No connectToQueueManager need then be specified. The client and server will naturally connect to the appropriate local queue manager, and WMQ distribution will move the messages between the queue managers.
The primary purpose of the URI is to inform the client how to address the target service. The same URI format may be used to configure the server, with different interpretation of the fields. In simple configurations this means the same URI content for the server as for the client. In distributed configurations a different URI may need to be used. This application of the URI at the server end will be formalised and made more consistent in future versions of the SupportPac.
There are many other options. These are not affected by the message payload consisting of a WebServices message. They depend instead on the particular application and MQ requirements at a given installation, so they are not described here.
clientConfig prepares a client directory for Axis clients to make calls using the WMQSOAP transport. It creates or updates client-config.wsdd in the current directory. It needs be called only once for each client directory.
This prepares code for use as a WebService using SOAP format and WebSphere MQ transport. deployWMQService should be called in the directory in which the source exists, and in which the service is expected to execute.
Call
Argument
Options:
Outputs:
Where the fileName is given, complete with the .java or .asmx extension, the operation defaults to allAxis or allAsmx respectively.
quietOK.bat is a utility that executes a command. If the command is successful, no output is produced. If the command fails, the stdout and stderr streams are displayed at the console. It should not usually be called by the end user.
RegisterDotNet.bat is a utility to register the code for the WMQSOAP .NET support. It should not usually be called by the end user.
setcp checks the environment and sets up the PATH and CLASSPATH.
setcp adds necessary directories to PATH. setcp replaces CLASSPATH with a new copy to give a sandboxed Java environment.
This has been outlined in the earlier Demo section. Here are some additional details. More details will be provided in future releases.
This runs a simple HTTP listener for running SOAP/Axis tests over HTTP transport. This is a minor extension to the standard Axis provided org.apache.axis.transport.http.SimpleAxisServer, with an initial startup message and kill ability.
SimpleAxisServerX may be terminated with "java com.ibm.mq.ma0r.util.Killme -s SimpleAxisServerX"
This can kill the provided servers, using the arguments "SimpleJMSListener", "JMSService" or "SimpleAxisServerX". A list of multiple servers to kill may be given in tne invocation.
The Java utility com.ibm.mq.ma0r.util.Killme can also be invoked to shut down servers if it is not required to execute any more IVT tests. The test name is specified with the "-s" parameter, for example:
java com.ibm.httpr.util.Killme -s DotNet
A bat file wrapper killit.bat (killit.sh on Linux) has been written to make this slightly easier. In the above example this would be invoked as:
killit -s DotNet
This can any of the provided servers, using arguments "SimpleJMSListener", "JMSService" or"SimpleAxisServerX". Neither the direct Java invocation or the bat file are case sensitive with regard to the server names. Multiple services can be killed by listing the service names within double quotes in the form:
killit -s "<service1> <service2>"
A further bat file, killall.bat, has also been supplied which kills all three of the above services on the local system without having to specify any arguments. This is also available on Linux as killall.sh.
To execute the IVT and run all tests, simply invoke the
runivt.bat or runivt.sh script that is located in the demos
directory. For example:
To run all tests, but keep the servers running after the IVT completes use the command "runivt hold".
To execute just the dotnet test and terminate all servers after the test completes, use the command "runivt dotnet killall".
To manually kill the dotnet server without running any further tests, use the command:
java com.ibm.httpr.util.Killme -s SimpleHTTPRListener
WMQSoapGui is a graphical user interface program that incorporates some of the above DOTNET client demonstrations into a single program, and also demonstrates asynchronous calls.
To use this test program first make sure that the servers that it is required to use from the program are already running. The quickest way to do this is with runIVT.
runivt dotnet dotnet2axis hold
To start the gui demo, ensure you are working in the demos directory and execute the program WMQSoapGui.exe.
The GUI demonstration uses the same StockQuoteAxis and StockQuoteDotNet services used by the rinIvt. These take an input String parameter that represents the name of a type of Stock and returns a real value that is supposed to represent the amount of that Stock that has been purchased. The service simply returns a hardcoded value (Axis service returns 55.25, .NET service 88.88).
The "Server Type" radio buttons are used to specify whether connection should be attempted to a Java or .NET service.
The three buttons underneath the server and protocol radio buttons are action buttons. The left two buttons each cause a simple call; to demonstrate synchronous and asynchronous connection to the service. The right button is mentioned below. When the button are pressed independently and with plenty of gaps, there is no appreciable difference between synchronous and asynchronous invokations.
The impact of synchronous and asynchronous client operation can be demonstrated by using the .NET server. For this server, when the Stock name "DELAY" is entered as a stock name the target service sleeps for a hard coded period of 5 seconds. Calling an Axis service during this period will show that the GUI is not locked out; and the Axis service may well respond before the .NET one.
This can more easily be shown by using the right hand 'Synchronous Breaking" action button. This calls the .NET service asynchronously with the stock name "DELAY", sleeps for 1 second, and then calls the Axis service.
The "MQ Tracing" check box is provided to give call history information when using MQ transport. This is mainly for diagnostic use, and demonstrates the multi-threading that the .NET framework causes during asynchronous operations.