Article in Futures Magazine on our Commodity Trading Program

From the December 2014 issue of Futures Magazine • Subscribe!

Zoi: A match made in cyber heaven

Konstantinos (Gus) Tsahas and Robert Terpilowski had similar ideas regarding trading. These partners, who have been working on trading strategies together for nearly a decade, met of all places on an Interactive Brokers (IB) message board where they began sharing ideas (both have an engineering background) despite being on separate coasts: Tsahas in New York and Terpilowski in Seattle.

“Around 2000, Interactive Brokers offered an API and I began developing a mean reversion strategy for the equity markets,” Terpilowski says. “I was working on software to automate that. Gus actually posted something on the message board of the API group so we hooked up and started bouncing ideas off of each other and hit it off.”

Tsahas adds, “It just turned out that we were working on the same mean reversion ideas. I was further along in some aspects, Rob was [further along] in others. Collaborating helped both of us to come up with some good strategies. That was the start.”

This collaboration continued for five years with both Terpilowski and Tsahas pursuing separate careers: Terpilowski in various civil engineering positions and Tsahas running his own business installing fiber optic lines.

By 2005 they were trading a number of different strategies but running into scalability issues trading individual equities and decided to look at taking their mean reverting strategies and porting them over to futures.

“We noticed in 2005 that it was difficult to get filled in equity markets,” Tsahas says.

“The reason we chose the mean reversion strategies is we were looking at forming a CTA and felt like mean reversion was a pretty good alternative to the 70% or so of [CTAs] who were trend followers,” Terpilowski says. “That would allow people to include our strategy in their portfolio and provide a return stream that was uncorrelated to other CTAs.”

At the time Tsahas went back to school to get a financial engineering degree and entered an IB-sponsored trading contest using their methodology. “I actually came in second place using this strategy and won $50,000.”

Both would build and code the strategy. “Once we hit something that was beneficial we would share it. It was a lot of test and verify,” Tsahas says. “That is the beauty of having a second person with a different set of skills. Once I saw something that I liked or Rob saw something that he liked, we would port it over and test it ourselves.”

“That is one of the reasons we have worked so well together,” Terpilowski adds. “Being from an engineering background we basically say if it is not something that we can model and backtest it is not something that we are willing to trade.”

By 2007 they began trading proprietary money on 19 futures markets in six sectors. Their strategy attempts to capture short-term pullbacks in medium-term (two to three-week) trends.  They did not attempt to optimize their strategy on each market but rather on the entire portfolio to avoid curve-fitting.

“The inputs we use for natural gas are the same inputs that we use for the S&P 500 or gold or wheat,” Terpilowski says. “We wanted to avoid curve-fitting so we decided we are going to optimize it at the portfolio level only and we included 40 markets.”

Their strategies performed extremely well in 2007-2009 and by 2010 they began trading customer money in CTA Zoi Capital.

Winning trades typically last 1.5 days, with losers lasting 2.5 days. Zoi’s Telio program has a four-point risk management strategy. They exit the market in five days if a trade does not begin to revert back to the mean.

“We want to minimize the amount of time in the market because whenever you are in the market you are assuming risk,” Terpilowski says. “We apply stop losses whenever we open a new position but they are dynamic; if volatility is higher we want to place the stops a little further away than if volatility is less to give it more room to breathe.”

However, Zoi will reduce the position size when applying wider stops. That way they maintain their risk parameters, 2.5% on every trade, but allow trades to work. They also will exit all positions if they reach a portfolio-wide drawdown of 5% in a day. They cap margin to equity at 25%, though it typically runs around 7 to 10%.

Zoi earned solid returns: 36.12% in 2010, 25.34% in 2011 and 32.66% in 2012, trading basically for friends and family and looked to raise more assets.

In 2013 Zoi got its first institutional client when Jack Schwager provided an allocation from the ADM Investor Services Diversified Strategies Fund he was co-portfolio manager of, which is ironic as Terpilowski first got interested in technical trading after reading a Jack Schwager book.

The Telio program has produced a compound annual return of 20.36% since April 2010 with a Sharpe ratio of 1.05. It is up 6.56% in 2014 through October.

Zoi is looking to expand its program to 40 markets, which should be no problem as the strategy has already been rigorously tested. As Tsahas says, “If we can’t see it in a model, validate it and make sure it is not curve fitted, we are not going to trade it.”

StockChartsFX is Now Open Source

I have received several inquiries asking to provide examples on how I created the JavaFX candlestick chart that I have used in the trading apps that I am currently working on, pictured below. enter image description here I’ve done a bit of work to separate the chart out from the rest of the application and create a chart new library which I’ve open sourced at checked in to GitHub at: https://github.com/rterp/StockChartsFX The project includes both the JavaFX code as well as the style sheet used to style the component. There isn’t currently a lot of functionality built in to library, and the code is a bit messy, but contributions are welcome. twitter: @RobTerpilowski

Written with StackEdit.

Make Money Online Automatically. Trading Commodities with JavaFX and the NetBeans Rich Client Platform

Ok, so maybe it isn’t quite as easy as it sounds, but we were able to leverage an automated trading application we had previously written and the modularity of the NetBeans Rich Client Platform to create a commodity trading application that will interface with, and allow us to place trades with a new commodity broker.

Even though the original application was for the purposes of automated trading, we were able to use many of the same NetBeans plugins we had developed in order to create the new application, as well as utilize JavaFX to put a nice polished UI on the app.

The login screen is below. The commodity images on the right side of the screen scroll down the UI and represent each commodity market that we trade.
enter image description here

After logging in to the application, those same commodities are in a dock at the top of the window. The images have an animated effect that will fade-in a green background when the mouse moves over the component. The first table in the UI shows orders that have been sent to the broker, but have not been fully executed, and the lower table displays commodity orders that have been completely executed.

enter image description here

After clicking on a commodity component at the top of the screen, the user is presented with a dialog to enter details about the order which will be placed. In the case of the screenshot below, an order is being entered to purchase 50 contracts of gold.

enter image description here

The last screenshot displays the state of the two main tables after orders to trade gold and natural gas have been fully executed, and while an order to purchase 50 Canadian Dollar futures contracts is still in process.

enter image description here

And finally, the 2 minute demo below highlights the application’s functionality as well as shows off the animated transitions and other eye candy that is possible using JavaFX. I will be speaking at JavaOne at a session entitled Flexibility Breeds Complexity: Living in a Modular World [CON6767], where I will discuss this and other JavaFX applications built on the NetBeans Rich Client Platform.

twitter: @RobTerpilowski

Written with StackEdit.

Animations with JavaFX: So Easy a Chimp Can Do It

Ok, well maybe its slightly more complicated than that, but not much. Things such as animations which were do-able with Swing, but were so painful, are baked into the JavaFX API and are relatively straightforward to implement.

In last month’s blog post, I demoed a JavaFX application which had 2 logos slowly scrolling across the app’s background. The code which was needed in order to acheive this effect was suprisingly minimal. The relevant code snippet from the application’s controller class is below.

public class AppController {

@FXML
protected ImageView logoImage;

@FXML
protected AnchorPane rootPane;

public void animateLogo() {
    TranslateTransition tt = 
    new TranslateTransition(Duration.seconds(30), logoImage);

    tt.setFromX( -(logoImage.getFitWidth()) );
    tt.setToX( rootPane.getPrefWidth() );
    tt.setCycleCount( Timeline.INDEFINITE );
    tt.play();
}
}

In the snippet above, we use a TranslationTransition which will move a node along a specified path over a specified time interval. The easiest way to do this is to give it the start point, end point, and the amount of time to run the animation for.

The TranslationTransition is created with a duration of 30 seconds, using the logoImage ImageView object that was injected by JavaFX into this controller class. Next, the starting point is set by specifying the fromX value on the transition. In this case, we want the animation to start the logo just off of the screen, so we specify a negative X value that is the width of the logo node. The toX value is set to the width of the entire UI so that the logo will scroll completely off the screen.

Finally, before playing the animation, the cycle count is set to INDEFINITE which means that as soon as the logo animation is complete, it will be automatically started again from the beginning, and keep doing so indefinitely.

That’s it, other transitions are equally as easy such as fading and scaling. Animations can also be chained together to run in sequence or set up to be run in parallel with other transitions.

Once again, from last month’s post, here’s a video showing animations in action. In particular, there are 2 logos which are animated on the Scene’s background that are scrolling in opposite directions across the screen.

 

Have fun!

twitter: @RobTerpilowski

Written with StackEdit.

Monitoring Real-Time Commodity Prices using JavaFX, NetBeans RCP, and Camel

Zoi Capital is a commodity investment firm which trades in the commodity futures markets on behalf of clients, with offices in New York and Seattle. We needed an application which could display the commodities we were currently holding as well as show any open profit/loss of our trades in real-time. In addition, we wanted to display the current performance of our trading strategy (named Telio) along with a comparison of the current performance of the S&P 500 stock index as well as the Dow Jones UBS commodity index.

Trades are placed from the Seattle office, but are monitored throughout the day from the New York office, so the application (which would be running in New York) needed a way to stay up to date with the current trades. The application also needed to be aesthetically pleasing as it was planned to put it on a large 50 inch LCD in the reception area of our New York office, where both staff and visitors could view the current trades and statistics in real time.

I had previously written an automated trading application on the NetBeans Rich Client Platform (RCP), where I had created a number of plug-ins, including a plug-in to connect to Interactive Brokers to retrieve real-time market data. Since I already had the plug-ins available in order to connect to a real-time data feed, it seemed a natural choice to also build the Quote Monitor application on the NetBeans RCP as well. Instead of using the existing Swing components however, I opted for JavaFX in order to give the application a polished look.

In order to get the trade information from the Seattle office to the Commodity Monitor application in the New York office, we made use of Camel to facilitate the communication between the 2 offices. The great thing about Camel is that it provides an abstraction layer for the actual communication mechanism between applications. Since the offices are not networked together we made use of the Camel email component in order to transfer the data from the Seattle office to the Commodity Monitor application. In the future we could move the communication mechanism to web services or JMS simply by changing a property file, with no code changes required as camel takes care of everything else under the hood.


System Architecture

enter image description here

Trades are placed in the Seattle office, and then emailed to a designated email box which the Commodity Monitor watches (via Camel). Trade information is then imported into the application, at which point it requests real-time quote information of the commodities from Interactive Brokers via their Java API. At this point the application can then update the profit/loss statistics in real-time.


Application Screen Shot

enter image description here

The grid in the top left portion of the screen displays the performance for our Telio trading strategy for today, for the month of August, and then the year-to-date return of the strategy. The table also shows the same statistics for the S&P 500 stock index and Dow Jones/UBS commodity index for comparison purposes.

Below the table is a candlestick chart displaying the performance of the S&P 500 Index futures for the current day. The chart made use of the charting API in JavaFX as well as CSS. The chart is updated in real-time throughout the day.

Finally, on the right half of the screen is a panel which displays the commodities that we are currently holding with current profit/loss on the trade. For example, we have a current profit of +0.18% since we bought natural gas.

To add additional eye candy to the application, I created a scrolling background with a slightly blurred Zoi Capital logo. The animation was extremely easy to set up in JavaFX, and I’ll post a short how-to blog on animations in the not-too-distant future.


Demo Video

Below is a 3 minute video demo showing the Commodity Monitor application with the animated scrolling background. About 40 seconds into the video an email is sent to the Camel email box, at which point the Commodity Monitor picks up the email and displays the commodities that were sent, and their corresponding profit/loss in real time. Another email is sent at the 2:10 mark that clears most of the commodities from the application.

 

twitter: @RobTerpilowski

Adding a Custom JavaFX Component to Scene Builder 2.0 (Part 2)

In a previous post I demonstrated how to add a custom component to Scene Builder 2.0 which was basically a short cut for copying & pasting FXML from the custom component into the FXML of the UI control which contained the component.

In this post I will demonstrate how to add a component as what I will call a ‘customized’ FXML component. Where the component will be encapsulated in its own custom FXML tag.

So to start off with, let’s say we have a label which contains a commodity name, image, and change in price. We’d like to have a collection of these commodity image labels on the main UI. Scene Builder is used to design the custom label (below):

enter image description here

Once the component is laid out, be sure that the “Use fxroot:construct” option is selected under the “Document” -> “Controller” accordion item on the left pane of Scene Builder.

enter image description here

In the project, for the custom component you should have the CommodityImageLabel.fxml file (the component just created in Scene Builder), and then create a CommodityImageLabel.java class to act as the component’s controller. (More on this in just a second)

enter image description here

First, a look below at the FXML code that was generated by Scene Builder

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.effect.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>

<fx:root styleClass="glass-pane" type="AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="110.0" prefWidth="675.0" styleClass="glass-pane" stylesheets="@zoi.css">
          <children>
              <Label fx:id="percentChangeLabel" layoutX="480.0" layoutY="14.0" text="- 0.23%" AnchorPane.rightAnchor="14.0">
                  <styleClass>
                      <String fx:value="label-text" />
                      <String fx:value="header" />
                  </styleClass>
              </Label>
              <Label fx:id="commodityLabel" layoutX="90.0" layoutY="28.0" text="Wheat">
                  <font>
                      <Font name="System Bold" size="50.0" />
                  </font>
                  <padding>
                      <Insets left="25.0" right="25.0" />
                  </padding>
                  <styleClass>
                      <String fx:value="label-text" />
                      <String fx:value="header" />
                  </styleClass>
              </Label>
              <Label fx:id="directionLabel" layoutX="120.0" layoutY="3.0" styleClass="label-direction-text" text="Long">
                  <opaqueInsets>
                      <Insets bottom="20.0" />
                  </opaqueInsets>
              </Label>
                <ImageView fx:id="commodityImageView" fitHeight="75.0" fitWidth="75.0" layoutX="14.0" layoutY="18.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="15.0" AnchorPane.leftAnchor="15.0" AnchorPane.topAnchor="15.0">
               <image>
                  <Image url="@../images/ZW.png" />
               </image></ImageView>
          </children>
      </AnchorPane>
   </children>
</fx:root>

Ok, on to the contorller class for the component.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.zoicapital.commoditylabelwidget;

import java.io.IOException;
import java.text.DecimalFormat;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;

/**
 *
 * @author robbob
 */
public class CommodityImageLabel extends AnchorPane {

    @FXML
    protected Label directionLabel;

    @FXML
    protected Label commodityLabel;

    @FXML
    protected Label percentChangeLabel;

    @FXML
    private ImageView commodityImageView;

    protected DecimalFormat decimalFormat = new DecimalFormat("#0.00");
    protected String currentStyle = "";

    public CommodityImageLabel() {
        FXMLLoader fxmlLoader = new FXMLLoader(
                getClass().getResource("/fxml/CommodityImageLabel.fxml"));

        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }

    }

    public void setPercentChange(double percentChange) {

        StringBuilder builder = new StringBuilder();
        String percentChangeString = decimalFormat.format(Math.abs(percentChange) * 100.0);
        String style;
        if ("0.00".equals(percentChangeString)) {
            style = Style.LABEL_PLAIN;
        } else {
            if (percentChange < 0) {
                builder.append("-");
                style = Style.LABEL_RED;
            } else {
                builder.append("+");
                style = Style.LABEL_GREEN;
            }
        }

        builder.append(percentChangeString);
        builder.append("%");

        percentChangeLabel.setText(builder.toString());

        if (!style.equals(currentStyle)) {
            getStyleClass().remove(currentStyle);
            currentStyle = style;
            getStyleClass().add(currentStyle);
        }

    }

}

 

First off, notice that it extends AnchorPane, and also that the constructor loads the component’s FXML and then tells the loader that ‘this’ will be acting as the component’s controller.
That’s it for creating the custom component. Build it, jar it up, and its ready to be imported into Scene Builder and used in an application.


Using the Custom Component in Scene Builder

The new application will need to include the previously created .jar file as a dependency, in this case the “CommodityLabelWidget.jar” file.

enter image description here

The DemoScreen.fxml component for this application currently looks as follows.

enter image description here

In order to get the CommodityImageLabel into Scene Builder’s pallete, select the small “gear” icon in the Library header of Scene Builder, and select the “Import JAR/FXML File…” item.
enter image description here

Next, browse to the .jar file that contains your custom component.
enter image description here

Once the .jar is selected, the import dialog should display a list of all the custom components in the .jar file. In this case the CommodityImageLabel is the only component available.

enter image description here

At this point the custom component is added to the Scene Builder pallette, and can be dragged on to the main UI.

enter image description here

Screen shot showing 2 CommodityImageLabels placed on the main application UI.

enter image description here

Now, in order to be able to access these custom component’s from your main UI’s controller class, enter an fx:id for the components in Scene Builder’s “Code” section for each component. Scene Builder may complain that it isn’t able to find an injectable field with the name you just entered, but don’t worry, you’ll be adding it to the UI’s controller shortly.
Save the .FXML file in Scene Builder and then head back over to the IDE.

enter image description here

Below is the FXML file generated by Scene Builder. Take note of the CommodityImageLabel “custom” FXML tags, also note that the controller for this class is “DemoScreenController” which is shown next.

<?xml version="1.0" encoding="UTF-8"?>

<?import com.zoicapital.commoditylabelwidget.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>


<AnchorPane id="AnchorPane" prefHeight="632.0" prefWidth="889.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.zoicapital.demolabelproject.DemoScreenController">
   <children>
      <Label layoutX="72.0" layoutY="48.0" text="My Commodities">
         <font>
            <Font name="System Bold" size="36.0" />
         </font>
      </Label>
      <Separator layoutX="72.0" layoutY="109.0" prefHeight="4.0" prefWidth="289.0" />
      <CommodityImageLabel fx:id="commodityLabel1" layoutX="72.0" layoutY="144.0" />
      <CommodityImageLabel fx:id="commodityLabel2" layoutX="72.0" layoutY="268.0" />
   </children>
</AnchorPane>

In order to access the custom label components, be sure to name the fields the same as the fx:id controller name that you specified in Scene Builder, and to annotate the fields with the @FXML annotation.
Once this is complete you will have access to the CommodityImageLabel’s underlying controller classes, and can manipulate the custom component.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.zoicapital.demolabelproject;

import com.zoicapital.commoditylabelwidget.CommodityImageLabel;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;

/**
 * FXML Controller class
 *
 * @author robbob
 */
public class DemoScreenController implements Initializable {


    @FXML
    protected CommodityImageLabel commodityLabel1;

    @FXML
    protected CommodityImageLabel commodityLabel2;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        commodityLabel1.setPercentChange(50.0);
        commodityLabel2.setPercentChange(-4.55);
    }    

}

The unfortunate wrinkle to this is that Scene Builder does not automatically pick up changes to the custom components. Meaning if you were to make a modification to the CommodityImageLabel component, you would need to manually re-import the .jar file in to Scene Builder in order to see the changes. This should hopefully be something that is addressed in a future version of Scene Builder.

twitter: @RobTerpilowski

Writing to a NoSQL DB using Camel

We use a somewhat out of the ordinary NoSQL database called “Universe“, produced by a company called Rocket as our primary data store. We have written our own ORM framework to write data to the DB from Java beans that we have dubbed “siesta” as it is a lightweight hibernate-like framework.

Camel is a great framework for implementing Enterprise Integration Patterns (EIP), and we have started making heavy use of the various Camel components in order to pass data in varying formats between internal and 3rd party systems.
While there are large number of components available out of the box available here, there are no components available for writing data to UniVerse

Fortunately it is extremely easy to implement custom Camel components, and we were able to create a component to write to UniVerse with a few classes and one configuration file.

For the Camel endpoint URI, we would like to use the following format:

siesta://com.lynden.siesta.component.FreightBean?uvSessionName=XDOCK_SHARED

where:

siesta:// denotes the component scheme,

com.lynden.siesta.component.FreightBean denotes the annotated POJO that the Siesta framework will use to persist the data to UniVerse.

uvSessionName=XDOCK_SHARED tells the component which database session pool to use when connecting to the DB.


The Endpoint Class

package com.lynden.siesta.component;

import com.lynden.siesta.BaseBean;
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.impl.DefaultEndpoint;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;

/**
 * Represents a Siesta endpoint.
 */
@UriEndpoint(scheme = "siesta" )
public class SiestaEndpoint extends DefaultEndpoint {

    @UriParam
    protected String uvSessionName = "";

    Class<? extends BaseBean> siestaBean;

    public SiestaEndpoint() {
    }

    public SiestaEndpoint(String uri, SiestaComponent component) {
        super(uri, component);
    }

    public SiestaEndpoint(String endpointUri) {
        super(endpointUri);
    }

    @Override
    public Producer createProducer() throws Exception {
        return new SiestaProducer(this);
    }

    @Override
    public Consumer createConsumer(Processor processor) throws Exception {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    public void setSiestaBeanClass( Class<? extends BaseBean> siestaBean) {
        this.siestaBean = siestaBean;
    }

    public Class<? extends BaseBean> getSiestaBeanClass() {
        return siestaBean;
    }

    public String getUvSessionName() {
        return uvSessionName;
    }

    public void setUvSessionName(String uvSessionName) {
        this.uvSessionName = uvSessionName;
    }
}

The Component Class
The next step is to create a class to represent the component itself. The easiest way to do this is to extend the org.apache.camel.impl.DefaultComponent class and override the createEndpoint() method.

import com.lynden.siesta.BaseBean;
import java.util.Map;
import org.apache.camel.Endpoint;
import org.apache.camel.impl.DefaultComponent;

public class SiestaComponent extends DefaultComponent {

    @Override
    protected Endpoint createEndpoint(String uri, String path,    Map<String, Object> options) throws Exception {

    SiestaEndpoint endpoint = new SiestaEndpoint(uri, this);
    setProperties(endpoint, options);

    Class<? extends BaseBean> type = getCamelContext().getClassResolver().resolveClass(path, BaseBean.class, SiestaComponent.class.getClassLoader());

   if (type != null) {
       endpoint.setSiestaBeanClass(type);
    }
    return endpoint;
    }
}

The createEndpoint method takes as arguments, the uri of the component, the path, which includes the “com.lynden.siesta.component.FreightBean” portion of the URI, and finally the options, which include everything after the “?” portion of the URI.

From this method we use reflection to load the BaseBean class specified in the URI, and pass it into the SiestaEndpoint class that was created in the previous step.


The Producer Class

import com.lynden.siesta.BaseBean;
import com.lynden.siesta.EntityManager;
import com.lynden.siesta.IEntityManager;
import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Siesta producer.
 */
public class SiestaProducer extends DefaultProducer {
    private static final Logger LOG = LoggerFactory.getLogger(SiestaProducer.class);
    private SiestaEndpoint endpoint;
    private IEntityManager entityManager;
    private String uvSessionName;

    public SiestaProducer(SiestaEndpoint endpoint) {
        super(endpoint);
        this.endpoint = endpoint;
        uvSessionName = endpoint.getUvSessionName();
        entityManager =  EntityManager.getInstance(uvSessionName);

    }

    @Override
    public void process(Exchange exchange) throws Exception {
        BaseBean siestaBean = exchange.getIn().getBody( BaseBean.class );
        entityManager.createOrUpdate(siestaBean);
        LOG.debug( "Saving bean " + siestaBean.getClass() + " with ID: "+ siestaBean.getId() );
    }

}

The Config File

The final step is to create a configuration file in the .jar’s META-INF directory which will allow the Camel Context to find and load the custom component. The convention is to put a file named component-name (“siesta” in our case) in the META-INF/services/org/apache/camel/component/
directory of the component’s .jar file

The META-INF/services/org/apache/camel/component/siesta file contains 1 line to tell the Camel Context which class to load:

class=com.lynden.siesta.component.SiestaComponent

That’s it, With 3 relatively simple classes and a small config file we were able to easily implement our own Camel producer using our NoSQL database as an endpoint.

twitter: @RobTerp

Written with StackEdit.