Thursday, April 30, 2009

Mule: Sending a JMS Message to WebSphere MQ

The Mule Client documentation example for sending a JMS message to a JMS queue seems simple enough:
    MuleClient client = new MuleClient();
client.dispatch("jms://my.queue", "Message Payload" null);
I was having trouble sending a JMS message to endpoint hooked to the following WebSphere MQ connector. The connector has a JMS to Object transformer for the incoming message. Sending a String as in the example produced an execption related to the connection factory stating that the incoming object was of type Class and not a JMS message. The connector:
  <jms:connector name="jmsConnectorWMQ"
connectionFactory-ref="WMQConnectionFactory"
maxRedelivery="5"
specification="1.1"
persistentDelivery="true"
numberOfConcurrentTransactedReceivers="5">
<service-overrides inboundTransformer="Jms2Obj"/>
</jms:connector>

<jms:jmsmessage-to-object-transformer name="Jms2Obj"/>
The connection factory:
  <spring:bean name="WMQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<spring:property name="transportType" value="1"/>
<spring:property name="hostName" value="${jms.connection.hostname}"/>
<spring:property name="port" value="${jms.connection.port}"/>
<spring:property name="queueManager" value="${jms.queue.manager}"/>
<spring:property name="channel" value="${jms.connection.channel}"/>
</spring:bean>

I was able to create and send a JMS message with the following method. Without giving the ObjectToJMSMessage transformer an endpoint, an exception was thrown stating the transformer requires a javax.jms.Session. The String to send is transformed to a JMS message to make the connector happy.

The URL returned by the getUrl() method below was the address of a JMS queue, for example: jms://request.queue. Im using MuleClient.send() because I want the response returned synchronously.

The method:

protected String sendRequest(Object request) throws Exception {

EndpointFactory endpointFactory = new DefaultEndpointFactory();
MuleContext context = MuleServer.getMuleContext();
endpointFactory.setMuleContext(context);
ImmutableEndpoint endpoint = endpointFactory.getInboundEndpoint(getUrl());

ObjectToJMSMessage transformer = new ObjectToJMSMessage();
transformer.setEndpoint(endpoint);

Object transformedMessage = transformer.doTransform(request, "UTF-8");

MuleClient client = new MuleClient();
MuleMessage responseMessage = client.send(getUrl(), transformedMessage, null);
String response = responseMessage.getPayloadAsString(ENCODING);

return response;
}

This seems like a lot of work to me to send a simple JMS message to WebSphere MQ, but it works. A suggestions for alternative would be greatly appreciated.

A better approach: I left this as a comment but it doesn't display too nicely...

With com.ibm.mqjms.jar, sending the JMS message is much easier. I wish I would of found this earlier.

With the following imports:
    import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.jms.MQJMSStringResources;
The original method is greatly simplified to:
    protected String sendRequest(Object request) throws Exception {

MQJMSStringResources resources = new MQJMSStringResources();
JMSTextMessage jmsMessage = new JMSTextMessage(resources, (String)request);
jmsMessage.setText((String)request);

MuleClient client = new MuleClient();
MuleMessage responseMessage = client.send(getUrl(), jmsMessage, null);

String response = responseMessage.getPayloadAsString(ENCODING);

return response;
}

Sunday, April 26, 2009

Using tidy to Format XML

Here's an exmaple of using tidy to format XML:
tidy -utf8 -xml -w 255 -i -c -q -asxml
I like to use an alias to work with files easily:
$ alias xmltidy="tidy -utf8 -xml -w 255 -i -c -q -asxml"

$ xmltidy some-file.xml > tidy-file.xml
You can also change a file in place:
$ xmltidy -m some-file.xml

Friday, April 3, 2009

Groovy: Pretty Printing XML

A script for pretty printing XML in Groovy:
#!/usr/share/groovy/bin/groovy
import org.xml.sax.SAXParseException

def xml = new File(args[0]).text
def stringWriter = new StringWriter()
def printWriter = new PrintWriter(stringWriter)

try {
def node = new XmlParser().parseText(xml)
new XmlNodePrinter(printWriter).print(node)
println stringWriter.toString()
} catch(SAXParseException spe) {
println spe.getMessage()
}
Suggestions for alternatives would be appreciated!

Mule: Displaying HTTP Outbound Responses

I had been tasked with adding an endpoint to my Mule service for verifying other service endpoints. One of the requirements was that the endpoint be HTTP so that a browser could be used to retrieve the verification report.

Originally, when hitting the endpoint in my browser, the resulting HTML was displayed as plain text.

I resolved this by adding the HtmlResponseTransformer below:
    <http:endpoint name="VerificationEndpoint"
host="localhost"
port="28080"
path="services/verify"
method="GET"
synchronous="true"
responseTransformer-refs="HtmlResponseTransformer"/>

<message-properties-transformer name="HtmlResponseTransformer">
<add-message-property key="Content-Type" value="text/html"/>
</message-properties-transformer>

<model name="setup">
...
<service name="verify">
<inbound>
<http:inbound-endpoint ref="VerificationEndpoint"/>
</inbound>
<component>
<spring-object bean="endpointVerifier"/>
</component>
</service>
...
</model>
It is worth noting the HTTP Transport Documentation states that HTTP endpoints are synchronous by default, but it did appear to be the case in my experience.