Monday, January 11, 2016

Issue With ObjectMessages 6.2.1 Jboss Fuse and AMQ

If you were working with Jboss Fuse 6.2.0 and migrated to 6.2.1 patch and working with Serialized Java Objects as messages in to AMQ , this post might be of interest to you.
I had a piece of code which was working fine in 6.2.0 version , the code was to simply drop a Java Serialized object in to AMQ  and then read it back.The class is as below
 package com.sundar.verify;  
 import java.io.Serializable;  
 public class MyBean implements Serializable{  
      /**  
       *   
       */  
      private static final long serialVersionUID = 1L;  
      private String id;  
      private String textData;  
      public String getId() {  
           return id;  
      }  
      public void setId(String id) {  
           this.id = id;  
      }  
      public String getTextData() {  
           return textData;  
      }  
      public void setTextData(String textData) {  
           this.textData = textData;  
      }  
 }  
with a camel route
 <camelContext xmlns="http://camel.apache.org/schema/spring">  
           <route>  
                <from uri="timer:foo?repeatCount=1&amp;delay=10000" />  
                <process ref="mybean" />  
                <to uri="activemq:personnel.records" />  
           </route>  
           <route>  
                <from uri="activemq:personnel.records" />  
                <log message="Body is ${body}" />  
           </route>  
 </camelContext>  
This was obsolutely working fine with Fuse 6.2.0 , but when the same code was migrated to 6.2.1 , I suddenly started to notice that the below exception was thrown
 Caused by: javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.sundar.verify.MyBean! This class is not allowed to be serialized. Add package with 'org.apache.activemq.SERIALIZABLE_PACKAGES' system property.  
      at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36)  
      at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:193)  
      at org.apache.camel.component.jms.JmsBinding.extractBodyFromJms(JmsBinding.java:126)  
      ... 23 more  
To prevent this from happening and for the deserilazation to work propertly add the below system property on the client side as below
-Dorg.apache.activemq.SERIALIZABLE_PACKAGES="java.lang,java.util,org.apache.activemq,org.fusesource.hawtbuf,
com.thoughtworks.xstream.mapper,<your-package-names>"  
and for the impatient
-Dorg.apache.activemq.SERIALIZABLE_PACKAGES="*"
In case if you are running the consumer on a fabric container , set the JVM props on the container as in the image below


Fabric Deployment Fuse

Deployments with Fuse And Fabric are very easy , there is a lot of automation available with in fabric which makes writing of scripts to manage devops a redundant process. In this post I am going explore two different ways of pushing changes to Jboss Fuse.

The versions of the products I am using are
  1. Fuse 6.2.1 (bom version : 6.2.1.redhat-084). 
  2. Fabric8 1.2.0.redhat-621084 (fabric maven plugin version : 1.2.0.redhat-133).
Using Fuse Profile Git - Manually

  • Once Fuse Fabric Environment is setup on your local or server. 
  • Go to http://<serverip>:8181
  • Log in to Hawtio using your username and password 
  • Navigate to the Containers , click on the root container navigate to Urls tab and copy the Git Url , it should look like "http://admin:admin@smunirAT-OSX:8181/git/fabric”. 
  • Open your eclipse clone the repository , provide the username and password if prompted. 
  • Create a new branch with a different version number
  • Navigate to the working directory on the Git repo cloned , and import the fabric directory as general project to eclipse .
  • All the profiles which are now the part fo the branch you checked out from git should now appear in eclipse.
  • Edit the file io.fabric8.agent.properties file and change the repositories , features and bundles that you need to add / remove /modify on the profile


 #To add a repository to the profile use the below keyword   
 repository.  
 <repository-name>=mvn\:groupid/<artifactid/version/type/classifer  
   
 #To add a feature to a profile use the below keyword features  
 feature.<feature-name>=<feature-name>  
   
 #To add a bundle to a profile use the below keyword  
 bundle.mvn\:groupid/artifactid/version= mvn\: groupid/artifactid/version  
   
  • Commit to the git repo and push to the remote repositories
Video for Demo Project




Look for The automated part of the above ....in my next post

Thursday, January 7, 2016

Jmeter Jms Publisher with discovery url Java Sampler


  • Add the below Jars to lib/ext directory to the Jmeter installation
      1. activemq-all-5.11.1.jar
      2. fabric-api-1.2.0.redhat-133.jar
      3. fabric-groups-1.2.0.redhat-133.jar
      4. fabric-utils-1.2.0.redhat-133.jar
      5. fabric-zookeeper-1.2.0.redhat-133.jar
      6. guava-17.0.jar
      7. jackson-annotations-2.4.3.jar
      8. jackson-core-2.4.3.jar
      9. jackson-databind-2.4.3.jar
      10. mq-discovery-1.2.0.redhat-133.jar
      11. mq-fabric-1.2.0.redhat-133.jar

  • Extend the class JavaSamplerClient.
  • Add arguments to the getDefaultParameters() method
  • Set the system properties zookeeper.url and zookeeper.password in setupTest() method.
  • Write the test to connect and send messages to the activemq broker.
  • For the complete code please click here
    When fabric is used to create network brokers fabric assigns free ports so that they will not all run on default port settings , also this provides the flexibility to the users to add more brokers in to the mix later on or remove them when the load becomes lesser.

    In this case the better option to connect to these network of brokers instead of using a fail over with all the ip's of the brokers or connecting individual brokers would be to use the discovery URL so to let the fabric manage the details.

    Based on the below post from
    https://github.com/FuseByExample/external-mq-fabric-client

    There are three ways this can be done from Jmeter.Adding the System properties zookeeper.url and zookeeper.password while starting the Jmeter.
    Editing the Jmeter.sh and adding the JVM Parameters
    1. Edit jmeter.sh.
    2. Append the below parameter to the JMETER_OPTS
      "-Dzookeeper.url=<zookeeperurl>  -Dzookeeper.password=<zookeeperpassword>".
    3. Add the below jars to the lib/ext directory.
      1. activemq-all-5.11.1.jar
      2. fabric-api-1.2.0.redhat-133.jar
      3. fabric-groups-1.2.0.redhat-133.jar
      4. fabric-utils-1.2.0.redhat-133.jar
      5. fabric-zookeeper-1.2.0.redhat-133.jar
      6. guava-17.0.jar
      7. jackson-annotations-2.4.3.jar
      8. jackson-core-2.4.3.jar
      9. jackson-databind-2.4.3.jar
      10. mq-discovery-1.2.0.redhat-133.jar
      11. mq-fabric-1.2.0.redhat-133.jar
    4. Run the script jmeter.sh and continue with the JMS publisher and JMS subsriber tests
    5. The sample parameters are as below
      1. intialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory.
      2. providerUrl=discovery:(fabric:<broker-group-name>).
      3. connection factory =ConnectionFactory.
      4. Destination = dynamicQueues/FOO.BAR.
    Customizing the JMSPublisher Sampler with GuiControls
    1. Copy the same jars from above step to lib/ext directory of Jmeter installation.
    2. Write custom code to add a new sampler JMS Activemq Discovery Publisher.I went along the lines of JMSPublisherGui and PublisherSampler from the JMS protocol code , most of the code is copied from them with necessary modifications.
    3. Create a class DiscoveryActivemqPublisherGui that extends AbstractSamplerGui and implements ChangeListener
    4. Create a class DiscoveryPublisherSampler  which extends
      BaseJMSSampler  and implements TestStateListener
      to write the actual Sampler code.
    5. In the initClient method of DiscoveryPublisherSampler write code to set the zookeeper properties to the system variables.
    6. Copy the core part of the source code of Jmeter from here.
    7. Add the property jms_discovery_publisher= JMS Activemq Discovery Publisher to messages.properties. This will be the label of the Sampler.
    8. Use the pom.xml below to compile the code.
  • Replace the ApacheJMeter_core.jar with the jar obtained above.
  • For the complete code please click here