≡ Menu

Smart Grids, part vierte: a simple data store

One of the challenges our smart grids application will have is data storage. It needs to be able to preserve data between submission and retrieval, and presumably many applications will need access to our data.

We have a lot of options here. The most obvious is a relational database, because that’s the standard choice for data in today’s computing world…

Plus ça change, plus c’est la même chose (or, in English, “the more that things change, the more they stay the same.”)

In other words, I’m going to strike out on my own, and suggest that we not use a relational database here. There are lots of reasons why, but investigating new technologies and methods is part of my goal for this application, so most of the reasoning boils down to “This is what I want to use.”

Therefore: Infinispan, an open source data grid from JBoss, integrated with JBoss AS7 and providing write-through and write-behind as well as a flexible query mechanism and other features one expects a decent data grid to have.

Infinispan provides a simple Map<K, V> implementation… where “simple” here means that it looks just like every other Map implementation for Java, but provides a lot of features behind the scenes.

The actual interface we use for interaction with Infinispan is the Cache. This adds some features to Map such as asynchronous calls, expiration times for stored values, and batch operations.

The next thing we need to think about is how to acquire a reference to the Infinispan data grid. For this, we turn to Java EE 6 and CDI.

For better or for worse, that means we get to dive head-first into our web application.

Therefore: it’s time to get an application server and configure it. I’ll be using JBoss AS7, as it’s one of the two best application servers for Java EE (along with Glassfish) and it has the advantage of already having Infinispan integrated.

Our first step is to download JBoss. I’d get the most recent version, of course. Unzip it into a directory of your choice – for me, it’s ~/tools/jboss-as-7.1.1.Final, hereafter referred to as $JBOSS_HOME.

We’ll want to configure an admin user before proceeding very far. If you try to use the administration console without an administrator configured, JBoss will tell you exactly what you need to do, but we’ll skip the error step.

The process for configuring an administrator account is very simple. The commands here are based on Fedora, and should work on any UNIX variant; if you’re imprisoned on Windows, the commands will differ slightly.

  • cd $JBOSS_HOME/bin
  • ./add-user/sh
  • Select “Management User”
  • Select “ManagementRealm” (the default realm)
  • Enter a username (“jottinge” is my username for this server installation)
  • Enter a password (twice)
  • Confirm creation of the user account

Well! We now have administrative access to this JBoss installation. Start it (with ./standalone.sh) and open up the administration console (which will be accessible at http://localhost:8080/console, logging in with the user credentials we just created.

JBoss' initial console

This will open up JBoss to the Runtime configuration details – which we don’t need to worry about at this point. What we want to do is open up the Profile.

JBoss' profile screen

The last element in the tree on the left of the window is “Infinispan.” We’re going to use this to configure a local cache with a valid JNDI name.

Just as a note: this is not as nice as a distributed Infinispan instance would be. That’s okay. We’re just playing with things at the moment, and we’ll get around to adding high availability (and long-term persistence) to the system in a later article.

So to create our Infinispan cache, we first need to create a cache container. In the “Cache Containers” panel, add a cache – let’s call it “sensorData” – and then edit the attributes to give it a JNDI name of “sensorData” as well. This means that a JNDI name of “java:/jboss/infinispan/sensorData” resolves to this cache container.

Note that after we’ve added the cache container and named it like this, we need to restart JBoss.

The next thing to do is actually write something that uses it.

The way to do this in Java EE is very simple, and a touch anticlimactic. All we have to do is declare an injected reference (via @Resource) to the cache container we just created, then we get a named cache from it. In a servlet, the code looks like this:

public class DataCollector extends HttpServlet {
    @Resource(lookup = "java:/jboss/infinispan/sensorData")
    private CacheContainer container;
    private Cache cache;

    @Override
    protected void doPost(HttpServletRequest request, 
                          HttpServletResponse response)
            throws ServletException, IOException {
        cache=container.getCache("dataPoints");
    ...

Once we have a reference to the Cache, we can use it just like any other Map: cache.put("myKey", myDataPoint), for example, would be an example of storing myDataPoint into Infinispan, with no expiration.

Getting data out is just as easy: cache.get("myKey") would return the reference pointed to by myDataPoint from the previous paragraph.

We also have queries available to us – but that’s an enhancement at which we’ll want to look after we’ve gotten to the point where we’re actually looking at data. We’re getting very close to it – we’re just not there yet.