SOAP Support for WebSphere MQ


The previous sections showed what's required to make existing JMS components and objects interoperate with .NET. Let's now look at the possible future for interoperability with WebSphere MQ. After reading the chapter, you'll no doubt agree that although today's developers can achieve tactical .NET and J2EE interoperability solutions with WebSphere MQ, one could make an argument for a more strategic approach.

Let's examine two options that promote the use of SOAP over WebSphere MQ. The first option is to use the product that we've used for Web services throughout the book, GLUE. This approach is similar to the MDB sample. The second option is to use another SupportPac from IBM, MA0R. This SupportPac shows a technical preview of using SOAP to host Web services by using both .NET and Apache Axis.

SOAP/JMS Support in GLUE

If you've been looking through the GLUE documentation that accompanies the libraries on the companion CD, you might have noticed that GLUE 4.0.1 shows support for JMS. This support allows the use of GLUE to create synchronous and asynchronous SOAP messages over JMS and provides integration with the J2EE Reference Implementation.

In short, this allows a message queue (such as WebSphere MQ) to be placed between a GLUE client and Web service by using the JMS API and the underlying provider transport instead of HTTP. Figure 9.20 illustrates this best. In the figure, the logical applications created by GLUE ( Service1 and Service2 ) are hosted using a system queue in WebSphere MQ.

click to expand
Figure 9.20: JMS support in GLUE and interoperability with WebSphere MQ.

In addition to WebSphere MQ, out of the box, GLUE supports adapters for other message queuing software, including SonicMQ, TIBCO, and SwiftMQ. By providing adapters that contain specific information about the queuing product itself, GLUE is able to connect without needing to know any additional configuration information.

Running the Sample Code

To show how GLUE works with JMS, let's look at the sample code, located in the C:\Interoperability\Samples\Resource\WMQ\GlueJMS directory. Using the same scenario as the earlier MDB sample, the sample code works by using JMS to listen for incoming messages and then making a Web service call to .NET. Because we're using the SYSTEM queues and calling JMS without referencing JNDI and/or JBoss, the setup is that shown in Figure 9.21. Notice how the calls between the GLUE client and Web service are asynchronous (taking advantage of the queue) and how the .NET Web service call uses a request/response mechanism.

click to expand
Figure 9.21: Asynchronous call styles between the services using GLUE's support for JMS.

The GLUE server side of the sample is contained within the Server subdirectory. Build and run the sample code in a separate command prompt window; this can easily be done by entering start ant run at the command prompt.

 using MQSeries JMS provider 

One of the nice features of GLUE is that it automatically detects which message queue libraries are in the CLASSPATH without forcing a developer to supply configuration information. Because the MQSeries libraries are in the CLASSPATH here, the provider is automatically loaded.

After the server is running in a separate window, navigate to the client directory. Then build and run the client sample, using the provided Ant script with the run target. The sample will create two stock recommendations (one sale and one purchase) and will use the GLUE JMS provider to make an asynchronous call. The client makes the call and waits for 10 seconds:

 Waiting for 10 seconds... 

While the client is waiting, switch to the server process. The StockServerAsync class uses the same agent and logic as the MDB example presented earlier in this chapter. Once the client has decided whether a stock should be purchased, the appropriate call is made to the .NET Web service. On the other hand, we simulate the Java Web service because the sell operation is handled locally:

 Reading the mappings for the StockService Stock agent is binding to the .NET Web Service This will be handled locally... Calling Buy Stocks method 

After the 10 seconds elapse, the client reconnects and checks the asynchronous response for the two calls. Based on the result from the call, the client can determine whether the recommendation invoked a call to the .NET Web service:

 Checking for the result... The async purchase of Lucerne Publishing was made with the  .NET Web Service call The async sale of Coho Winery was not made with the  .NET Web Service call 

You can see that the purchase was indeed forwarded to the .NET Web service, whereas the sale was handled locally by GLUE.

Key Elements of the GLUE Sample

If you've used any of the GLUE sample code in the earlier chapters, you'll have noticed that the following line is used to publish a Web service by using the HTTP transport:

 HTTP.startup("http://localhost:8004/JavaWebService"); Registry.Publish("StockService", new StockService()); 

Within GLUE, the mechanism used to publish the service via JMS is very similar:

 JMS.startup("jms:///StockServiceAsync"); Registry.publish("StockServiceAsync",new StockServiceAsync()); 

This can be very useful for the Web services that need to be published via both HTTP and JMS because it gives developer a similar set of interfaces to use.

The GLUE client follows a similar pattern. In the sample, the following URL is used to bind to the Web service exposed by JMS:

 jms:///StockService/StockServiceAsync.wsdl 

Notice how the URL doesn't contain a hostname . Because GLUE support for JMS is for local clients only, no concept of a remote call exists and no hostname is required. To get the asynchronous callback working, the client defines and uses a class of type electric.util.async.Async :

 Async asyncBuy = new Async(); 

This Async object is passed as part of the method call:

 ss.AddRecommendation(LUCP,"buy",asyncBuy); 

The client can now leave and potentially run other tasks while this message is dealt with on the server side. To check the status of the call, the Async object is used again ”this time calling the getResponse method:

 boolean buyResult      = ((Boolean)asyncBuy.getResponse()).booleanValue(); 

The result from the asynchronous call is cast correctly and is returned to the client.

SOAP/JMS Messages and Interoperability with .NET

Apart from the different programming model, one thing that differentiates this sample from the MDB sample shown earlier is the message format on the wire. The GLUE JMS provider sends the message between the client and the server as a JMS BytesMessage. (You saw this earlier in the chapter in the discussion of message types.) The content of the message is actually a SOAP message.

You can see this by examining the SYSTEM.DEFAULT.LOCAL.QUEUE queue, until the queue is cleared. (You can see system queues in WebSphere MQ Explorer by right-clicking the Queues folder and selecting View/Show System Objects.)

The message, which can be viewed from the Data tab of the message's Properties window, contains the header information and JMS message payload shown earlier:

 52 46 48 20 00 00 00 02  RFH .... 00 00 00 AC 00 00 01 11  ....... 00 00 04 B8 20 20 20 20  ...     20 20 20 20 00 00 00 00      .... 00 00 04 B8 00 00 00 20  ......  3C 6D 63 64 3E 3C 4D 73  <mcd><Ms 64 3E 6A 6D 73 5F 62 79  d>jms_by 74 65 73 3C 2F 4D 73 64  tes</Msd 3E 3C 2F 6D 63 64 3E 20  ></mcd>  00 00 00 60 3C 6A 6D 73  ...`<jms 3E 3C 44 73 74 3E 71 75  ><Dst>qu 65 75 65 3A 2F 2F 2F 53  eue:///S 59 53 54 45 4D 2E 44 45  YSTEM.DE 46 41 55 4C 54 2E 4C 4F  FAULT.LO 43 41 4C 2E 51 55 45 55  CAL.QUEU 45 3C 2F 44 73 74 3E 3C  E</Dst>< 54 6D 73 3E 31 30 34 39  Tms>1049 39 32 32 39 30 34 31 39  92290419 36 3C 2F 54 6D 73 3E 3C  6</Tms>< 44 6C 76 3E 32 3C 2F 44  Dlv>2</D 6C 76 3E 3C 2F 6A 6D 73  lv></jms 3E 20 20 20 3C           > 

After this header, however, you can actually see the SOAP message, as shown next . This message is the false value returned from the GLUE Web service presented earlier.

 3F 78 6D      <?xm 6C 20 76 65 72 73 69 6F  l versio 6E 3D 27 31 2E 30 27 20  n='1.0'  65 6E 63 6F 64 69 6E 67  encoding 3D 27 55 54 46 2D 38 27  ='UTF-8' 3F 3E 0D 0A 3C 73 6F 61  ?>..<soa 70 3A 45 6E 76 65 6C 6F  p:Envelo 70 65 20 78 6D 6C 6E 73  pe xmlns 3A 78 73 69 3D 27 68 74  :xsi='ht 74 70 3A 2F 2F 77 77 77  tp://www 2E 77 33 2E 6F 72 67 2F  .w3.org/ 32 30 30 31 2F 58 4D 4C  2001/XML 53 63 68 65 6D 61 2D 69  Schema-i 6E 73 74 61 6E 63 65 27  nstance' 20 78 6D 6C 6E 73 3A 78   xmlns:x 73 64 3D 27 68 74 74 70  sd='http 3A 2F 2F 77 77 77 2E 77  ://www.w 33 2E 6F 72 67 2F 32 30  3.org/20 30 31 2F 58 4D 4C 53 63  01/XMLSc 68 65 6D 61 27 20 78 6D  hema' xm 6C 6E 73 3A 73 6F 61 70  lns:soap 3D 27 68 74 74 70 3A 2F  ='http:/ 2F 73 63 68 65 6D 61 73  /schemas 2E 78 6D 6C 73 6F 61 70  .xmlsoap 2E 6F 72 67 2F 73 6F 61  .org/soa 70 2F 65 6E 76 65 6C 6F  p/envelo 70 65 2F 27 20 78 6D 6C  pe/' xml 6E 73 3A 73 6F 61 70 65  ns:soape 6E 63 3D 27 68 74 74 70  nc='http 3A 2F 2F 73 63 68 65 6D  ://schem 61 73 2E 78 6D 6C 73 6F  as.xmlso 61 70 2E 6F 72 67 2F 73  ap.org/s 6F 61 70 2F 65 6E 63 6F  oap/enco 64 69 6E 67 2F 27 3E 3C  ding/'>< 73 6F 61 70 3A 42 6F 64  soap:Bod 79 20 73 6F 61 70 3A 65  y soap:e 6E 63 6F 64 69 6E 67 53  ncodingS 74 79 6C 65 3D 27 68 74  tyle='ht 74 70 3A 2F 2F 73 63 68  tp://sch 65 6D 61 73 2E 78 6D 6C  emas.xml 73 6F 61 70 2E 6F 72 67  soap.org 2F 73 6F 61 70 2F 65 6E  /soap/en 63 6F 64 69 6E 67 2F 27  coding/' 20 78 6D 6C 6E 73 3A 73   xmlns:s 6F 61 70 3D 27 68 74 74  oap='htt 70 3A 2F 2F 73 63 68 65  p://sche 6D 61 73 2E 78 6D 6C 73  mas.xmls 6F 61 70 2E 6F 72 67 2F  oap.org/ 73 6F 61 70 2F 65 6E 76  soap/env 65 6C 6F 70 65 2F 27 3E  elope/'> 3C 6F 62 6A 65 63 74 20  <object  78 6D 6C 6E 73 3A 78 73  xmlns:xs 69 3D 27 68 74 74 70 3A  i='http: 2F 2F 77 77 77 2E 77 33  //www.w3 2E 6F 72 67 2F 32 30 30  .org/200 31 2F 58 4D 4C 53 63 68  1/XMLSch 65 6D 61 2D 69 6E 73 74  ema-inst 61 6E 63 65 27 20 78 6D  ance' xm 6C 6E 73 3A 78 73 64 3D  lns:xsd= 27 68 74 74 70 3A 2F 2F  'http:// 77 77 77 2E 77 33 2E 6F  www.w3.o 72 67 2F 32 30 30 31 2F  rg/2001/ 58 4D 4C 53 63 68 65 6D  XMLSchem 61 27 20 78 73 69 3A 74  a' xsi:t 79 70 65 3D 27 73 6F 61  ype='soa 70 65 6E 63 3A 62 6F 6F  penc:boo 6C 65 61 6E 27 3E 66 61  lean'>fa 6C 73 65 3C 2F 6F 62 6A  lse</obj 65 63 74 3E 3C 2F 73 6F  ect></so 61 70 3A 42 6F 64 79 3E  ap:Body> 3C 2F 73 6F 61 70 3A 45  </soap:E 6E 76 65 6C 6F 70 65 3E  nvelope> 

This message has some interesting possibilities for interoperability with .NET. Recall how the MA7P SupportPac (the .NET classes) used bytes messages without the JMS header when they wrote to the queue. In theory, you could build a .NET client that uses the MA7P SupportPac today, accepts these types of incoming messages, strips off the JMS header section, and deserializes the SOAP envelope into a request it can understand. This could work equally well with requests coming from .NET.

I haven't seen this technique tested , but it's worth contemplating for projects that require this level of custom interoperability. For such interoperability to be a success, you'd have to ensure that the JMS header information is correctly understood and translated (which might take some testing with multiple vendor implementations ). However, this method does offer some interesting possibilities for achieving SOAP-based interoperability by using JMS.

IBM SupportPac MA0R

IBM released SupportPac MA0R around the same time that it released its MA7P SupportPac (the WebSphere MQ classes for .NET presented earlier in the chapter). SupportPac MA0R is titled SOAP Support for WebSphere MQ, and is a technical preview of what later releases of the product might bring.

The goal of SupportPac MA0R is to show how SOAP endpoints can be used with WebSphere MQ to provide reliable messaging between Web service “ style clients and the queue itself. To overcome the reliability issues of HTTP that were discussed in Chapter 8, MA0R is designed to use HTTPR, which is IBM's draft specification for Reliable HTTP.

To set up the endpoints, MA0R uses a MQSOAPHost process. This allows Web services written to both the Java (Apache Axis implementation) and .NET specifications to be hosted independently. Web services clients that want to use this service can do so by specifying a WebSphere MQ “specific URI naming scheme, an example of which could be:

 this.Url = "wmq:SOAP.StockQuoteDotNet@MQSOAP.DEMO.QM?"     +"connectQueueManager=MQSOAP.DEMO.QM"; 

This naming scheme, and of course SOAP/HTTPR, are independent of the platform ”meaning that both Java and .NET Web service clients can interoperate with the respective services hosted on the other platform.

At the time of this writing, MA0R can be downloaded from the IBM Web site, at http://www.ibm.com/software/integration/support/supportpacs/individual/ma0r.html . Although it wasn't possible to include any MA0R sample code in this book, it will be interesting to see how this SupportPac evolves in the near future.




Microsoft. NET and J2EE Interoperability Toolkit
Microsoft .NET and J2EE Interoperability Toolkit (Pro-Developer)
ISBN: 0735619220
EAN: 2147483647
Year: 2003
Pages: 132
Authors: Simon Guest

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net