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.

Wednesday, February 18, 2009

Maven Assemblies: Including Runtime Dependencies

I wanted to share a tip I picked up from Maven: The Definitive Guide
Previously, I thought you had to list every runtime dependency you wanted to include in a dependencySet:
   <dependencySets>
<dependencySet>
<includes>
<include>commons-dbcp:commons-dbcp</include>

</includes>
<outputDirectory>mule/lib/user</outputDirectory>
</dependencySet>
</dependencySets>
But all runtime dependencies can be brought into the assembly with an empty dependencySet element (runtime scope implicitly includes compile scope):
   <dependencySet/>
This will put all the runtime dependencies in the root of the assembled artifact, so you can add an outputDirectory:
   <dependencySet>
<outputDirectory>mule/lib/user</outputDirectory>
</dependencySet>
And in the case where you want to exclude something (such as mule-#.tar.gz or isoft-#.tar.gz) you can add exclusions:
   <dependencySet>
<outputDirectory>mule/lib/user</outputDirectory>
<excludes>
<exclude>*:tar.gz</exclude>
</excludes>
</dependencySet>
Doing things this way puts a heavier burden on properly managing your dependencies however (which really is a good thing). If transitive dependencies you may not need are not excluded in the POM’s dependency declaration or the parent’s dependencyManagement, the transitive dependencies will end up in your artifact, leading to potential collisions and jar bloat. An example of an exclusion:
    <dependency>
<groupId>toplink.essentials</groupId>
<artifactId>toplink-essentials</artifactId>
<scope>runtime</scope>
<excludes>
<exclude>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
</exclude>
</excludes>
</dependency>
You can run each of the following to help with your dependency manangement:
mvn dependency:analyze
mvn dependency:resolve
mvn dependency:tree

Friday, February 13, 2009

Spring ref vs. bean: no ID/IDREF binding for IDREF

hen upgrading a project from Mule 1.x to Mule 2.x, I ran into the following error while converting my Mule configuration file:
A Fatal error has occurred while the server was running:
cvc-id.1: There is no ID/IDREF binding for IDREF 'someProxy'.
(org.xml.sax.SAXParseException)
The offending bean:
   <spring:bean id="myImplementationBean" class="org.my.class" scope="prototype">
<spring:property name="myInterface">
<spring:ref local="myProxy"/>
</spring:property>
</spring:bean>
The problem was using local instead of bean as the value of the spring:property:
   <spring:bean id="myImplementationBean" class="org.my.class" scope="prototype">
<spring:property name="myInterface">
<spring:ref bean="myProxy"/>
</spring:property>
</spring:bean>
For a discussion the difference, see Spring-ref-local-vs-ref.

Determining which Process is Using a Port

This post is more of a reminder to myself than anything. To determine which process is using a port with fuser in Linux run:
fuser -n tcp port
Alternatively, you can use netstat:
netstat -nlp | grep port