Friday, June 28, 2013

Webinar on JBoss A-MQ High Availability

We are planning to do the following webinar on JBoss A-MQ High Availability on July 16th. (registration for live webinar and on demand after at http://www.redhat.com/about/events-webinars/)

Title: Deploying JBoss A-MQ in a High Availability (HA) environment
Speaker: Kenny Peeples, Scott Cranton, Jack Britton
Abstract:
The possibility of catastrophic failures such as network failures, power outages, etc should be taken into account when building a production environment so that applications will be continuously available. If a broker fails due to these catastrophic events then messages cannot be delivered until the broker restarts. Additionally if non-persistent messaging is used and a broker fails then message loss can occur.

JBoss A-MQ achieves high availability (HA) through clustering to enable continuous operation.  The JBoss A-MQ HA deployments are known as master/slave which means one broker has the role of the master and there are one or more slave brokers that wait for the failure of the master, at which point one will take over to become the new master.  The JBoss A-MQ clients automatically switch from the failed master to the new master.  We will go further into these concepts in the webinar so that you can create a JBoss A-MQ HA environment.

In this webinar, you’ll learn:

-JBoss A-MQ HA Concepts
-How to deploy complex A-MQ Networks
-How to use a fabric-based network of brokers

A demonstration during the webinar will show how to configure, deploy and test a fabric-based network of fault-tolerant (master/slave) brokers.  You will see how a failure of an active broker will not impact continued message flow.

Fuse Integration in Healthcare

Michelle Davis, Solutions Architect, and myself did the following webcast on Fuse Integration in Healthcare. 

http://www.bitpipe.com/detail/RES/1369075754_86.html?asrc=CL_PRM_RedHat

During this session, we will discuss what is Jboss Fuse and how it can be leveraged to solve today's healthcare integration challenges.  Additionally, we will walk through a demonstration of a Red Hat JBoss Fuse quickstart which utilizes the HL7 Camel Component.

In this podcast, you will:

-Listen to how JBoss Fuse can be leveraged to solve current healthcare challenges
-Witness a demonstration of using the Camel HL7 component with the ability to download and run the project

Integration with Apache Camel in jaxmagazine


Senior Enterprise Architect at Red Hat and Apache Fellow, Charles Moulliard,  discusses Integration with Apache Camel in the latest jaxmagazine.  He will get you over the hump, by detailing the inner workings of Apache Camel from the DSL to routes and exchanges.

http://tinyurl.com/ky4nmfr

Wednesday, June 19, 2013

JBoss A-MQ Broker, Consumer and Producer with SSL in JBDS

This example shows how to run an A-MQ Broker, Producer and Consumer with SSL within JBoss Developer Studio.

Broker
1. Create a Maven project using the maven-archetype-quickstart with artifactId and groupId
<groupId>summit.example.activemq</groupId>
<artifactId>broker</artifactId>

2. Add the broker.ks and broker.ts files for the truststore and keystore from the conf directory from apache-activemq-5.8.0

3. Update the pom.xml with the following which has the maven-activemq-plugin

<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>summit.example.activemq</groupId>
  <artifactId>broker</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>broker</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
    <build>
    <plugins>
      <plugin>
        <groupId>org.apache.activemq.tooling</groupId>
        <artifactId>maven-activemq-plugin</artifactId>
        <version>5.1</version>
        <configuration>
          <configUri>xbean:file:activemq.xml</configUri>
          <fork>false</fork>
          <systemProperties>
            <property>
              <name>org.apache.activemq.default.directory.prefix</name>
              <value>./target/</value>
            </property>
          </systemProperties>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
            <version>2.5.5</version>
          </dependency>
          <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty-xbean</artifactId>
            <version>6.1.11</version>
          </dependency>
          <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-activemq</artifactId>
            <version>1.1.0</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>


4. Create the A-MQ activemq.xml file.  Notice the sslContext and the uri in the transportConnector.

<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:amq="http://activemq.apache.org/schema/core"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://activemq.apache.org/schema/core
  http://activemq.apache.org/schema/core/activemq-core.xsd">
  <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="./data">
   <sslContext>
       <sslContext keyStore="file:broker.ks"
           keyStorePassword="password"
           trustStore="file:broker.ts"
           trustStorePassword="password"/>
    </sslContext>
    <!-- The transport connectors ActiveMQ will listen to -->
    <transportConnectors>
      <transportConnector name="ssl" uri="ssl://localhost:61001"/>
    </transportConnectors>
  </broker>
</beans>


5. Next add the ActiveMQ Broker run configuration with the correct goal org.apache.activemq.tooling:maven-activemq-plugin:5.2.0:run



6. Run the Broker Configuration and view the output for the running broker listening on the port defined in activemq.xml









Consumer
7. Create a Maven project using the maven-archetype-quickstart
  <groupId>summit.example.activemq</groupId>
  <artifactId>consumer</artifactId>


8. Update the pom.xml
<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>summit.example.activemq</groupId>
  <artifactId>consumer</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>consumer</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
<dependency>
  <groupId>javax.jms</groupId>
  <artifactId>jms</artifactId>
  <version>1.1</version>
  <type>pom</type>
</dependency>
    <dependency>
      <groupId>org.apache.activemq</groupId>
     <artifactId>activemq-core</artifactId>
      <version>5.2.0</version>
    </dependency>
  </dependencies>
</project>


9.  Create the consumer.java class
package summit.example.activemq.consumer;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Consumer implements MessageListener
{
    public static String brokerURL = "ssl://localhost:61001";
    private Connection connection;
    private Session session;
    private MessageConsumer consumer;
    public static void main( String[] args )
    {
        Consumer app = new Consumer();
        app.run();
    }
    public void run()
    {
        try
        {
            ConnectionFactory factory = new ActiveMQConnectionFactory(brokerURL);
            connection = factory.createConnection();
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            Destination destination = session.createQueue("test");
            consumer = session.createConsumer(destination);
            consumer.setMessageListener(this);
        }
        catch (Exception e)
        {
            System.out.println("Caught:" + e);
            e.printStackTrace();
        }
    }
    public void onMessage(Message message)
    {
        try
        {
            if (message instanceof TextMessage)
            {
                TextMessage txtMessage = (TextMessage)message;
                System.out.println("Message received: " + txtMessage.getText());
            }
            else
            {
                System.out.println("Invalid message received.");
            }
        }
        catch (JMSException e)
        {
            System.out.println("Caught:" + e);
            e.printStackTrace();
        }
    }
}


10. Create the run configuration for the consumer with the goal
clean compile exec:java -Dexec.mainClass=summit.example.activemq.consumer.Consumer














 11. Add the ssl parameters to the JVM parameters in the consumer run configuration
-Djavax.net.ssl.keyStore=client.ks -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=client.ts  -Djavax.net.ssl.trustStorePassword=password

12. Run the consumer run configuration.  The consumer should start and wait on messages.

Producer
13.  Create the producer similar to the consumer.
pom.xml
<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>summit.example.activemq</groupId>
  <artifactId>producer</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>producer</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
<dependency>
  <groupId>javax.jms</groupId>
  <artifactId>jms</artifactId>
  <version>1.1</version>
  <type>pom</type>
</dependency>
    <dependency>
      <groupId>org.apache.activemq</groupId>
     <artifactId>activemq-core</artifactId>
      <version>5.2.0</version>
    </dependency>
  </dependencies>
</project>

producer.java
package summit.example.activemq.producer;

import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;

public class Producer {

        public static String brokerURL = "ssl://localhost:61001";
        private ConnectionFactory factory;
        private Connection connection;
        private Session session;
        private MessageProducer producer;
   
        public static void main( String[] args ) throws Exception
        {
            // setup the connection to ActiveMQ
            ConnectionFactory factory = new ActiveMQConnectionFactory(brokerURL);
   
            Producer producer = new Producer(factory, "test");
            producer.run();
            producer.close();
        }

   
        public Producer(ConnectionFactory factory, String queueName) throws JMSException
        {
            this.factory = factory;
            connection = factory.createConnection();
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            Destination destination = session.createQueue(queueName);
            producer = session.createProducer(destination);
        }
   
        public void run() throws JMSException
        {
            for (int i = 0; i < 100; i++)
            {
                System.out.println("Creating Message " + i);
                Message message = session.createTextMessage("Hello World!");
                producer.send(message);
            }
        }
   
        public void close() throws JMSException
        {
            if (connection != null)
            {
                connection.close();
            }
        }

}


run configuration
goal: clean compile exec:java -Dexec.mainClass=summit.example.activemq.producer.Producer
JVM params: -Djavax.net.ssl.keyStore=client.ks -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=client.ts  -Djavax.net.ssl.trustStorePassword=password

14. Run the producer to see messages sent and messages received
producer output


consumer output





Tuesday, June 18, 2013

CamelOne 2013 Security Presentation

I have uploaded the CamelOne 2013 Presentation on Karaf, CXF, A-MQ and Camel Security.  I will be posting examples shortly.   Alot of examples and material are in the Security Guide.

http://www.slideshare.net/opensourcementor/kenneth-peeples-presentation

https://access.redhat.com/site/documentation/en-US/JBoss_Fuse/6.0/html/Security_Guide/files/front.html

Monday, June 3, 2013

Fuse and Spring DSL with JDBC and Postgresql



The Apache Camel JDBC component enables you to access databases through JDBC, where SQL queries and operations are sent in the message body.  This component uses the standard JDBC API, unlike the SQL component, which uses spring-jdbc.

I installed the following products and built an example using the jdbc component by creating a Fuse Project with the camel-spring archetype.  I also created a new database, user and table in Postgres.
  • PostgreSQL 9.2
  • pgAdmin III
  • Fedora 18
  • Fuse 6.0 
  • Fuse IDE 6.0
The new project is created with a Spring DSL, sample messages and routes.  I added a new when, log and 2 endpoints.  A bean is used to setup the SQL statement to send to the datasource.  The FuseIDE designer is shown below after the route was added.


The camel-context.xml is shown below.  Notice the datasource and the OrderToSQLBean along with the route.


<?xml version="1.0" encoding="UTF-8"?>
<!-- Configures the Camel Context-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/camel" />
        <property name="username" value="cameluser" />
        <property name="password" value="camel" />
    </bean>

       <bean id="orderToSQL" class="com.mycompany.camel.spring.jdbc.OrderToSQLBean" />
  <camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <description>here is a sample which processes the input files
         (leaving them in place - see the 'noop' flag)
         then performs content based routing on the message using XPath</description>
        <from uri="file:src/data?noop=true"/>
        <choice>
            <when>
                <xpath>/person/city = 'London'</xpath>
                <log message="UK message"/>
                <to uri="file:target/messages/uk"/>
            </when>
            <when>
                <xpath>/person/city = 'Charleston'</xpath>
                <log message="US message"/>
                <to uri="bean:orderToSQL?method=toSql"/>
                <to uri="jdbc:datasource"/>
            </when>

            <otherwise>
                <log message="Other message"/>
                <to uri="file:target/messages/others"/>
            </otherwise>
        </choice>
    </route>
</camelContext>
</beans>



I built the toSql method in the OrderToSQLBean.java to take the name information to put into the camel database.  I created the main and dump methods for testing the connection to the database.

package com.mycompany.camel.spring.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.camel.language.XPath;

public class OrderToSQLBean {

    /**
     * @param args
     */
    public static void main(String[] args) {
         try {
             Class.forName("org.postgresql.Driver" );
             } catch (Exception e) {
             System.err.println("ERROR: failed to load JDBC driver.");
             e.printStackTrace();
             }
             try {
                Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/camel", "cameluser", "camel");
                Statement st = null;
                ResultSet rs = null;
                st = c.createStatement();
                rs = st.executeQuery("SELECT * FROM testtable;");
                dump(rs);
                st.close();   
            } catch (SQLException e) {
                e.printStackTrace();
            }

    }
    public static void dump(ResultSet rs) throws SQLException {
        ResultSetMetaData meta   = rs.getMetaData();
        int colmax = meta.getColumnCount();
        int i;
        Object o = null;
        for (; rs.next(); ) {
            for (i = 0; i < colmax; ++i) {
                o = rs.getObject(i + 1);
                System.out.print(o.toString() + " ");
            }
            System.out.println(" ");
        }
    } 
    public String toSql(@XPath("person/firstName") String firstName,
        @XPath("person/lastName") String lastName,
        @XPath("person/city") String city)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("insert into people ");
        sb.append("(country, lastname, firstname, city) values (");
        sb.append("'US', ");
        sb.append("'").append(lastName).append("', ");
        sb.append("'").append(firstName).append("', ");
        sb.append("'").append(city).append("') ");
        return sb.toString();
    }
   
}








I added the dependencies in the 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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mycompany</groupId>
  <artifactId>camel-spring-jdbc</artifactId>
  <packaging>jar</packaging>
  <version>1.0.0-SNAPSHOT</version>
  <name>A Camel Spring Route</name>
  <url>http://www.myorganization.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
   </properties>
  <repositories>
    <repository>
      <id>release.fusesource.org</id>
      <name>FuseSource Release Repository</name>
      <url>http://repo.fusesource.com/nexus/content/repositories/releases</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <enabled>true</enabled>
      </releases>
    </repository>
    <repository>
      <id>snapshot.fusesource.org</id>
      <name>FuseSource Snapshot Repository</name>
      <url>http://repo.fusesource.com/nexus/content/repositories/snapshots</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
      <releases>
        <enabled>false</enabled>
      </releases>
    </repository>
  </repositories>

  <pluginRepositories>
    <pluginRepository>
      <id>release.fusesource.org</id>
      <name>FuseSource Release Repository</name>
      <url>http://repo.fusesource.com/nexus/content/repositories/releases</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <enabled>true</enabled>
      </releases>
    </pluginRepository>
    <pluginRepository>
      <id>snapshot.fusesource.org</id>
      <name>FuseSource Snapshot Repository</name>
      <url>http://repo.fusesource.com/nexus/content/repositories/snapshots</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
      <releases>
        <enabled>false</enabled>
      </releases>
    </pluginRepository> 
  </pluginRepositories>

  <dependencies>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-core</artifactId>
      <version>2.10.0.redhat-60024</version>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-spring</artifactId>
      <version>2.10.0.redhat-60024</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jdbc</artifactId>
        <version>2.10.0.redhat-60024</version>
    </dependency>
    <dependency>
        <groupId>hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>1.8.0.7</version>
    </dependency>
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901.jdbc4</version>
    </dependency>
   
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>3.0.7.RELEASE</version>
    </dependency>
    <!-- logging -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.6.6</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.6</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

    <!-- testing -->
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-test-spring</artifactId>
      <version>2.10.0.redhat-60024</version>
      <scope>test</scope>
    </dependency>

  </dependencies>

  <build>
    <defaultGoal>install</defaultGoal>

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.5.1</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.4.3</version>
        <configuration>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>

      <!-- allows the route to be ran via 'mvn camel:run' -->
      <plugin>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-maven-plugin</artifactId>
        <version>2.10.0.redhat-60024</version>
      </plugin>
    </plugins>
  </build>
</project>


To test a message with a US city I created a new message3.xml to process.
<?xml version="1.0" encoding="UTF-8"?>
<person user="kenneth">
  <firstName>Kenneth</firstName>
  <lastName>Peeples</lastName>
  <city>Charleston</city>
</person>


References:

https://access.redhat.com/site/documentation/en-US/JBoss_Fuse/6.0/html/EIP_Transaction_Guide/files/TxnManagers-Samples-JDBC.html

https://github.com/FuseByExample/camel-persistence-part1/
http://camel.apache.org/jdbc.html
http://www.if-not-true-then-false.com/2012/install-postgresql-on-fedora-centos-red-hat-rhel/
https://access.redhat.com/site/documentation/en-US/Fuse_IDE/7.1/html/Introduction_to_Fuse_IDE/files/IDEIntroEclipseCreate.html