Thursday, October 14, 2010

WebSphere Application Server SIBus as MQ queue manager

You may find yourself developing (legacy) message driven beans (MDBs) using listener port mechanism to connect to WMQ. If you want to test the MDBs (point-2-point) you need connection to WebShere MQ (at least if you are on WAS v6.x). Typically developers don't have dedicated WMQ so that could be a problem. I have used two workarounds. If you only have WAS on your disposal you could do:
  1. (Scenario one) Test MDB using activation specification (JCA 1.5 AS) instead of LP
  2. (Scenario two) Use SIBus to mimic WMQ and test as you would if you had WMQ

Scenario one

Both solution requires use of service integration bus (SIBus). If you are okey to use AS resource instead of LP then go ahead and create needed queues on SIBus, JNDI queues, queue conn. factories and AS. You can replace LP with AS in development tool (open ejb-jar.xml in RAD) or when application is deployed in WAS admin console. Because you created default messaging provider resources if you like to test MQ scenario you should have MQ resource set in JNDI also. That is inconvenient so you could use built in SIBus feature called MQ Client Link (not MQ Link, that's something different).

Scenario two

You define new MQ Client Link in your SIBus messaging engine (details here). You need give link name (not so important), define MQ channel name and Queue manager name. Those fields are important and you can enter something like WAS.JMS.SVRCONN and DEVQM respectively. So far so good. BTW this feature is added to SIBus so WAS v5 apps could be migrated to WAS v6 and use default messaging provide instead v5's embedded messaging (details here).
To keep things simple if you already have resources defined to connect to WMQ (queue, queue conn. factory, LP) all you need to do is change queue connection factory. Accordingly to given queue manager name and MQ channel name you should change it so it has properties like one below. 
MQ queue connection factory
Picture of queue manager connection factory (important fields shown)

You can find correct port on servers page in admin console. Look for SIB_MQ_ENDPOINT_ADDRESS port.
By default, this is 5558. Everything defined, after server restart, you can use JNDI resources and test MDB. Also note that JNDI mq queues
have the same base queue name as the queues defined on SIBus (same as on WMQ).  One can also use JNDI resources from client applications (let say to put message).





Wednesday, April 14, 2010

HTTP Server with logging in 20 lines of Groovy code

Developing web services often there is need for testing client against mock implementation. You can develop web service that will return response with mock data. Quicker way is to serve predefined SOAP response. Groovy can be very handy to do just that. Basically you can use Groovy CLI with -l option to run Groovy script against TCP port. Simple server that logs HTTP headers that was used as starting point you can find here. Here is the server code:
if (init) {
  request = "";
  log = new File('server.log')
}
if (line.size() > 0) {
  request += line + "\n"
}
else {
  response = 'HTTP/1.0 200 OK\n'
  responseFile = new File('SoapResponse.xml').text
  responseSize = responseFile.bytes.length
  response += "Content-Type: text/xml\n"
  response += "Content-Length: ${responseSize}\n\n"
  response += responseFile
  out << response

  log << "${new Date().format('dd.MM.yyyy HH:mm:ss.SSS')} - REQUEST: '\n${request}'\n\n"
  log << "${new Date().format('dd.MM.yyyy HH:mm:ss.SSS')} - RESPONSE: '\n${response}'\n\n"
  return "success"
}
Save this code as GroovyServer.groovy in directory where you have yours SoapResponse.xml and run it with:
groovy -l 8000 GroovyServer.groovy
If you go in your browser to http://localhost:8000 you should see yours SoapResponse.xml in browser. Now you can test your web service clients against this mock response. If you are curious how this works you can take a peek at groovy.ui.GroovySocketServer class from Groovy source. The interesting part is below:
...
String line = null;
script.setProperty("out", writer);
script.setProperty("socket", socket);
script.setProperty("init", Boolean.TRUE);
while ((line = reader.readLine()) != null) {
    // System.out.println(line);
    script.setProperty("line", line);
    Object o = script.run();
    script.setProperty("init", Boolean.FALSE);
    if (o != null) {
        if ("success".equals(o)) {
            break; // to close sockets gracefully etc...
        } else {
            if (autoOutputFlag) {
                writer.println(o);
            }
        }
    }
    writer.flush();
}
...
From the Java source one can see that Groovy script can't know when it gets last line from socket. Groovy server logs lines from request until it gets empty one. Usually there is empty line between header and body in POST so one will see only headers from HTTP request. Response is logged in complete. Feel free to reuse this code as you wish.