You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@servicemix.apache.org by guilhelm <gu...@gmail.com> on 2010/04/07 18:53:55 UTC

servicemix-jms consumer with non-xml messages

Hi,

I'm testing ServiceMix 3.3.1 and trying to do the following :

WebsphereMQ ---> servicemix-jms-su ---> servicemix-file-su --> local
directory

With the following servicemix-jms-su configuration :
...
  <jms:endpoint service="tut:mq2file"
                endpoint="mq"
                targetService="tut:mq2file"
                role="consumer"
                targetEndpoint="sender"
                destinationStyle="queue"
                jmsProviderDestinationName="QUEUE_NAME"
                connectionFactory="#mqConnectionFactory"
                defaultMep="http://www.w3.org/2004/08/wsdl/in-only" />
  <bean id="mqConnectionFactory"
class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="transportType">
      <util:constant
static-field="com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP" />
    </property>
    <property name="queueManager" value="QMGR" />
    <property name="hostName" value="HOST" />
    <property name="channel" value="SYSTEM.DEF.SVRCONN" />
    <property name="port" value="PORT" />
  </bean>
  <classpath>
   
<location>/tmp/apache-servicemix-3.3.1/lib/ext/com.ibm.mqjms.jar</location>
    <location>/tmp/apache-servicemix-3.3.1/lib/ext/com.ibm.mq.jar</location>
    <location>/tmp/apache-servicemix-3.3.1/lib/ext/dhbcore.jar</location>
  </classpath>
...

It works very well when I post an xml message in the queue (the message gets
written in a file). But the real messages I'll have to send will be plain
text (fixed length) and these are not accepted...

So I tried another way, as seen here and there on the web. With that
configuration :

...
  <jms:consumer service="tut:mq2file"
                endpoint="mq"
                targetService="tut:mq2file"
                targetEndpoint="sender"
                destinationName="QUEUE_NAME"
                connectionFactory="#mqConnectionFactory"
                marshaler="#myMarshaler" />
  <bean id="myMarshaler"
class="org.apache.servicemix.jms.endpoints.DefaultConsumerMarshaler">
    <property name="mep" value="http://www.w3.org/2004/08/wsdl/in-only" />
  </bean>
  <bean id="mqConnectionFactory"
class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="transportType">
      <util:constant
static-field="com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP" />
    </property>
    <property name="queueManager" value="QMGR" />
    <property name="hostName" value="HOST" />
    <property name="channel" value="SYSTEM.DEF.SVRCONN" />
    <property name="port" value="1414" />
  </bean>
...

The SA deployment is fine, but if I send the same xml message (the one sent
with the first configuration) I get the following exception :

WARN  - DefaultMessageListenerContainer - Execution of JMS message listener
failed
javax.jms.JMSException: Error sending JBI exchange
        at
org.apache.servicemix.jms.endpoints.AbstractConsumerEndpoint.onMessage(AbstractConsumerEndpoint.java:575)
        at
org.apache.servicemix.jms.endpoints.JmsConsumerEndpoint$1.onMessage(JmsConsumerEndpoint.java:505)
        at
org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:518)
        at
org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:479)
        at
org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451)
        at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323)
        at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261)
        at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982)
        at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:974)
        at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:876)
        at java.lang.Thread.run(Thread.java:736)
Caused by:
java.lang.UnsupportedOperationException: JMS message is not a TextMessage
        at
org.apache.servicemix.jms.endpoints.DefaultConsumerMarshaler.populateMessage(DefaultConsumerMarshaler.java:183)
        at
org.apache.servicemix.jms.endpoints.DefaultConsumerMarshaler.createExchange(DefaultConsumerMarshaler.java:99)
        at
org.apache.servicemix.jms.endpoints.AbstractConsumerEndpoint.onMessage(AbstractConsumerEndpoint.java:544)
        ... 10 more

If I send a non-xml message, I get the same exception.

Has anyone succeeded using directly the
org.apache.servicemix.jms.endpoints.DefaultConsumerMarshaler class ?

Thanks for any hint... I'm a bit lost...

PS : this is only the first step, there will be more actions on the message
(fixed length to xlm conversion, xslt transformation, xml to fixed length
conversion and post back to a queue... ) and the idea is to avoid any coding
(if possible).
-- 
View this message in context: http://old.nabble.com/servicemix-jms-consumer-with-non-xml-messages-tp28167771p28167771.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: servicemix-jms consumer with non-xml messages

Posted by guilhelm <gu...@gmail.com>.
Hi !

In fact, the problem was slightly different : it was an MQ issue : the jms
consumer was receiving a BytesMessage and not a TextMessage. I managed this
with the folleowing xbean configuration :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:jms="http://servicemix.apache.org/jms/1.0"
       xmlns:util="http://www.springframework.org/schema/util">

  <jms:consumer service="eu.partecis.simu"
                endpoint="mqin"
		            targetService="eu.partecis.simu"
                targetEndpoint="mqout"
                destination="#inDestination"
                connectionFactory="#inConnectionFactory"
                marshaler="#plainToXmlMarshaler" 
		        />
  <bean id="plainToXmlMarshaler"
class="eu.partecis.esb.toxmlmarshaler.toXMLConsumerMarshaler">
  </bean>
  
  <bean id="inConnectionFactory"
class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="transportType">
      <util:constant
static-field="com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP" />
    </property>
    <property name="queueManager" value="QMGR" />
    <property name="hostName" value="HOST" />
    <property name="channel" value="SYSTEM.DEF.SVRCONN" />
    <property name="port" value="1414" />
  </bean> 

  <bean id="inDestination" class="com.ibm.mq.jms.MQQueue">
    <property name="baseQueueName" value="QUEUE" />
    <property name="baseQueueManagerName" value="QMGR" />
    <property name="targetClient" value="1" />
  </bean>   
  <classpath>
   
<location>/home/panaget/apache-servicemix-3.3.1/lib/ext/com.ibm.mqjms.jar</location>
   
<location>/home/panaget/apache-servicemix-3.3.1/lib/ext/com.ibm.mq.jar</location>
   
<location>/home/panaget/apache-servicemix-3.3.1/lib/ext/dhbcore.jar</location>
   
<location>/home/panaget/apache-servicemix-3.3.1/lib/ext/eu.partecis.esb.toxmlmarshaler.jar</location>
   
<location>/home/panaget/apache-servicemix-3.3.1/lib/ext/eu.partecis.esb.toplaintextmarshaler.jar</location>
  </classpath> 

</beans>

The targetClient property (0 or 1) sets the type of message received...

Then I wrote my own marshaler (just to put <data></data> tags around the
incoming message) :

import javax.xml.transform.Source;
/*
import javax.jbi.component.ComponentContext;
import javax.jbi.messaging.Fault;
import javax.jbi.messaging.MessageExchange;
import javax.jms.Session;


import org.apache.servicemix.jbi.jaxp.SourceTransformer;
import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
*/

public class toXMLConsumerMarshaler extends DefaultConsumerMarshaler {
    
    protected void populateMessage(Message message, NormalizedMessage
normalizedMessage) throws Exception {
if (message instanceof TextMessage) {
            System.out.println("Message de type TextMessage");
            TextMessage textMessage = (TextMessage) message;
            System.out.println(textMessage.getText());
            Source source = new
StringSource("<data>".concat(textMessage.getText()).concat("</data>"));
            normalizedMessage.setContent(source);
        }
        else {
            ;
            throw new UnsupportedOperationException("JMS message is not a
TextMessage : " + message.getClass().getName());
        }
    }
}

And it works fine !

But... once my message has been processed in servicemix it has to be posted
to another MQ queue... without the tags, so I added the following inside
xbean.xml :

  <jms:provider service="eu.partecis.simu"
                endpoint="mqout"
		            destination="#outDestination"
		            connectionFactory="#outConnectionFactory"
		            marshaler="#xmlToPlainTextMarshaler" />
                
  <bean id="xmlToPlainTextMarshaler"
class="eu.partecis.esb.toplaintextmarshaler.toPlainTextProviderMarshaler">
  </bean>


  <bean id="outConnectionFactory"
class="com.ibm.mq.jms.MQQueueConnectionFactory">
	  <property name="transportType">
		  <util:constant
static-field="com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP" />
	  </property>
    <property name="queueManager" value="INFRA.TEST.JMS" />
    <property name="hostName" value="10.77.16.203" />
	  <property name="channel" value="SYSTEM.DEF.SVRCONN" />
	  <property name="port" value="1414" />
  </bean> 
  
  <bean id="outDestination" class="com.ibm.mq.jms.MQQueue">
	  <property name="baseQueueName" value="QLOCAL.INFRA.JMS.ECRITURE" />
	  <property name="baseQueueManagerName" value="INFRA.TEST.JMS" />
    <!--  valeur 1 pour ne transmettre un message du type JMSTextMessage -->
	  <property name="targetClient" value="1" />
  </bean>


And wrote my own provider marshaler just Ias I did for the consumer... but
it is not taken into acount (I put some System.out.println to debug but they
don't appear in the servicemix console !). Thi is how my custom provider
marshaler look like (for the moment it just changes the message to another
text just to see if it works) :

package eu.partecis.esb.toplaintextmarshaler;

import java.lang.System;

import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jbi.messaging.NormalizedMessage;

import org.apache.servicemix.jbi.jaxp.StringSource;
import org.apache.servicemix.jms.endpoints.DefaultProviderMarshaler;
import javax.xml.transform.Source;

public class toPlainTextProviderMarshaler extends DefaultProviderMarshaler {
    
    public Message createMessage(MessageExchange exchange, NormalizedMessage
in, Session session) throws Exception {
        System.out.println("In Message");
        TextMessage text = session.createTextMessage();
//        text.setText(transformer.contentToString(in));
        text.setText("Message_text");
        if (jmsProperties != null) {
            for (Map.Entry<String, Object> e : jmsProperties.entrySet()) {
                text.setObjectProperty(e.getKey(), e.getValue());
            }
        }
        return text;
    }
    protected void populateMessage(Message message, NormalizedMessage
normalizedMessage) throws Exception {
        if (message instanceof TextMessage) {
            System.out.println("In populateMessage");
            TextMessage textMessage = (TextMessage) message;
            Source source = new StringSource("populateMessage_text"));
            normalizedMessage.setContent(source);
        } 
        else {
            throw new UnsupportedOperationException("JMS message is not a
TextMessage");
        }
    }


}

Any idea why it doesn't work ?

Guilhelm
-- 
View this message in context: http://old.nabble.com/servicemix-jms-consumer-with-non-xml-messages-tp28167771p28433531.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: servicemix-jms consumer with non-xml messages

Posted by Ray Brown <ha...@gmail.com>.
Of course you're right about ServiceMix and XML.  I found the "all XML or
nothing" restriction just as ridiculous as you are finding it.  ServiceMix,
as well as it does some things, is not a cure-all.  The best example that I
know of, and others will say that ServiceMix can do it, is streaming video.
Most developers will not want to pipe streaming video(s) through a
ServiceMix installation.  So, you're going to have to let an outside
application convert the straight text into XML before the ServiceMix bus
sees it.  Or, you could switch to Camel.  I have my own problems with
Camel.  Good luck.

On Sun, Apr 18, 2010 at 11:42 AM, guilhelm <gu...@gmail.com>wrote:

>
> Hello,
>
> thanks for your answer, theproblem is : I have an error message even if the
> message content is an xml message !
>
> Anyway, What i'd like to do is convert the text content inside the MQ
> message in a simple XML message like :
>
> <data>text content</data>... (it could be any other tag)
>
> so that it can be used inside servicemix...
>
> I can't believe this has not been done before...
>
>
> Guilhelm
>
>
>
> --
> View this message in context:
> http://old.nabble.com/servicemix-jms-consumer-with-non-xml-messages-tp28167771p28283011.html
> Sent from the ServiceMix - User mailing list archive at Nabble.com.
>
>

Re: servicemix-jms consumer with non-xml messages

Posted by guilhelm <gu...@gmail.com>.
Hello,

thanks for your answer, theproblem is : I have an error message even if the
message content is an xml message !

Anyway, What i'd like to do is convert the text content inside the MQ
message in a simple XML message like : 

<data>text content</data>... (it could be any other tag)

so that it can be used inside servicemix...

I can't believe this has not been done before... 


Guilhelm



-- 
View this message in context: http://old.nabble.com/servicemix-jms-consumer-with-non-xml-messages-tp28167771p28283011.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: servicemix-jms consumer with non-xml messages

Posted by iocanel <ca...@upstreamsystems.com>.
The DefaultConsumerMarshaler you are using assumes that the content of the
message is XML and that causes an error.

You can extend DefaultConsumerMarshaler and override the populateMessage
method and put the the fixed length to xml conversion logic.

Once you do so declare the new marshaler:


<bean id="customJmsConsumerMarshaler"
class="net.guilhelm.CustomJmsConsumerMarshaler"> 

<jms:endpoint service="tut:mq2file" 
                endpoint="mq" 
                targetService="tut:mq2file" 
                role="consumer" 
                targetEndpoint="sender" 
                destinationStyle="queue" 
                jmsProviderDestinationName="QUEUE_NAME" 
                connectionFactory="#mqConnectionFactory"
                marshaler="#customJmsConsumerMarshaler"
                defaultMep="http://www.w3.org/2004/08/wsdl/in-only" /> 



Hope that helps !!!

-----
Ioannis Canellos
-- 
View this message in context: http://old.nabble.com/servicemix-jms-consumer-with-non-xml-messages-tp28167771p28267869.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.