Bridging the ActiveMQ with IBM Websphere using Camel

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Bridging the ActiveMQ with IBM Websphere using Camel

JavaRat
Camel seems too be a most interesting and promising keycomponent in our work and we have thrown ourselves into trying its potentials. However while trying to bridge an ActiveMQqueue with an IBM MQ websphere queue we have discovered the following problem (please see attached picture).

camelissue.jpeg

Messages taken off the Active MQ queue and delivered onto the IBM MQ Websphere queue which is good and what we want. However the messages will not have the specific parameters set in the JMS header and it’s payload emptied???
 
Hopefully this is an error from our part but without success we have tried to locate the faulty code and are now turning too this forum for any advice or pointers where we are going wrong. (It might be worth mentioning that this code has worked for us previously using the Servicemix-JMS-Component which we have tried adapting in the camel approach.)

Our setup is as follows:

CAMEL-CONTEXT.xml
<camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
<package>org.websitename</package>
</camelContext>

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant staticfield="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/> 
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>     
<property name="port" value="1414"/>
</bean>
</property> 
</bean>

<bean id="activemq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://127.0.0.1:61616" />
</bean>
</property> 
</bean>

MyRouteBuilder.java
public class MyRouteBuilder extends RouteBuilder {

public void configure() {
from("activemq:queue.in").process(new Processor() {
public void process(Exchange exchange) throws Exception {
JmsMessage inMsg = null;

if (exchange.getIn() instanceof JmsMessage) {
inMsg = (JmsMessage)exchange.getIn();
javax.jms.Message inMsgMsg = inMsg.getJmsMessage();

if (inMsgMsg instanceof ActiveMQTextMessage) {
ActiveMQTextMessage inTextMsg = (ActiveMQTextMessage)inMsgMsg;
inTextMsg.setReadOnlyProperties(false);
inMsgMsg.setStringProperty("JMS_IBM_Format", MQC.MQFMT_STRING);
inMsgMsg.setIntProperty("JMS_IBM_MsgType", MQC.MQMT_REQUEST);
}
else {
System.out.println("inMsgMsg not a ActiveMQTextMessage but a " + inMsgMsg.getClass().toString());
}

}
else {
System.out.println("inMsg not a JmsMessage but a " + exchange.getIn().getClass().toString());
}

.to("ibmmq:queue.out");

}



A search through forums provided some related clues what might be a problem in this case???

http://www.nabble.com/Some-headers-are-not-forwarded-to-JMS-destinations-td16763376s22882.html#a16763376

http://www.nabble.com/How-to-avoid-to-lost-Headers-add-from-messages-go-from-activemq---td18381854s22882.html#a18381854

http://www.nabble.com/-CONF--Apache-Camel:-Bean-Binding-(page-edited)-td18903933s22882.html
Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

Claus Ibsen
Hi

What version of Camel are you using? There have been a lot of activities on Camel 1.3, 1.4 and 1.5 (in progress). So it's good to know what you use.

Camel-jms will filter out any non JMS-spec valid headers. This is done by iterating the headers and check if the object type is not a valid one:

See the source: JmsBinding, JmsHeaderFilterStrategy

You set some MQ specific types and thus they are probably filtered out as they are not valid JMS types. Can't you use String, Integer or the likes?

Camel sends the JMS message based on the payload type either as a:
TextMessage
ObjectMessage
MapMessage
BytesMessage
...
See source: JmsBinding


What kind of payload are you sending?

We have a ticket for a RFE where you can configure Camel to use a fixed type so you can force it to send TextMessage.


Try setting DEBUG/TRACE logging to: org.apache.camel.component.jms
And see what it logs

You can also try to set a fixed message to send in your Processor code.

exchange.getIn.setBody("Hello World");
exchange.getIn.setHeader("foo", "bar");


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: JavaRat [mailto:[hidden email]]
Sent: 23. september 2008 10:29
To: [hidden email]
Subject: Bridging the ActiveMQ with IBM Websphere using Camel


Camel seems too be a most interesting and promising keycomponent in our work
and we have thrown ourselves into trying its potentials. However while
trying to bridge an ActiveMQqueue with an IBM MQ websphere queue we have
discovered the following problem (please see attached picture).

http://www.nabble.com/file/p19623329/camelissue.jpeg camelissue.jpeg

Messages taken off the Active MQ queue and delivered onto the IBM MQ
Websphere queue which is good and what we want. However the messages will
not have the specific parameters set in the JMS header and it's payload
emptied???
 
Hopefully this is an error from our part but without success we have tried
to locate the faulty code and are now turning too this forum for any advice
or pointers where we are going wrong. (It might be worth mentioning that
this code has worked for us previously using the Servicemix-JMS-Component
which we have tried adapting in the camel approach.)

Our setup is as follows:

CAMEL-CONTEXT.xml
<camelContext id="camel"
xmlns="http://activemq.apache.org/camel/schema/spring">
<package>org.websitename</package>
</camelContext>

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant staticfield="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>    
<property name="port" value="1414"/>
</bean>
</property>
</bean>

<bean id="activemq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://127.0.0.1:61616" />
</bean>
</property>
</bean>

MyRouteBuilder.java
public class MyRouteBuilder extends RouteBuilder {

public void configure() {
from("activemq:queue.in").process(new Processor() {
public void process(Exchange exchange) throws Exception {
JmsMessage inMsg = null;

if (exchange.getIn() instanceof JmsMessage) {
inMsg = (JmsMessage)exchange.getIn();
javax.jms.Message inMsgMsg = inMsg.getJmsMessage();

if (inMsgMsg instanceof ActiveMQTextMessage) {
ActiveMQTextMessage inTextMsg = (ActiveMQTextMessage)inMsgMsg;
inTextMsg.setReadOnlyProperties(false);
inMsgMsg.setStringProperty("JMS_IBM_Format", MQC.MQFMT_STRING);
inMsgMsg.setIntProperty("JMS_IBM_MsgType", MQC.MQMT_REQUEST);
}
else {
System.out.println("inMsgMsg not a ActiveMQTextMessage but a " +
inMsgMsg.getClass().toString());
}

}
else {
System.out.println("inMsg not a JmsMessage but a " +
exchange.getIn().getClass().toString());
}

.to("ibmmq:queue.out");

}



A search through forums provided some related clues what might be a problem
in this case???

http://www.nabble.com/Some-headers-are-not-forwarded-to-JMS-destinations-td16763376s22882.html#a16763376

http://www.nabble.com/How-to-avoid-to-lost-Headers-add-from-messages-go-from-activemq---td18381854s22882.html#a18381854

http://www.nabble.com/-CONF--Apache-Camel:-Bean-Binding-(page-edited)-td18903933s22882.html

--
View this message in context: http://www.nabble.com/Bridging-the-ActiveMQ-with-IBM-Websphere-using-Camel-tp19623329s22882p19623329.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

JavaRat
Thank you for your quick reply in this matter Claus.

We are currently using camel 1.4 (testing with 1.4.0.0. & 1.4.2.0). The aim of our project is picking up a short textmessage from the activeMQ queue and sending it to a websphere queue. However for websphere too accept textmessages it seems from previous testing a few IBM specific properties in the JMSheader must be set accordingly:

property: JMS_IBM_Format must be of format: MQC.MQFMT_STRING
property: JMS_IBM_MsgType must be set as MQC.MQMT_REQUEST
property: JMSReplyTo must also be set to a valid replyToqueue on the ibm mq.
(A lot of reading about these properties may be found at: http://publib.boulder.ibm.com/infocenter/wbihelp/v6rxmx/index.jsp )

Unless these minimum parameters are set it appears the receiving application will not accept our messages. Do you believe with using camel it would be possible to solve this task?

I am not quite certain too what you mean with 'Can't you use String, Integer or the likes?'
Is there an alternative solution to what we are trying to achieve?
Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

Claus Ibsen
Hi

I would be quite surprised if you can not use standard JMS to send a simple text message to WebSphere MQ.

But you have to use IBM specific headers to mark it as a text message.

I have sent JMS messages from older WebLogic 5 and 6 to WebSphereMQ using standard JMS and never have to add specific MQ types.

I am sure there have been a lot of people before being able with success to send a text message to WebSphereMQ without having to use these IBM types as JMS properties.


Could you send a link to the exact point in the WebSphereMQ documentation where its stated that these MQ types must be set?
http://publib.boulder.ibm.com/infocenter/wbihelp/v6rxmx/index.jsp (is just the "welcome page" ;))

Then we will be able to digest this and maybe add some code in Camel to allow IBM types to be set.

It would be helpful if you could create a sample java code that sends a TextMessage to IBM WebSphereMQ (just from a plain java main(String args...)



> I am not quite certain too what you mean with 'Can't you use String, Integer or the likes?'
The JMS spec mandates that only simple types must be used for JMS properties. By simple types its: Numeric types, String types, etc.

So setting a property with the type: com.ibm.MQ.MQ_XXX is not a simple type, according to the JMS spec. So that is why Camel filter out these types.




Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: JavaRat [mailto:[hidden email]]
Sent: 23. september 2008 11:03
To: [hidden email]
Subject: RE: Bridging the ActiveMQ with IBM Websphere using Camel


Thank you for your quick reply in this matter Claus.

We are currently using camel 1.4 (testing with 1.4.0.0. & 1.4.2.0). The aim
of our project is picking up a short textmessage from the activeMQ queue and
sending it to a websphere queue. However for websphere too accept
textmessages it seems from previous testing a few IBM specific properties in
the JMSheader must be set accordingly:

property: JMS_IBM_Format must be of format: MQC.MQFMT_STRING
property: JMS_IBM_MsgType must be set as MQC.MQMT_REQUEST
property: JMSReplyTo must also be set to a valid replyToqueue on the ibm mq.
(A lot of reading about these properties may be found at:
http://publib.boulder.ibm.com/infocenter/wbihelp/v6rxmx/index.jsp )

Unless these minimum parameters are set it appears the receiving application
will not accept our messages. Do you believe with using camel it would be
possible to solve this task?

I am not quite certain too what you mean with 'Can't you use String, Integer
or the likes?'
Is there an alternative solution to what we are trying to achieve?
--
View this message in context: http://www.nabble.com/Bridging-the-ActiveMQ-with-IBM-Websphere-using-Camel-tp19623329s22882p19623857.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

JavaRat
Thank you for your reply once again Claus!

We have been researching the pointers you gave us.
After some experimenting we found a few interesting things with camel. This is what we think is happening in camel and our problem (we attach another sketchy picture what we think is happening):

camelencapsulation.jpeg

1.

Question: The payload is missing on the message put onto the final destinationqueue?!

Probable cause: While trying out the MyRouterBuilder.java with the following code we left an old fashion system.println.out in the code:
 
from(activemq:queue.in)..process(new Processor() {
public void process(Exchange exchange) throws Exception { System.out.println("camelInMsg = " +exchange.getIn().toString());
}})
.to("ibmmq:queue:///queue.out");

   
We belive by doing exchange.getIn() you actually take the message “off the queue” and if not setting the exchange.setIn() afterwards you will end up with an empty message? (Removing the system.out.println and you get your original message on the finalqueue as we want)


2.

Question: When picking a message off the Active MQ queue it seems that Camel “wraps it in an own “Messagewrapper” called org.apache.camel.component.jms.JMSMessage.
How will we reach the “real message we need to access and enrich?”?!

What we have tried:
We attempt too dig into the original message by peeling off the camelshellmessage using some cast like:
JMSMessage camelWrapMessage =  (JMSMessage)exchange.getIn();
ActiveMQTextMessage myInnerTextMessage = (ActiveMQTextMessage)camelWrapMessage;

Now the original message seems to be accessable for adding additional information as in our case were we want to put a few IBMMQ specific properties such as for example myInnerTextMessage.setStringProperty(JMS_IBM_Format”, MQC.MQFMT_STRING); and  myInnerTextMessage.JMSReplyTo(responseQueue);
However here is an interesting feature when we use myInnerTextMessage.setStringProperty(“jms_IBM_Format”, MQC.MQFMT_STRING); camel will not think it is a specific JMS property and accept it as a custom header. (So be mindful when using capital letters.)

After this is done we can now what we believe is the actual message put onto the next queue with first camelWrapMessage.setJMSMessage(myInnerTextMsg);
exchange.setIn(camelWrapMessage);

So far so good…

However when we check the IBM MQ queue we find the message properties are set what looks like a textmessage inside a JMSmessage ?!
Why do we have this at the end?

We are guessing here and this is where really could use some help:

We want ONLY the textMessage to be sent not the camelWrapMessage, this might not be our problem though since we use:

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/> 
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>     
<property name="port" value="1414"/>
</bean>
</property> 
</bean>

in our camel-context.xml. But if we remove the

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">



</property> 
</bean>

we cannot seem to get it too connect to our IBM MQ queue?

Question 3: How do we remove what looks like the extra enwrapped JMSMessage and only send our original TextMessage to the final queue?
Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

Claus Ibsen
Hi

Just a quick hint:

JmsMessage camelJmsMessage = exchange.getIn().getBody();
javax.jms.Message jmsMsg = camelJmsMessage.getJmsMessage();

And hopefully there is a good type converter so you can do this in one line:
javax.jms.Message jmsMsg = exchange.getIn().getBody(javax.jms.Message.class);

If this one is failing please report a bug in JIRA so we can have a type converter for this out-of-the-box.



Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: JavaRat [mailto:[hidden email]]
Sent: 24. september 2008 09:17
To: [hidden email]
Subject: RE: Bridging the ActiveMQ with IBM Websphere using Camel


Thank you for your reply once again Claus!

We have been researching the pointers you gave us.
After some experimenting we found a few interesting things with camel. This
is what we think is happening in camel and our problem (we attach another
sketchy picture what we think is happening):

http://www.nabble.com/file/p19643280/camelencapsulation.jpeg
camelencapsulation.jpeg

1.

Question: The payload is missing on the message put onto the final
destinationqueue?!

Probable cause: While trying out the MyRouterBuilder.java with the following
code we left an old fashion system.println.out in the code:
 
from(activemq:queue.in)..process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("camelInMsg = " +exchange.getIn().toString());
}})
.to("ibmmq:queue:///queue.out");

   
We belive by doing exchange.getIn() you actually take the message "off the
queue" and if not setting the exchange.setIn() afterwards you will end up
with an empty message? (Removing the system.out.println and you get your
original message on the finalqueue as we want)


2.

Question: When picking a message off the Active MQ queue it seems that Camel
"wraps it in an own "Messagewrapper" called
org.apache.camel.component.jms.JMSMessage.
How will we reach the "real message we need to access and enrich?"?!

What we have tried:
We attempt too dig into the original message by peeling off the
camelshellmessage using some cast like:
JMSMessage camelWrapMessage =  (JMSMessage)exchange.getIn();
ActiveMQTextMessage myInnerTextMessage =
(ActiveMQTextMessage)camelWrapMessage;

Now the original message seems to be accessable for adding additional
information as in our case were we want to put a few IBMMQ specific
properties such as for example
myInnerTextMessage.setStringProperty(JMS_IBM_Format", MQC.MQFMT_STRING); and
myInnerTextMessage.JMSReplyTo(responseQueue);
However here is an interesting feature when we use
myInnerTextMessage.setStringProperty("jms_IBM_Format", MQC.MQFMT_STRING);
camel will not think it is a specific JMS property and accept it as a custom
header. (So be mindful when using capital letters.)

After this is done we can now what we believe is the actual message put onto
the next queue with first camelWrapMessage.setJMSMessage(myInnerTextMsg);
exchange.setIn(camelWrapMessage);

So far so good...

However when we check the IBM MQ queue we find the message properties are
set what looks like a textmessage inside a JMSmessage ?!
Why do we have this at the end?

We are guessing here and this is where really could use some help:

We want ONLY the textMessage to be sent not the camelWrapMessage, this might
not be our problem though since we use:

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>    
<property name="port" value="1414"/>
</bean>
</property>
</bean>

in our camel-context.xml. But if we remove the

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">

...

</property>
</bean>

we cannot seem to get it too connect to our IBM MQ queue?

Question 3: How do we remove what looks like the extra enwrapped JMSMessage
and only send our original TextMessage to the final queue?

--
View this message in context: http://www.nabble.com/Bridging-the-ActiveMQ-with-IBM-Websphere-using-Camel-tp19623329s22882p19643280.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

JavaRat
Hi,

When we tried your JmsMessage camelJmsMessage = exchange.getIn().getBody(); we get an error in eclipse saying cannot convert Message to Object. We therefor changed the code a little too the following:

Object myObj = exchange.getIn().getBody();
System.out.println("============================================");
System.out.println("Class of exchange.getIn().getBody() is : " + myObj.getClass());
System.out.println("and it is : " + myObj);
System.out.println("============================================");

Which resultet in the following output in our console when running the code:

consoleoutput.jpeg

=========================================================
Class of exchange.getIn().getBody() is : class java.lang.String
and it is : try 40
=========================================================

It might be worth a notice while testing we aim to have a standard webbrowser from ActiveMQ using the http://localhost:8161/admin and putting the message onto our first queue which we call 'put.queue' (see attached picture)

camelissue5.jpeg

In the above test we typed "try 40" into the webbrowser and selected our put.queue.
The first camel routing component delivers the message onto the queue.in and browsing this message there it looks good.
Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

Claus Ibsen
In reply to this post by JavaRat
Ad 1)
Missing payload. Sounds as if when you do get the payload and print it using system out, the payload type is stream based and thus can ONLY be read once.

I do believe that we have added some stream cache features into Camel so you can read it more than ONCE.

Ad 2)
Yeah Camel has an internal representation of JmsMessage as you wrote.
There is a getJmsMessage() to get the javax.jms.Message object.

The getBody() method should return the payload with the appropriate type such as String.


Sending the message to IBM MQ)
Looks like you can use the option alwaysCopy=true and then you can create the javax.jms.JmsMessage object to send wrapped in an org.apache.camel.component.jms.JMSMessage object. Then you are in control and Camel should not interfere and filter out headers etc.

The option is configured on the uri:
from(xxX).to("ibmmq:queue:xxx?alwaysCopy=true");

And in your processor java code, something like this:


Javax.jms.Message myJavaxJmsMessage = ...
// here get a standard JMS message and set the payload and the properties to send

// wrap it into a camel message and set the body to send
exchange.getIn().setBody(new org.apache.camel.component.jms.JMSMessage(myJavaxJmsMessage));


This is just what I could find looking into the source for 5 mins.



Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: JavaRat [mailto:[hidden email]]
Sent: 24. september 2008 09:17
To: [hidden email]
Subject: RE: Bridging the ActiveMQ with IBM Websphere using Camel


Thank you for your reply once again Claus!

We have been researching the pointers you gave us.
After some experimenting we found a few interesting things with camel. This
is what we think is happening in camel and our problem (we attach another
sketchy picture what we think is happening):

http://www.nabble.com/file/p19643280/camelencapsulation.jpeg
camelencapsulation.jpeg

1.

Question: The payload is missing on the message put onto the final
destinationqueue?!

Probable cause: While trying out the MyRouterBuilder.java with the following
code we left an old fashion system.println.out in the code:
 
from(activemq:queue.in)..process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("camelInMsg = " +exchange.getIn().toString());
}})
.to("ibmmq:queue:///queue.out");

   
We belive by doing exchange.getIn() you actually take the message "off the
queue" and if not setting the exchange.setIn() afterwards you will end up
with an empty message? (Removing the system.out.println and you get your
original message on the finalqueue as we want)


2.

Question: When picking a message off the Active MQ queue it seems that Camel
"wraps it in an own "Messagewrapper" called
org.apache.camel.component.jms.JMSMessage.
How will we reach the "real message we need to access and enrich?"?!

What we have tried:
We attempt too dig into the original message by peeling off the
camelshellmessage using some cast like:
JMSMessage camelWrapMessage =  (JMSMessage)exchange.getIn();
ActiveMQTextMessage myInnerTextMessage =
(ActiveMQTextMessage)camelWrapMessage;

Now the original message seems to be accessable for adding additional
information as in our case were we want to put a few IBMMQ specific
properties such as for example
myInnerTextMessage.setStringProperty(JMS_IBM_Format", MQC.MQFMT_STRING); and
myInnerTextMessage.JMSReplyTo(responseQueue);
However here is an interesting feature when we use
myInnerTextMessage.setStringProperty("jms_IBM_Format", MQC.MQFMT_STRING);
camel will not think it is a specific JMS property and accept it as a custom
header. (So be mindful when using capital letters.)

After this is done we can now what we believe is the actual message put onto
the next queue with first camelWrapMessage.setJMSMessage(myInnerTextMsg);
exchange.setIn(camelWrapMessage);

So far so good...

However when we check the IBM MQ queue we find the message properties are
set what looks like a textmessage inside a JMSmessage ?!
Why do we have this at the end?

We are guessing here and this is where really could use some help:

We want ONLY the textMessage to be sent not the camelWrapMessage, this might
not be our problem though since we use:

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>    
<property name="port" value="1414"/>
</bean>
</property>
</bean>

in our camel-context.xml. But if we remove the

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">

...

</property>
</bean>

we cannot seem to get it too connect to our IBM MQ queue?

Question 3: How do we remove what looks like the extra enwrapped JMSMessage
and only send our original TextMessage to the final queue?

--
View this message in context: http://www.nabble.com/Bridging-the-ActiveMQ-with-IBM-Websphere-using-Camel-tp19623329s22882p19643280.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

JavaRat
This post was updated on .
Hi Claus, many thanks for your ideas and suggestions so far!

We have tested the above tips you had. Both on their own and together without any effect we can see on the message which ends up on our final queue destination. Browsing the message we get on the IBM MQ queue we get the following:


XQH .... CAMELoutputchannel
                                  queue.out

            CT ....................ÿÿÿÿ....
....R...MQHRF2 .............AMQ Qmgr
            <<exH ...$.....................
......................

                                        Qmgr

                      CAMELusertester...'
Vu%%._IneiZ..................
                               .........WebS
phere MQ Client for Java20080924
11025671    RFH .........................
MQSTR   ........,...........,<mcd><Msd>
jms_text</Msd><Type></Type></mcd>
...X<jms><Dst>queue:///queue.out</Dst>
<Tms>1222311223456</Tms><Cid></Cid>
<Dlv>2</Dlv></jms> ......
<usr><jms_IBM_MsgType dt='i4'>1</jms_IBM_MsgType>
<jms_IBM_Format>MQSTR</jms_IBM_Format>
</usr>
my chocolatechip cookie recipie


Without getting into MQ details it looks very much as we have a JMSMessage around the TextMessage which we are intending to put onto the queue. (Clues too why we think so is we see a MQHRF2 and a RFH part.) Also we see the MQSTR and <Msd>jms_text</Msd> beeing recognized.
 
Our current guess (and let us assume this is the case) is that we are not "peeling" off the camelWrapper Message before putting it onto the IBM MQ queue.
How can we avoid sending our textMessage inside this camelWrapperMessage?

Have we made a misstake thinking we can use the following configuration inside the camel-context.xml?
We refer to this bean when we use the from(activemq:queue.in).to(ibmmq:queue///queue.out)

<bean id="<b>ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/> 
</property>
<property name="queueManager" value="MW01"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>     
<property name="port" value="1414"/>
</bean>
                </property> 
        </bean>
Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

Claus Ibsen
Hi

Can you use Hermes to browse the MQ queues? Maybe the MQ queue browser is showing it as a raw kinda format. I am not familiar with the MQ console.

At my current client we have with success setup Hermes to browse our MQ broker.


I think you need some Java code in between your routing to be able to set the IBM specific headers and other stuff that you need in your case to send it to your MQ.

So the route: from(activemq:queue.in).to(ibmmq:queue///queue.out)
Must be expanded with a processor to do the java coding needed.



You can do this route to let you be in control what is sent to MQ
from(activemq:queue.in).process(new Processor()) {
  public void process(Exchange exchange) {
    // TODO: Insert java code here
    exchange.getIn().setBody("Hello World");
    exchange.getIn().setHeaders(Collections.EMPTY_MAP);
};).to(ibmmq:queue///queue.out)



You can also remove the .to(ibmmq:queue///queue.out) in the route and send it manually from the processor in java code. Here you can send it using spring-jms, so you can avoid whatever Camel interferes with.

Bottom line: I will try to get some plain java code working that can send a message to MQ. And then later use that code in Camel.


If you ping my en email at: [hidden email] then I will be able to send you some sample java code that we use for sending message to MQ using spring-jms. Albeit we don't use this in production, we are using it for proof-of-concept.

The same code can be used in Camel, just in the processor or as a spring bean etc.


 


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: JavaRat [mailto:[hidden email]]
Sent: 24. september 2008 13:26
To: [hidden email]
Subject: RE: Bridging the ActiveMQ with IBM Websphere using Camel


Hi Claus, many thanks for your ideas and suggestions so far!

We have tested the above tips you had. Both on their own and together
without any effect we can see on the message which ends up on our final
queue destination. Browsing the message we get on the IBM MQ queue we get
the following:


XQH .... CAMELoutputchannel
                                  queue.out

            CT ....................ÿÿÿÿ....
....R...MQHRF2 .............AMQ Qmgr
            <<exH ...$.....................
......................

                                        Qmgr

                      CAMELusertester...'
Vu%%._IneiZ..................
                               .........WebS
phere MQ Client for Java20080924
11025671    RFH .........................
MQSTR   ........,...........,<mcd><Msd>
jms_text</Msd><Type></Type></mcd>
...X<jms><Dst>queue:///queue.out</Dst>
<Tms>1222311223456</Tms><Cid></Cid>
<Dlv>2</Dlv></jms> ......
<usr><jms_IBM_MsgType dt='i4'>1</jms_IBM_MsgType>
<jms_IBM_Format>MQSTR</jms_IBM_Format>
</usr>
my chocolatechip cookie recipie


Without getting into MQ details it looks very much as we have a JMSMessage
around the TextMessage which we are intending to put onto the queue. (Clues
too why we think so is we see a MQHRF2 and a RFH part.) Also we see the
MQSTR and <Msd>jms_text</Msd> beeing recognized.
 
Our current guess (and let us assume this is the case) is that we are not
"peeling" off the camelWrapper Message before putting it onto the IBM MQ
queue.
How can we avoid sending our textMessage inside this camelWrapperMessage?

Have we made a misstake thinking we can use the following configuration
inside the camel-context.xml?
We refer to this bean when we use the
from(activemq:queue.in).to(ibmmq:queue///queue.out)

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>
<property name="queueManager" value="MW01"/>
<property name="hostName" value="172.23.1.19"/>    
<property name="port" value="1414"/>
</bean>
                </property>
        </bean>
--
View this message in context: http://www.nabble.com/Bridging-the-ActiveMQ-with-IBM-Websphere-using-Camel-tp19623329s22882p19646763.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Bridging the ActiveMQ with IBM Websphere using Camel

JavaRat
In reply to this post by JavaRat
It took us a while too let things sink in and too grasp the problem correctly. We have been approaching the problem in the wrong way not understanding camel or the problem at hand.
We want to set a vendorspecific property on the queue where we put our message. This is done with the property targetClient=1. (IBM MQ standard is targetClient=0) Setting this property to 1 will alert the IBM MQ queue that we intend to put a JMS Message onto it.
(This property is set through the class com.ibm.mq.jms.MQDestination.)

This problem has nothing too do with camel. However it would be very nice to be able to set a URI as in the case with servicemix-jms where we could simply type into the destinationName:

<jms:provider service="esb:IBMMQOutbound"
endpoint="mqOutbound"
destinationName="queue:///MyQueueOutBound?targetClient=1"
connectionFactory="#mqConnectionFactory"/>       
       
<bean id="mqConnectionFactory"
class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/> 
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>     
<property name="port" value="1414"/>
</bean>

Something like this would be ideal in our case:

<camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
<route>
<from uri="activemq:myqueueinbound"/>
<to uri="ibmmq:queue:///MyQueueOutBound?targetClient=1"/>
</route>
</camelContext>


However this is not the case. We believe that something like this should solve the problem if we only figured out the correct spring configuration:

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>   
<property name="port" value="1414"/>
</bean>
</property>
<property name="queue" ref="ibmqueueprop">
</bean>

<bean id="ibmqueueprop" class=" com.ibm.mq.jms.MQDestination">
<property name="targetClient" value="1"/>   
</bean>


If someone finds a solution to this problem please send us a message or post it here.
Thanks again Claus for your assistance in this matter!
We will keep this update if we stumble on the solution

Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

Claus Ibsen
Hi

Just a reminder. We should check how servicemix-jms supports these options.
Is "targetClient" a known option in servicemix-jms? Or does it support setting any arbitrary options, eg. ?mysuperoption=true

We could check the source code, servicemix-jms documentation and ask on the servicemix IRC chat room.

Frederik this option is not possible to set on the MQQueueConnectionFactory?
And why are you using a NON JMS transport type?
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>

I think it should be "1" for JMS.


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: JavaRat [mailto:[hidden email]]
Sent: 6. oktober 2008 09:24
To: [hidden email]
Subject: Re: Bridging the ActiveMQ with IBM Websphere using Camel


It took us a while too let things sink in and too grasp the problem
correctly. We have been approaching the problem in the wrong way not
understanding camel.

This problem has nothing too do with camel. However it would be very nice to
be able to set a URI as in the case with servicemix-jms where we could
simply type into the destinationName:

<jms:provider service="esb:IBMMQOutbound"
endpoint="mqOutbound"
destinationName="queue:///MyQueueOutBound?targetClient=1"
connectionFactory="#mqConnectionFactory"/>
       
<bean id="mqConnectionFactory"
[CI]
class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>    
<property name="port" value="1414"/>
</bean>

Something like this would be ideal in our case:

<camelContext id="camel"
xmlns="http://activemq.apache.org/camel/schema/spring">
<route>
<from uri="activemq:myqueueinbound"/>
<to uri="ibmmq:queue:///MyQueueOutBound?targetClient=1"/>
</route>
</camelContext>


However this is not the case. We believe that something like this should
solve the problem if we only figured out the correct spring configuration:

<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>
<property name="queueManager" value="QMgr"/>
<property name="hostName" value="xxx.xxx.xxx.xxx"/>    
<property name="port" value="1414"/>
</bean>
</property>
<property name="queue" ref="ibmqueueprop">
</bean>

<bean id="ibmqueueprop" class=" com.ibm.mq.jms.MQDestination">
<property name="targetClient" value="1"/>    
</bean>


If someone finds a solution to this problem please send us a message or post
it here.
Thanks again Claus for your assistance in this matter!
We will keep this update if we stumble on the solution =)


--
View this message in context: http://www.nabble.com/Bridging-the-ActiveMQ-with-IBM-Websphere-using-Camel-tp19623329s22882p19833105.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

JavaRat
You are correct here Claus, using the parameter:

<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>

seems to make no difference at all and we should remove it.

Instead we tried using:
<property name="transportType" value="1" />
This unfortunately didn’t have an effect on the result.

Taking a dive into servicemix-jms is the next step for sure here! This might reveal some answers.

From what I understand camel JMS is based on org.springframework.jms.core.JmsTemplate?
We could perhaps make use of this?

Reply | Threaded
Open this post in threaded view
|

RE: Bridging the ActiveMQ with IBM Websphere using Camel

Claus Ibsen
Hi

I was wondering if you should use a different constant that = JMS.

So this one should be changed:
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>

To:
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_JMS_MQ"/>
</property>

Notice: That the 2nd is a JMS (there is not a NON). This constant is the "1" I have sent to you in my sample, so it could probably be configured as:
<property name="transportType" value="1"/>


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: JavaRat [mailto:[hidden email]]
Sent: 6. oktober 2008 09:52
To: [hidden email]
Subject: RE: Bridging the ActiveMQ with IBM Websphere using Camel


You are correct here Claus, using the parameter:

<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ"/>
</property>

seems to make no difference at all and we should remove it.

Instead we tried using:
<property name="transportType" value="1" />
This unfortunately didn't have an effect on the result.

Taking a dive into servicemix-jms is the next step for sure here! This might
reveal some answers.

From what I understand camel JMS is based on
org.springframework.jms.core.JmsTemplate?
We could perhaps make use of this?


--
View this message in context: http://www.nabble.com/Bridging-the-ActiveMQ-with-IBM-Websphere-using-Camel-tp19623329s22882p19833403.html
Sent from the Camel - Users mailing list archive at Nabble.com.