4

How should the following userid/password property expressions translated into blueprint "bean" notation?

MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();

connectionFactory.setBooleanProperty(WMQConstants.CAPABILITY_USERNAME_PASSWORD, true); //XMSC_CAPABILITY_USERNAME_PASSWORD
connectionFactory.setStringProperty(WMQConstants.USERID, "admin");  //"XMSC_USERID"
connectionFactory.setStringProperty(WMQConstants.PASSWORD, "passw0rd"); //XMSC_PASSWORD  

When deploying to JBoss Fuse, the camel-route.xml (blueprint) chokes on the userid, password part...

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
       xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
       xmlns:camel="http://camel.apache.org/schema/blueprint"
       xsi:schemaLocation="
         http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
         http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
         http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
         ">

    <camel:camelContext id="aaa.bbb.ccc.routing.poc" xmlns="http://camel.apache.org/schema/blueprint">
    <packageScan>
        <package>aaa.bbb.ccc*</package>
    </packageScan>
    </camel:camelContext>

    <bean id="camelRestService" class="aaa.bbb.ccc.CamelRestService"/>     

    <!-- need to convert to blueprint bean representation...
    connectionFactory.setStringProperty(WMQConstants.USERID, "admin");  //"XMSC_USERID", "admin"
    connectionFactory.setStringProperty(WMQConstants.PASSWORD, "passw0rd"); //"XMSC_PASSWORD", "passw0rd"       
    -->

    <bean id="connectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="transportType" value="1"/>
    <property name="hostName" value="localhost"/>
    <property name="port" value="1414"/>
    <property name="queueManager" value="QM1"/>
    <property name="channel" value="DEV.APP.SVRCONN" />    
    <property name="XMSC_USERID" value="admin" />  
    <property name="XMSC_PASSWORD" value="passw0rd" />        
    </bean>    

    <bean id="ibmMqConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="concurrentConsumers" value="10"/>    
    </bean>

    <bean id="ibmMq" class="org.apache.camel.component.jms.JmsComponent">
    <property name="configuration" ref="ibmMqConfig"/>         
    </bean>
</blueprint>    

QUESTION: How should the above user and password properties be written as proper blueprint "bean" property notation?

please note: the java code, when run in a standalone client works fine. -Apparently, "WMQConstants.USERID" resolves to "XMSC_USERID"... -at least according to my NetBeans debugger. :-)

On deploy getting the following error...

org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to find property descriptor XMSC_USERID on class com.ibm.mq.jms.MQQueueConnectionFactory

SOLUTION FOUND! :-)

NOTE: I did not receive a direct answer as to how to convert the java property setter statements in to blueprint "beans". But, thanks to help/postings from generous individuals, I arrived at the working solution, below...:

I included relatively full code/context, i.e., to enable others to arrive at the solution more quickly than I did :-)


aaa.bbb.ccc.CamelRestRoutes.java

package aaa.bbb.ccc;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.rest.RestBindingMode;

public class CamelRestRoutes extends RouteBuilder {

    public CamelRestRoutes() {
    }

    @Override
    public void configure() throws Exception {

    restConfiguration().component("restlet")
        .host("localhost")
        .port(8182)
        //.bindingMode(RestBindingMode.json_xml);
        .bindingMode(RestBindingMode.json);

    rest("/service")
        //.bindingMode(RestBindingMode.json_xml)
        .bindingMode(RestBindingMode.json)
        .get("/getAll")
        .produces("application/json")
        .to("direct:thingX");

    from("direct:thingX")
        .to("bean:camelRestService?method=getAll")
        .log("---------------------- (AAA) ----------------------> direct:thingX...:" + body().toString())
        .to("direct:thingY");

    from("direct:thingY")
        .log("---------------------- (BBB) ----------------------> direct:thingY...:" + body().toString())
        .to("direct:thingZ");

    from("direct:thingZ")
        .log("---------------------- (CCC) ----------------------> direct:thingZ...:" + body().toString())
        .to("wmq:queue:mylocalqueue?jmsMessageType=Text&exchangePattern=InOnly");        
    }
}

aaa.bbb.ccc.CamelRestService.java

package aaa.bbb.ccc;

import aaa.bbb.ccc.model.CamelRestPojo;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.MediaType;

@Path("/service/")
public class CamelRestService {

    Map<Long, CamelRestPojo> itemMap = new HashMap<>();

    public CamelRestService() {
    init();
    }

    @GET
    //@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    @Produces({MediaType.APPLICATION_JSON})
    @Path("/getAll/")
    public Collection<CamelRestPojo> getAll() {
    System.out.println("====================== (getAll) ---------------------->");
    return itemMap.values();
    }

    final void init() {
    System.out.println("---------------------- (init) ---------------------->");
    CamelRestPojo o = new CamelRestPojo();
    o.setName("JOE BLOW");
    o.setId(100);
    itemMap.put(o.getId(), o);
    }
}

aaa.bbb.ccc.model.CamelRestPojo

package aaa.bbb.ccc.model;

import java.io.Serializable;
public class CamelRestPojo implements Serializable {

    private long id;
    private String name;

    public long getId() {
    return id;
    }
    public void setId(long id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }

    @Override
    public String toString() {
    return "CamelRestPojo{" + "id=" + id + ", name=" + name + '}';
    }
}

camel-route.xml

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
       xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
       xmlns:camel="http://camel.apache.org/schema/blueprint"
       xsi:schemaLocation="
         http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
         http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
         http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
         ">
    <camel:camelContext id="aaa.bbb.ccc.routing.poc" xmlns="http://camel.apache.org/schema/blueprint">
    <packageScan>
        <package>aaa.bbb.ccc</package>
    </packageScan>
    </camel:camelContext>

    <bean id="camelRestService" class="aaa.bbb.ccc.CamelRestService"/> 

    <bean id="wmqcf" class="com.ibm.mq.jms.MQConnectionFactory">
    <property name="hostName" value="localhost"/>        
    <property name="port" value="1414"/>
    <property name="queueManager" value="QM1"/>     
    <property name="channel" value="DEV.ADMIN.SVRCONN"/>                     
    <property name="transportType" value="1"/>
    </bean>

    <bean id="wmqcfw"  class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
    <property name="targetConnectionFactory" ref="wmqcf" />
    <property name="username" value="admin" />
    <property name="password" value="passw0rd" />
    </bean>  

    <bean id="wmqcfg" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="wmqcfw"/>
    <property name="concurrentConsumers" value="10"/>
    </bean>

    <bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
    <property name="configuration" ref="wmqcfg"/>     
    </bean>    
</blueprint>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>aaa.bbb.ccc</groupId>
    <artifactId>camelRest</artifactId>
    <version>1</version>
    <packaging>bundle</packaging>
    <name>camelRest</name>
    <description>camelRest</description>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <skipTests>true</skipTests>
    <mq.version>8.0.0.7</mq.version>
    </properties>

    <dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.25</version>
        <scope>provided</scope>               
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
        <scope>provided</scope>               
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>2.17.0</version>
        <scope>provided</scope>
    </dependency>           
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-restlet</artifactId>
        <version>2.17.0</version> 
        <scope>provided</scope>                     
    </dependency>       
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-cxf</artifactId>
        <version>2.17.0</version>
        <scope>provided</scope>              
    </dependency> 
    <dependency>
        <groupId>com.ibm.mq</groupId>
        <artifactId>allclient</artifactId>
        <version>${mq.version}</version>
        <scope>provided</scope>               
    </dependency>
    <dependency>
        <groupId>com.ibm.mq</groupId>
        <artifactId>jms</artifactId>
        <version>${mq.version}</version>
        <scope>provided</scope>
    </dependency>  

    </dependencies>

    <build>
    <finalName>${project.artifactId}-${project.version}</finalName>

    <resources>
        <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        </resource>
    </resources>

    <plugins>
        <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <showDeprecation>true</showDeprecation>
        </configuration>
        </plugin>   
        <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>3.3.0</version>
        <extensions>true</extensions>
        <configuration>
            <instructions>
            <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
            <Export-Package>aaa.bbb.ccc*</Export-Package> 
            <Import-Package>*</Import-Package>                                                                      
            </instructions>
        </configuration>
        </plugin>             
    </plugins>
    </build>
</project>

here is the contents of the jboss fuse "deploy" folder

C:\tools\jboss-fuse-6.3.0.redhat-187\deploy>dir
 Volume in drive C is OSDisk
 Volume Serial Number is D89B-75DE

 Directory of C:\tools\jboss-fuse-6.3.0.redhat-187\deploy

08/17/2017  01:49 PM    <DIR>          .
08/17/2017  01:49 PM    <DIR>          ..
08/17/2017  01:49 PM             7,975 camelRest-1.jar
06/29/2017  01:00 AM           159,649 com.ibm.mq.osgi.allclientprereqs_8.0.0.7.jar
06/29/2017  01:00 AM         8,011,749 com.ibm.mq.osgi.allclient_8.0.0.7.jar
06/29/2017  01:00 AM         4,088,715 com.ibm.mq.osgi.java_8.0.0.7.jar
06/29/2017  01:00 AM           171,064 com.ibm.msg.client.osgi.commonservices.j2se_8.0.0.7.jar
06/29/2017  01:00 AM            48,715 com.ibm.msg.client.osgi.jms.prereq_8.0.0.7.jar.DISABLE
06/29/2017  01:00 AM           639,807 com.ibm.msg.client.osgi.jms_8.0.0.7.jar
06/29/2017  01:00 AM           216,218 com.ibm.msg.client.osgi.nls_8.0.0.7.jar
06/29/2017  01:00 AM           279,861 com.ibm.msg.client.osgi.wmq.nls_8.0.0.7.jar
06/29/2017  01:00 AM            92,406 com.ibm.msg.client.osgi.wmq.prereq_8.0.0.7.jar
06/29/2017  01:00 AM         7,963,226 com.ibm.msg.client.osgi.wmq_8.0.0.7.jar
09/15/2016  04:19 AM               873 README
          12 File(s)     21,680,258 bytes
           2 Dir(s)  143,871,660,032 bytes free

C:\tools\jboss-fuse-6.3.0.redhat-187\deploy>

other notes...

fwiw, I had add following features: 

    -camel-jackson
    -camel-restlet

(I'm sure your "mileage will vary" as you tinker to make your IBM MQ app work, etc)

Also, fwiw, running:  
    features:list | grep "jms" 
yields....

    JBossFuse:karaf@root> features:list | grep "jms"
    [installed  ] [2.4.0.redhat-630187  ] jms                                           karaf-enterprise-2.4.0.redhat-630187   JMS service and commands
    [installed  ] [2.17.0.redhat-630187 ] camel-jms                                     camel-2.17.0.redhat-630187
    [uninstalled] [2.17.0.redhat-630187 ] camel-sjms                                    camel-2.17.0.redhat-630187
    [uninstalled] [3.1.5.redhat-630187  ] cxf-transports-jms                            cxf-3.1.5.redhat-630187
    [uninstalled] [2.1.0.redhat-630187  ] switchyard-jms                                switchyard-2.1.0.redhat-630187
    [uninstalled] [2.1.0.redhat-630187  ] switchyard-quickstart-bpel-jms-binding        switchyard-2.1.0.redhat-630187
    [uninstalled] [2.1.0.redhat-630187  ] switchyard-quickstart-camel-jms-binding       switchyard-2.1.0.redhat-630187
    [uninstalled] [2.1.0.redhat-630187  ] switchyard-demo-security-propagation-jms      switchyard-2.1.0.redhat-630187
    [uninstalled] [1.1                  ] jms-spec                                      activemq-core-5.11.0.redhat-630187     JMS spec 1.1 libraries
    [installed  ] [2.0                  ] jms-spec                                      activemq-core-5.11.0.redhat-630187     JMS spec 2.0 libraries
    [uninstalled] [1.1                  ] jms-spec-dep                                  activemq-core-5.11.0.redhat-630187     JMS spec 1.1 dependency
    [installed  ] [2.0                  ] jms-spec-dep                                  activemq-core-5.11.0.redhat-630187     JMS spec 2.0 dependency
    [uninstalled] [5.11.0.redhat-630187 ] activemq-jms-spec-dep                         activemq-core-5.11.0.redhat-630187     ActiveMQ broker libraries
    [installed  ] [3.2.16.RELEASE_1     ] spring-jms                                    spring-2.4.0.redhat-630187             Spring 3.2.x JMS support 

Special thank you to all who helped me on the pain-staking journey that landed this solution! :-)

sairn
  • 461
  • 3
  • 24
  • 58

2 Answers2

3

XMS is IBM's implementation of a JMS like interfaces in non-Java languages like C# and C++. XMS constants would not be present in the IBM MQ Classes for JMS libraries.

I took your sample and changed the names of some of the beans and wrapped the MQQueueConnectionFactory with org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter to pass the credentials.

UPDATE: In reading the source for Apache Camel's org.apache.camel.component.jms.JmsComponent it appears that if it is provided with a username and password it will wrap the connection factory with UserCredentialsConnectionFactoryAdapter automatically.

Try with the following changes:

<bean id="ibmMqConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="transportType" value="1"/>
    <property name="hostName" value="localhost"/>
    <property name="port" value="1414"/>
    <property name="queueManager" value="QM1"/>
    <property name="channel" value="DEV.APP.SVRCONN" />    
</bean>    

<bean id="ibmMqConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="ibmMqConnectionFactory"/>
    <property name="concurrentConsumers" value="10"/>    
</bean>

<bean id="ibmMq" class="org.apache.camel.component.jms.JmsComponent">
    <property name="configuration" ref="ibmMqConfig"/>
    <property name="username"                value="admin"/>
    <property name="password"                value="passw0rd"/>     
</bean>
JoshMc
  • 10,239
  • 2
  • 19
  • 38
  • Hi JoshMc - I've tried you suggestion (maybe too literally? let me know if I've left something out) and posted the results, above – sairn Aug 16 '17 at 18:46
  • 1
    @sairn Apologies if I am pointing you in the wrong direction, all the examples I have seen with Apache Camel using IBM MQ were using Spring. Is it possible for you to use Spring with Apache Camel to gain the use of UserCredentialsConnectionFactoryAdapter? Some other posts on here suggest this is the only Spring component they use. – JoshMc Aug 16 '17 at 20:42
  • np, joshmc :-) need the "non-spring" solution, if one exists. In the meantime, let me know if you familiar w/ how to properly convert the java property setters statements (above) into the blueprint bean equivalent? I'd like to explore whether that makes a difference. thx – sairn Aug 17 '17 at 14:07
  • @sairn See my update above and try what I suggested. – JoshMc Aug 17 '17 at 16:12
  • @saim did my revised suggestion work? I noticed you accepted the answer from KevinBoone which was similar to the original answer I provided. Did you have to do something to resolve the exception: "Caused by: java.lang.ClassNotFoundException: org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter not found by aaa.bbb.ccc.camelRest [832]" which the other answer is also referencing? – JoshMc Aug 17 '17 at 18:17
  • Hi JoshMc -I was rather conflicted, but, ultimately chose ("checked") Kevin Boone's answer. I've posted the "final solution" above. That said, I up-voted your comments - in this and a related post - as the truth is that the all the posts together, drastically improved my understanding of how to use IBM MQ with JBossFuse. Thx!!! – sairn Aug 17 '17 at 18:39
  • @sairn what did you have to do to resolve the `ClassNotFoundException` for `org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter`? It appears the final solution is also referencing this in the same way I suggested. I would like to understand more for myself in the future as well what actually made this work? – JoshMc Aug 17 '17 at 18:58
  • @sairn If my updated answer is incorrect I can either delete it or roll it back to the answer that looked more like Kevin Boone's answer. – JoshMc Aug 17 '17 at 19:04
  • I think my answer is essentially the same as JoshMc's answer, except that I included the BluePrint XML boilerplate :) – Kevin Boone Aug 21 '17 at 10:41
  • @KevinBoone thank you. I didn't include all of it since he had that in the original question. My later modification was based on reading the source it appears that if you provide a username and password to org.apache.camel.component.jms.JmsComponent it will automatically wrap the connection factory with org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter. I don't have Apache Camel setup to test this, or know in what version of Apache Camel it was added. – JoshMc Aug 21 '17 at 18:22
2

If you're working with a stock Fuse installation, you should be able to use Spring classes within Blueprint code. Here is a Blueprint XML that works for me with W-MQ.

<?xml version="1.0" encoding="UTF-8"?> 
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instancexmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
    xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 
        http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">

    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
        <route id="timer">
          <from uri="timer://foo?fixedRate=true&amp;period=5000" />
          <setBody>
            <constant>Hello World.</constant>
          </setBody>
          <to uri="wmqxa:queue:QUEUE1"/>
        </route>
    </camelContext>
    <bean id="wmqxa" class="org.apache.camel.component.jms.JmsComponent">
        <property name="configuration" ref="WMQConfig"/>
    </bean>

    <bean id="WMQConfig" class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="WMQConnectionFactoryWrapper"/>
        <property name="maxConcurrentConsumers" value="5"/>
        <property name="cacheLevelName" value="CACHE_CONNECTION"/>
    </bean>

    <bean id="WMQConnectionFactory" class="com.ibm.mq.jms.MQConnectionFactory">
        <property name="hostName" value="192.168.1.51" />
        <property name="port" value="1414" />
        <property name="queueManager" value="QMA" />
        <property name="channel" value="MYCHANNEL" />
        <property name="transportType" value="1" />
        <property name="shareConvAllowed" value="1" />
        <property name="useConnectionPooling" value="true" />
        <property name="SSLFipsRequired" value="false" />
    </bean>

  <bean id="WMQConnectionFactoryWrapper"  class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
        <property name="targetConnectionFactory" ref="WMQConnectionFactory" />
        <property name="username" value="kevin" />
        <property name="password" value="password" />
  </bean>
</blueprint>
JoshMc
  • 10,239
  • 2
  • 19
  • 38
Kevin Boone
  • 4,092
  • 1
  • 11
  • 15
  • Hi Kevin - I tried a similar suggestion posted by JoshMc (below), and received classnotfound exception for the spring class. but, I'll retry just to make certain. thx! – sairn Aug 17 '17 at 15:29
  • Hi. The code I posted was from a working installation on Fuse 6.2.1 with (as I recall) nothing extra installed except the W-MQ client runtime. If it still doesn't work, please post the full exception backtrace and the output of osgi:list; these will help with troubleshooting. – Kevin Boone Aug 21 '17 at 10:39