IBM Developer Day | Bengaluru | March 14th Register now
Tutorial
By Larissa Auberger, Matthias Kloppmann | Published January 1, 2017
BlockchainCloudHybrid Cloud
Note: IBM Blockchain Platform now utilizes Hyperledger Fabric for end-to-end development. Users may use Hyperledger Composer at their choice, but IBM will not provide support for it.
Part 1 of our series showed how the combination of business process management (BPM) and blockchain technology greatly simplifies distributed, collaborative processes between multiple enterprises, via a shared ledger used by all the participants. Rather than individually storing relevant data in individual information systems and synchronizing between parties bilaterally, the single shared ledger instance is updated, and its information becomes visible to all participants (based on their authorization).
Now in this Part 2, we go beyond mere data sharing through blockchain, and explore blockchain’s “active behavior”: its capability to notify participants about successful completion of a transaction, by sending events.
Figure 1 shows a typical B2B interaction, represented as a BPMN (Business Process Model and Notation) collaboration diagram, where three participants communicate to achieve an overall business goal. Each participant is assumed to autonomously run a private process of its own (those processes are not shown). Private processes interact through bilateral messages, ensuring exchange of information and synchronization between participants.
The resulting collaboration is sometimes called a choreography, because the individual participants act autonomously, according to their own internal rules. Still, the exchange of messages is happening in a pre-defined way, according to a contract between participants. The minimal process adhering to this contract is sometimes called the public process of a participant, to indicate that it can be observed by other participants. Its actual implementation is through a private process, which may include additional steps internal to the participant.
The drawback of this model is the need for multiple communication channels, one per bilateral communication. Also, messages are transient, and not visible to other participants apart from sender and receiver.
Replacing the messaging infrastructure with a blockchain-based distributed ledger addresses those issues. A participant can trigger a transaction in the business network implemented through the ledger, which in turn will send notifications to any other interested participant. Thus, the blockchain framework effectively becomes the B2B messaging layer. Note that this basically is a different view of the same technology: We can either focus on the capability of a blockchain to persist data in a shared, distributed way with non-repudiation and audit capability, or we can focus on its ability to trigger transactions and push transaction results to participants as events, thus becoming a messaging layer.
Figure 2 shows a blockchain in the middle, surrounded by the participants and including their private processes. Note that the messaging is replaced by the ledger. The actual rules that determine which transaction can be called, and which events are triggered, become part of the business network definition and the definition of the network’s smart contracts.
Now, in order to implement such B2B interactions using blockchain as the B2B messaging layer, your processes need to be able to react to blockchain events. The remainder of this tutorial shows you how to use Hyperledger Composer and IBM Business Process Manager (IBM BPM) to make your processes react to blockchain events.
In Part 1, we used Hyperledger Composer REST Server to query data on the blockchain and invoke transactions from an IBM BPM process.
A long-awaited enhancement to Hyperledger Composer REST Server was introduced recently: events support. This means that the blockchain event mechanism is now exposed via Hyperledger Composer REST Server. Hyperledger Composer REST Server can publish events that occur on a business network, so that connected applications can subscribe to them.
So, Hyperledger Composer REST Server can now publish events. And IBM BPM can handle message events to start or continue processes based on these events. So far, so good. However, part of the equation is missing. We need a way to listen for events published by Hyperledger Composer REST Server and transform them into message events that IBM BPM can understand.
Our solution for this missing link is what we call an Event Bridge. The Event Bridge listens for events emitted by Hyperledger Composer REST Server and calls the appropriate undercover agent in IBM BPM to start or continue a process instance that reacts to the event.
We based our example on the vehicle lifecycle business network that is provided as a sample network with Hyperledger Composer. In this network, a private person places an order for a vehicle on the blockchain. The initiated transaction creates an order for the manufacturer and broadcasts an event. The manufacturer needs to react to this event by initiating the actions required to schedule the vehicle for manufacturing and to update the status of the order on the blockchain.
This tutorial shows you the steps to react to blockchain events in a IBM BPM process:
So, this tutorial is for you, whether you are familiar with Hyperledger Composer and the blockchain event mechanism and want to learn how to handle those events in an IBM BPM process – or you are an expert in IBM BPM and want to learn how Hyperledger Composer events work and how they can be consumed in IBM BPM.
To follow along with this tutorial, you need the following prerequisites:
To explore the REST API for the vehicle lifecycle network, navigate to: http://your-hyperledger-composer-rest-server:3000/explorer
In the REST API Explorer, you can see the participants in the business network, including Manufacturer, PrivateOwner, Regulator, and ScrapMerchant. In addition, there are two Assets defined: Order and Vehicle. You can perform several transactions, including SetupDemo, PlaceOrder, UpdateOrderStatus, and PrivateVehicleTransfer.
Manufacturer, PrivateOwner, Regulator
ScrapMerchant
Order
Vehicle
SetupDemo, PlaceOrder, UpdateOrderStatus, and PrivateVehicleTransfer
To initially create participants and assets for the vehicle business network, perform the POST /SetupDemo transaction.
Now, use the REST API Explorer to simulate a manufacturer’s ordering application that allows a private owner to submit an order to the manufacturer. Navigate to the POST /PlaceOrder transaction and submit an order using the following data:
{ "$class": "org.acme.vehicle.lifecycle.manufacturer.PlaceOrder", "orderId": "9999", "vehicleDetails": { "$class": "org.vda.VehicleDetails", "make": "Arium", "modelType": "Rose", "colour": "red" }, "manufacturer": "org.acme.vehicle.lifecycle.manufacturer.Manufacturer#Arium", "orderer": "org.acme.vehicle.lifecycle.PrivateOwner#anthony", "timestamp": "2017‑11‑03T15:26:05.528Z" }
This transaction creates a new order in the asset registry and emits a PlaceOrderEvent event.
PlaceOrderEvent
Now explore how this event is implemented in the vehicle lifecycle network. The event is defined in the manufacturer.cto model file and consists of two properties – orderId and vehicleDetails:
manufacturer.cto
orderId
vehicleDetails
event PlaceOrderEvent { o String orderId o VehicleDetails vehicleDetails }
The transaction that creates the PlaceOrderEvent event is defined in manufacturer.js. In order for the event to be published, this transaction implements three functions and sets the required properties of the event:
manufacturer.js
var factory = getFactory() // allows events to be created as part of the transaction var placeOrderEvent = factory.newEvent(‘org.acme.vehicle.lifecycle.manufacturer’,‘PlaceOrderEvent’) // creates the PlaceOrderEvent in the specified namespace. placeOrderEvent.orderId = order.orderId; // sets event properties, as defined in manufacturer.cto placeOrderEvent.vehicleDetails = order.vehicleDetails; emit(placeOrderEvent) // emits the event
In our scenario, we want the Hyperledger Composer REST Server to publish events for consumption by the Event Bridge application. This step requires additional configuration on the REST Server.
Configure Hyperledger Composer REST Server to publish events emitted from a business network, so that the Event Bridge that you implement in Step 3 can subscribe to these events. At the time of writing, the REST Server supports publishing events over WebSockets. Therefore, you need to enable WebSockets in Hyperledger Composer REST Server:
export COMPOSER_WEBSOCKETS=true
In this step, you implement the Event Bridge. For now, the Event Bridge only subscribes to events that are published by the Hyperledger Composer REST Server and write the event message (payload) to the console. In Step 5, you extend the Event Bridge to invoke a process instance in IBM BPM.
The Event Bridge implementation is done in Node.js. The initial implementation of the Event Bridge establishes a connection to the Hyperledger Composer REST Server using the WebSocket protocol. If a PlaceOrderEvent event occurs, the script writes the event message to the console:
var WebSocketClient = require('websocket').client; var client = new WebSocketClient(); client.connect('ws://your‑hyperledger‑composer‑rest‑server:3000/'); client.on('connectFailed', function(error) { console.log('Connect Error: ' + error.toString()); }); client.on('connect', function(connection) { console.log('Connection established'); connection.on('error', function(error) { console.log("Connection Error: " + error.toString()); }); connection.on('close', function() { console.log('Connection Closed'); }); connection.on('message', function(message) { var jsonString = JSON.parse(message.utf8Data); if (jsonString.$class == "org.acme.vehicle.lifecycle.manufacturer.PlaceOrderEvent") { console.log("PlaceOrderEvent received: '" + message.utf8Data + "'"); } }); });
To run the script, complete the following steps:
npm install websocket
node EventBridge.js
Connection established
PlaceOrderEvent received: '{"$class":"org.acme.vehicle.lifecycle.manufacturer.PlaceOrderEvent","orderId":"99998","vehicleDetails": {"$class":"org.vda.VehicleDetails","make":"Arium","modelType":"Rose","colour":"red"},"eventId":"5fdd65ab9a02fcc7c0bfc1caf80055320247e6ee4e83b5b65aef1f18dfbac1d2#0","timestamp":"2017‑11‑03T15:26:05.528Z"}'
In this step, we’ll show you how to implement the undercover agent in IBM BPM. An undercover agent provides the ability to invoke a process using REST:
NameValuePair
String
Output(NameValuePair)
name(String)
value(String)
Your undercover agent is now ready to receive event messages.
Tip: Before moving to the next step, test your undercover agent using the REST API Tester provided with IBM BPM.
a. Access the REST API Tester. b. Expand Business Process Manager REST API and then Process API. c. Select Send Message. d. Select the POST method. e. For the message, use the following format. Replace processApp and ucaname, if necessary, to match the names you used.
processApp
ucaname
<eventmsg> <event processApp="OP" ucaname="OrderProcessingUCA"> </event> <parameters> <parameter> <key>Input</key> <value type="NameValuePair"> <name>message</name> <value>Hello from REST API Tester</value> </value> </parameter> </parameters> </eventmsg>
Execute Call
Congratulations, your undercover agent is working!
So far, the Event Bridge that we developed in Step 3 can detect an event emitted from the Hyperledger Composer REST Server. In our scenario, when the PlaceOrderEvent event occurs, we want to start an IBM BPM process instance for the manufacturer to process the order. We therefore need to extend the connection.on('message') function in EventBridge.js to perform the necessary REST call. When constructing the URL, add the encoded event message to the URL as the message value.
connection.on('message')
The request includes:
Method: 'POST'
Note: To demonstrate the essentials of the Event Bridge (subscribe to blockchain events and initiate a BPM process), the sample is simple and easy to understand. If you use the sample in your environment, you may want to replace the rejectUnauthorized: false option and add the content of the CA certificate file of your BPM server, so that server’s identity can be verified. See https://github.com/request/request for more details.
rejectUnauthorized: false
connection.on('message', function(message) { var jsonString = JSON.parse(message.utf8Data); if (jsonString.$class == "org.acme.vehicle.lifecycle.manufacturer.PlaceOrderEvent") { console.log("PlaceOrderEvent received: '" + message.utf8Data + "'"); console.log("Starting IBM BPM process to process order... "); // replace username:password and hostname var base64encoded = Buffer.from("username:password").toString('base64'); var urlcomplete = 'https://bpmserver:9443/rest/bpm/wle/v1/process?action=sendMessage&message=<eventmsg><event processApp="OP" ucaname="OrderProcessingUCA"></event><parameters><parameter><key>Input</key><value type="NameValuePair"><name>message</name><value>' + encodeURIComponent(message.utf8Data) + '</value></value></parameter></parameters></eventmsg>'; // if class of event : "org.acme.vehicle.lifecycle.manufacturer.PlaceOrderEvent" call the BPM UCA to process the order. request({ url: urlcomplete, method: 'POST', headers: {'Content‑Type': 'application/json', 'Authorization' : 'Basic ' + base64encoded}, rejectUnauthorized: false }, function (err, resp, body) { if (err){ console.log("resp = " + resp); } else{ console.log("StatusCode: "+resp.statusCode); if (resp.statusCode == 200) { console.log(body); } } }); }; });
The server request requires three more npm components that need to be added to the EventBridge.js:
var request = require('request'); var response = require('response'); var https = require('https');
npm install request
npm install response
npm install https
PlaceOrderEvent received: '{"$class":"org.acme.vehicle.lifecycle.manufacturer.PlaceOrderEvent","orderId":"99995","vehicleDetails ":{"$class":"org.vda.VehicleDetails","make":"Arium","modelType":"Rose","colour":"red"},"eventId":"a7ca458a434f45f3f73a95db3248a2258eea216e983cf4985860ba6713c92cba#0","timestamp":"2017‑ 11‑03T15:26:05.528Z"}'
Starting IBM BPM process to process order... StatusCode: 200 {"status":"200","data":{"messageSent":true}}
message received: {"$class":"org.acme.vehicle.lifecycle.manufacturer.PlaceOrderEvent","orderId":"99995","vehicleDetails" :{"$class":"org.vda.VehicleDetails","make":"Arium","modelType":"Rose","colour":"red"},"eventId":"a7ca458a434f45f3f73a95db3248a2258eea216e983cf4985860ba6713c92cba#0","timestamp":"2017‑ 11‑03T15:26:05.528Z"}
Your Event Bridge now receives events and starts an IBM BPM process instance in response to the event!
You can now extend the IBM BPM process. Parse the event message, pass the data to the human service, and arrange the order details in the user interface so that the business person can conveniently review the order. Finally, update the order status on the blockchain by performing the corresponding transaction.
Your friend and helper for this step is the service discovery in Process Designer. It discovers the model and operations available in the business network and generates an external service that can be used in a process.
You can follow the same procedure and react to blockchain events using intermediate message events in IBM BPM. Intermediate message events allow a message event to be received during the process execution. For this type of events, you can also use an undercover agent to trigger a message event. Instead of the “Start event,” use the component “Intermediate message event” in the process diagram. In addition, for the event message to be passed to the correct process instance, you need to assign a correlation value to an output value of the undercover agent.
Follow these steps to define intermediate message events.
In this example, the parameter name of the undercover agent output is assigned to the variable orderId:
In EventBridge.js, you define the URL that is used in the request to trigger the undercover agent like the following example:
var urlcomplete = 'https://bpmserver:9443/rest/bpm/wle/v1/process?action=sendMessage&message=<eventmsg><event processApp="OP" ucaname="OrderProcessingUCA"></event><parameters><parameter><key>Input</key><value type="NameValuePair"><name>' + jsonString.orderId + '</name><value>' + encodeURIComponent(message.utf8Data) + '</value></value></parameter></parameters></eventmsg>';
In this sample, an event message with the parameter <name>9876</name> will be passed to the process instance where the variable tw.local.oderId is 9876.
<name>9876</name>
tw.local.oderId
Blockchain events can be easily exposed in Hyperledger Composer REST Server, so that connected applications can subscribe to the events using the WebSockets protocol. In this tutorial, you learned how to implement the Event Bridge that listens to events emitted by the Hyperledger Composer REST Server and calls the appropriate undercover agent in IBM BPM. You also learned how to configure the undercover agent that is triggered by the Event Bridge and — in response to the event — starts a process instance to kick off the necessary actions.
You can clone this GitHub repository to use the Event Bridge sample: https://github.com/ibmbpm/bpm-blockchain-events/tree/master.
We’re eager to learn about your experiences and any further requirements you might have for integrating IBM BPM and blockchain. For more ways to connect, see the links in our bios (Larissa and Matthias).
We’d like to thank Ute Tanneberger and Thomas Duerr for their careful review of this tutorial, and their valuable comments and corrections. Further thanks to Thomas and also Benjamin Wende for the thorough code review. Many thanks to Helen O’Shea and Joshua Horton for their helpful comments and editorial suggestions.
Think is IBM's flagship technology conference. This year, one of our leading containers dev advocates will be live streaming on…
Artificial IntelligenceBlockchain+
When you are creating APIs that will interact with blockchain, you need to watch out for a flaw that could…
API ManagementBlockchain+
Get the Code »
BlockchainCloud+
Back to top