Giter VIP home page Giter VIP logo

camel-quartz-cluster's Introduction

Camel Quartz cluster

Red Hat JBoss Fuse can be used to load balance and cluster using Fuse Fabric. In the absence of Fabric, there are a few options to achieve this particular functionality. These options include:

  • Camel Zookeeper - This component offers a RoutePolicy that can start/stop routes in master/slave fashion. The first route that gets the lock will be started where the remaining routes will be waiting to get the lock.
  • Camel Quartz - This component has clustering support. If you are using quartz consumers, in clustered mode, you can have only one of the routes triggered at a time.
  • Camel JGroups - Using JGroupsFilters, we can get master/slave capability

NOTE: This demo has been created using Red Hat JBoss Fuse 6.0.0-redhat-60024, so the version of Camel that we are limited to is 2.10-redhat-60024, which only supports Quartz 1.x components.

This code is not supported by my employer - Red Hat. I have made this available online to save someone an hour or so of Google searches.

For background reference, see:

The aim of this project is to create a singleton route so that our Camel route runs only on one instance at any point in time. Clustering is achieved by using database as a Persistence layer which can help with the failover. We are using PostgreSQL for this example.

<bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="jdbc:postgresql://localhost:5432/quartz"/>
    <property name="username" value="quartz"/>
    <property name="password" value="quartz"/>
</bean>

Camel Quartz component is initialized with a reference to the scheduler bean:

<bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent">
    <property name="scheduler" ref="scheduler"/>
</bean>

Note that this can also be done by providing a quartz properties file if so desired. A sample file quartzcluster.properties.notused (not fully configured) is added to this project under the META-INF/spring directory for quick reference purposes:

<bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent">
    <property name="propertiesFile" value="META-INF/spring/quartzcluster.properties"/>
</bean>

The key component from the scheduler definition is the schedulerContextAsMap section. This hooks the camel context into the quartz configuration. If this is not configured correctly, and if you reinstall your bundle in the container, you may see errors in your log like: org.quartz.JobExecutionException: No CamelContext could be found with name: 274-quartz-cluster where the bundle id shown would be the previous bundle-id of the deployed application bundle.

<property name="schedulerContextAsMap">
    <map>
        <entry key="CamelQuartzCamelContext" value-ref="quartzCluster"/>
    </map>
</property>

The isClustered flag turns on clustering, and the PostgreSQLDelegate sets the dialect:

<property name="quartzProperties">
    <props>
        <prop key="org.quartz.scheduler.instanceName">myscheduler</prop>
        <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
        <prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
        <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.PostgreSQLDelegate</prop>
        <prop key="org.quartz.jobStore.isClustered">true</prop>
        <prop key="org.quartz.jobStore.clusterCheckinInterval">5000</prop>
    </props>
</property>

The camel context has been configured to fire off every 5 seconds and print a log message:

<camelContext xmlns="http://camel.apache.org/schema/spring" id="quartzCluster" managementNamePattern="#name#">
    <route id="clusteredRoute">
        <from uri="quartz://clustergroup/clusterTimerName?job.name=demoQuartzCluster&amp;cron=0/5+*+*+*+*+?"/>
        <log message="Fired quartz cluster trigger"/>
    </route>
</camelContext>

Testing

Create database and tables in PostgreSQL

Run the commands from the file tables_postgres.sql to create the Quartz tables required for JDBC persistence. Double check the port and credentials used in the camel-context.xml file for the PostgreSQL datasource.

Install two versions of Red Hat JBoss Fuse (this test was done using version 6.0.0-redhat-60024)

If you plan to run them on the same host, the files to be modified to avoid port conflicts are:

${karaf.home}/etc/system.properties

Instance 1: org.osgi.service.http.port=8181 activemq.port=61616 activemq.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-${karaf.name}

Instance 2: org.osgi.service.http.port=8281 activemq.port=61716 activemq.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1199/karaf-${karaf.name}

${karaf.home}/etc/jetty.xml

Instance 1: 8443

Instance 2: 8543

${karaf.home}/etc/org.ops4j.karaf.management.cfg

Instance 1: rmiRegistryPort=1099 rmiServerPort=44444

Instance 2: rmiRegistryPort=1199 rmiServerPort=44544

${karaf.home}/etc/org. apache.karaf.shell.cfg

Instance 1: sshPort=8101

Instance 2: sshPort=8201

Start and install features

Run the following commands from the karaf command line:

features:install quartz

features: install spring-jdbc

Install the PostgreSQL JDBC driver

The proper way to do it would be to install it in your local repository with the right felix-export and import options, and then install it in Fuse. A quick workaround for testing purposes would be to do a wrap install as below:

install -s wrap:file://<path_to_postgresql_jdbc.jar>

Compile and install this application bundle

mvn clean install

In the karaf console:

install -s mvn:com.redhat.gps/quartzcluster/1.0.0-SNAPSHOT

When you do this on both the servers, you will see that only one of them (the first one where the application bundle was installed) will start printing the log statements from our route:

Fired quartz cluster trigger

If you shut down this instance, the other instance should pick up the route, and you will start seeing the log statement being outputted in its logs.

camel-quartz-cluster's People

Contributors

yashpatil avatar

Watchers

Justin.Lee avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.