In part 1 of this series, we briefly discussed why it makes a ton of sense to use BPM to manage processes in an IoT world. The pieces are all there, but how, exactly, can we make this work? The answer to that question is, of course, “it depends”. What kind of device are you connecting? What sort of messages does it send or receive? How much, if any, control do you have over these factors? If you are building something from scratch with an Arduino or Raspberry Pi then it’s likely you’ll have a lot of control over what the device sends, how often, and what protocol it uses. If you are deploying an off the shelf device your options will likely be much more limited or simply nonexistent. A good place to start is to look at what kind of data you are working with and what protocol is used. In my experimentation, I have been working with three protocols that are widely used in the IoT world: HTTP(S), XMPP and MQTT.
HTTP is a beautiful thing. It’s easy to implement, easy to test, flexible, ubiquitous and mature. You can use it to send any kind of data you want. It has a nice set of verbs that map to the kinds of operations we might need. HTTP is supported everywhere, with robust client and server implementations available in any language on any platform. Done right, HTTP is extremely scalable. Looking at the negatives, HTTP is pretty heavyweight when compared with some other IoT options and doesn’t offer multiple levels of quality of service. This makes it reliable but that reliability is not always a requirement. It’s also based on a request / response model which isn’t always a good fit for IoT applications. If you want a long running Activiti process task to send messages back to your device it will need to be both a HTTP client and server, which is a lot to ask of a very low power device on an unreliable network.
XMPP was originally developed for instant messaging and presence applications as the protocol used by Jabber. In subsequent releases it evolved into an IETF standard. Today, XMPP is well defined but not stagnant thanks to an active community. There are multiple client and server implementations across many platforms and languages. The message format is flexible and extensible via XML. XMPP supports a publish / subscribe model (via an extension), presence and a fairly rich set of features. It is generally lighter than HTTP, but is still weighty on very low powered devices due mostly to the fact that it is a text based protocol. XMPP, like HTTP does not support multiple QoS levels. This makes it suitable for IoT devices that have a fair amount of power and need reliable message delivery.
MQTT is the lightest of the protocols that I have been researching. It is an OASIS standard supporting a publish / subscribe model, and has a number of client and broker implementations available. MQTT isn’t quite as widely used or supported as either HTTP or XMPP, but it is mature and stable. MQTT is a binary protocol designed for constrained devices operating on unreliable networks, which means it is very well suited for IoT applications like remote sensor networks. Support is included for multiple levels of QoS ranging from “fire and forget” to guaranteed delivery. It isn’t great for large amounts of data, and is not as flexible or extensible as either HTTP or XMPP.
There are a huge number of protocols for IoT devices both open (to varying degrees) and proprietary. For my purposes I’m not even going to look at the proprietary protocols because proprietary protocols are dumb. The real value of IoT can only be realized through openness and integration, not through secrecy and walled gardens. Some other open protocols that may be worth a look depending on your needs include AMQP and STOMP. These may get their own articles in the future, but for now I’m going to focus on the three described above.
Connecting to Activiti
Assuming we now have a device and a use case in mind, we know what its data and delivery reliability requirements look like and we know what protocol we are going to use, how can we get this thing talking to Activiti to either start a new process or interact with one that is already in-flight? Again, that depends.
At its simplest, your IoT device could simply call one of several REST APIs in Activiti to start a workflow. You could call one of the workflow initialization APIs directly to start a workflow using a message or a process definition. This sort of simple point to point integration works, but it is hard to scale without excess complexity, hard to maintain and brittle. A better option, if you are going the HTTP route in your IoT project, might be to push the message onto some kind of bus. Either way, if your device speaks HTTP, getting a basic connection to Activiti that you can use to start a workflow or interact with tasks is straightforward. What about other options?
Using another protocol with Activiti will require some sort of bridge or gateway since Activiti doesn’t speak MQTT or XMPP natively. Each of these protocols uses a different architecture and will require a different approach. Even so, we can map out some high level requirements by asking a few questions about what we are trying to do with our IoT project:
- Do we just need to start a process, or do we need to be able to interact with tasks as well?
- Do we need Activiti to be able to push messages back to our device?
- Is there more than one type of device that may interact with a given workflow?
- Is there more than one type of workflow that may be started from a given class of device?
- What triggers the interaction with the process? Is it a single condition? Is it a pattern?
- How reliable does this need to be? Is some loss or delay of messages tolerable?
In part 3 of this series, we’ll outline a simple use case, introduce our example IoT device and code, answer the questions above for our application and get a basic gateway working.