Managing IoT Blockchain Service routes
A route is a IoT Blockchain Service component that is used to connect your IoT device or application to a blockchain and map all or part of the incoming payload data to a smart contract.
Overview
An IoT Blockchain Service route connects a source end-point to a destination end-point with a mapping between their payload schema formats.
Note: In the following diagrams the label IoT Blockchain Service identifies the IoT Blockchain Service service component.
A map can be passthrough or contain individual mappings for properties:
-
Mappings
Each required outgoing property for the smart contract is mapped from a corresponding incoming property from the payload schema. -
Passthrough
The incoming payload is routed with no intervention, leaving the incoming and outgoing payloads identical.
Route components
The following components make up a IoT Blockchain Service route:
- Source end-point
Applications send payloads to a source end-point, which is defined by the following components:- appname
The unique identifier of the type of app that connects, for exampleelevator.
Appname corresponds to the Watson IoT Platform ServicedeviceTypeparameter. - appevent
The unique identifier of the event, for examplestatus.
Appevent corresponds to the Watson IoT Platform Serviceevent_idparameter. - payload schema
The structure and content of the payload data that is processed by IoT Blockchain Service.
- appname
- Map
The properties of the incoming transaction or event payload are mapped to the outgoing payload that is required by the smart contract.
A map can be passthrough or contain individual mappings for properties:- Mappings
Each required outgoing property for the smart contract is mapped from a corresponding incoming property from the payload schema. - Passthrough
The incoming payload is routed with no intervention, leaving the incoming and outgoing payloads identical.
- Mappings
- Destination end-point
IoT Blockchain Service sends the outgoing payload to a destination end-point that is defined in a fabric definition with the following components:- fabric connection profile
A fabric connection profile describes the peers to which the service is to connect to talk to the target blockchain. It is obtained by uploading a Hyperledger Composer Business Network Card at fabric document creation time. - channel
A channel is a single independent blockchain inside a larger blockchain business network and is defined in the fabric connection profile.
Important: IoT Blockchain Service requires unique channel names across the blockchain fabrics that are used by your IoT Blockchain Service organization. - smart contract
A deployed smart contract developed using the Hyperledger Composer, which enables management and manipulation of business rules, network participants, queries, and access control in a single deployable contract. It is defined in the fabric connection profile. Other terms used are Hyperledger Composer Business Network and BNA or Business Network Archive. - smart contract transaction payload schema format
One or more formats to which incoming payloads can be transformed to communicate with the smart contract.
- fabric connection profile
- Notifications
IoT Blockchain Service can send one or more of three event types to an application for a transaction.
Notifications can be directed to either an http(s) endpoint or to an IBM® Event Streams for IBM Cloud topic. The following event types are supported:- Settlement
The final status of a transaction: SUCCESS or FAILURE. A failure settlement carries a reason for the failure. The event is sent by the service that processes the transaction immediately upon notification from the blockchain. - Asset Update
A new asset state in an asset registry as the result of this transaction. Every state transition that occurs as the result of the transaction generates a separate notification. The event is sent when the block containing the transaction has been committed and is suppressed when the transaction has failed. - Contract Emitted Event
Information that the smart contract sends to the application. This event type might contain an event showing the state transition or might contain information regarding alerts or other relevant occurrences that an application should be aware of. The event is sent when the block containing the transaction has been committed and is suppressed when the transaction has failed.
- Settlement
Create an IoT Blockchain Service route with the API
Follow these steps to create a route with the IoT Blockchain Service API.
Tip: You can also create basic passthrough routes using the IoT Blockchain Service user interface. For information, see Getting started with IoT Blockchain Service.
Before you begin.
- Understand your smart contract API property formats and your application or device payload properties.
Use Hyperledger Composer to explore your smart contract at:http://<public_IP>:31080
Wherepublic_IPif your blockchain network's Kubernetes cluster public IP. For a smart contract example, see Smart contract. - Look over the Routes API documentation.
- Optional: Install the sample postman collection.
Route creation sample calls are included with the sample postman collection:- Set up Postman.
Download and install Postman at: https://www.getpostman.com. - Import the Postman collection.
- Download the IoTBC_Customer.postman_collection.json collection that is available from Github.
- In Postman, click Import and then import the file that you just downloaded.
- Open the collection in postman.
- Edit the collection and select the Variables tab.
Update the included variables with the information for your environment.iotbc_url: https://iot-blockchain.ibm.com org: <organization_id> user: use-token-auth api: api/v1/{{org}} public_IP: <your_cluster_public_IP> pass: <your_organization_api_key> - Open the 2. Routes folder.
- Duplicate and then modify the new route iot-bti-create postman command for your environment.
For examples, see Examples.
- Set up Postman.
Create an IoT Blockchain Service notification endpoint with the API
A notification endpoint is defined in a separate Endpoint document, which defines an application end point with an HTTP or Event Streams target server to which IoT Blockchain Service sends the selected notifications. For more information, see the Endpoint and Route sections of the API documentation. The IoT Blockchain Service Postman collection contains examples of the two types of notifications under “3 Notify endpoints”.
To create an endpoint document, do the following API POST:
{iotbc_url}/api/v1/{org}/endpoints/{endpoint}
Where:
{iotbc_url}is the SaaS URL for your IoT Blockchain Service organization:https://iot-blockchain.ibm.com{org}is your five alphanumeric character IoT Blockchain Service organization identifier.{endpoint}is the name of the endpoint that you are creating.
The body of the call differs depending on the type of endpoint that you are creating:- Event Streams
- type
Useeventstream. - hosts
The host and port number for the Event Streams server. - name
The Event Streams topic name to publish notifications to. - Credentials A username and password that are used to access the Event Streams servers.
- type
- HTTP
- type
Usehttp. - url
The URL represents a callback HTTP application server that is able to catch and process notifications. - method
POST or PUT HTTP method as required by the server. - (Optional) Credentials A username and password that are used to access the callback HTTP server. If they are present they are used in a generated BASIC auth header.
- (Optional) Headers
These are sent to the callback server and can be used for example to send alternate credentials such as bearer auth.
- type
- Event Streams
Create a route
For a route and mapping example, see Sample route.
- Create a JSON routing map to map the properties.
Decide which device payload properties to include as required and which contract properties to map them to. -
Create the route.
For detailed information, see Create route API documentation.
Tip: If you installed the Postman collection, use the modified new route... postman command that you created.Do the following API
POST:
{iotbc_url}/api/v1/{org}/routes/{appname}/{appevent}
Where:-
{iotbc_url}is the SaaS URL for your IoT Blockchain Service organization:https://iot-blockchain.ibm.com{org}is your five alphanumeric character IoT Blockchain Service organization identifier.{appname}is the application name.
Tip: For Watson IoT Platform Service you could for example use the device name for clarity.{appevent}is the smart contract transaction to execute.
Use the following message content:
- Content-Type header:
application/json - Authorization header: Basic Auth with username
use-token-authand password:{apiKey}.
Note: For more information, see Creating IoT Blockchain Service API keys. - Body:
rawJSON (application/json) mapping. A mappings example is available in the Example route section.
-
Examples
The following examples are based on the sample IoT Blockchain Service supply chain IoT sample contract (iot-supplychain-network.bna) business network that is available Github.
Smart contract example
The sample smart contract data model looks like the following abbreviated example which defines a simple IoT device asset that is identified by deviceId and that contains several properties. Each of the transactions take the same required
parameter object format of type deviceId.
Two transactions are shown:
- CreateIoTDevice
The CreateIoTDevice transaction creates a new IoT device asset on the blockchain. - IoTDeviceReading
The IoTDeviceReading transaction writes device data to an existing IoT device asset.
Note: The full sample contract includes additional transactions.
/**
* Sample IoT business network definition for supply chain.
*/
namespace org.poc.scbn
asset IoTDevice identified by deviceId {
o String deviceId
o String description optional
o DateTime date optional
o DateTime time optional
o Double altitude optional
o Double accelX optional
o Double accelY optional
o Double accelZ optional
o Double latitude optional
o Double longitude optional
o Double temperature optional
o Double humidity optional
o Integer eventCode optional
o String shipmentId optional
--> SupplyChainParticipant participant optional
}
participant SupplyChainParticipant identified by email {
o String email
o String name
}
transaction CreateIoTDevice {
o String deviceId
o String description optional
o DateTime date optional
o DateTime time optional
o Double altitude optional
o Double accelX optional
o Double accelY optional
o Double accelZ optional
o Double latitude optional
o Double longitude optional
o Double temperature optional
o Double humidity optional
o Integer eventCode optional
o String shipmentId optional
--> SupplyChainParticipant participant optional
}
transaction IoTDeviceReading {
o String deviceId
o String description optional
o DateTime date optional
o DateTime time optional
o Double altitude optional
o Double accelX optional
o Double accelY optional
o Double accelZ optional
o Double latitude optional
o Double longitude optional
o Double temperature optional
o Double humidity optional
o Integer eventCode optional
o String shipmentId optional
--> SupplyChainParticipant participant optional
}
...
event LogInfoEvent {
o String message
o String payload
}
Incoming payload example
An operational payload from an IoT device that is sending a temperature reading might look like this:
{
"jsonString": {
"deviceId": "device1",
"temperature": -1.1,
"humidity": "83.0",
"latitude": 123,
"longitude": 456
}
}
Outgoing payload example
For Hyperledger Composer transactions, the transaction class, consisting of name space plus transaction class name, for the transaction provides the actual routing to the specific API which is implemented in JavaScript to match the defined transaction
data model format. In this case, the transaction class for creation would be constant.org.poc.scbn.CreateIoTDevice.
An outgoing payload, with only the deviceId parameter included might look like this for CreateIoTDevice:
{
"$class": "constant.org.poc.scbn.CreateIoTDevice",
"iotsensor_device": {
"deviceId": "device1"
}
}
This transaction creates an IoTDevice asset on the blockchain but doesn't include any associated data. Data can be added to the blockchain later by using the IoTDeviceReading transaction.
Route example
The following sample mapping route is included with the Postman IoTBC_Customer.postman_collection.json collection that is available from Github.
Notes
- The sample route in the Postman collection includes additional parameters.
- In the mappings section, each property that you want to send to the blockchain smart contract must be mapped from a property in the incoming payload.
- Tip: It is possible to map multiple smart contract properties from the same incoming payload using the regex mapping type. Regex lets you pick apart an incoming value and generate multiple outgoing properties with the pieces rearranged. This does not work in reverse (combining two incoming properties into one outgoing property).
- Mappings provide a mechanism to deal with a missing incoming property by designating the outgoing property optional or by designating it required and providing a default property value. Note that a default value is only used if the missing incoming property is designated required.
- Mappings use qualified paths to navigate the nested object hierarchy to incoming or outgoing properties, so any arbitrary change in structure is possible. Further, you do not have to create intermediate objects when mapping an outgoing property
as they are automatically created for you. So for example, the previous example would have a mapping entry from
jsonString.deviceIdtoiotsensor_device.deviceId. But it could as easily bu nested much deeperiotsensor_device.a.b.c.d.deviceIdand the intermediate object levels would be generated by this mapping entry. - Tip: If the properties of the incoming payload is an exact match to the smart contract properties then a
passthroughmapping can be used to forward the payload without intervention. This will be common with application transactions and uncommon with device events.
{
"deviceType": "iotsensor_device",
"eventId": "CreateIoTDevice",
"fabricName": "k8sFabric",
"dataMap": [
{
"output": "json",
"mappings": [
{
"deviceKey": "$class",
"chaincodeKey": "$class",
"required": true,
"default": "org.poc.scbn.CreateIoTDevice"
},
{
"deviceKey": "server.uuid",
"chaincodeKey": "transactionId",
"required": false
},
{
"deviceKey": "deviceId",
"chaincodeKey": "deviceId",
"required": true
},
{
"deviceKey": "description",
"chaincodeKey": "description",
"required": false
},
{
"deviceKey": "date",
"chaincodeKey": "date",
"required": false
},
{
"deviceKey": "time",
"chaincodeKey": "time",
"required": false
},
{
"deviceKey": "altitude",
"chaincodeKey": "altitude",
"required": false
},
{
"deviceKey": "accelX",
"chaincodeKey": "accelX",
"required": false
},
{
"deviceKey": "accelY",
"chaincodeKey": "accelY",
"required": false
},
{
"deviceKey": "accelZ",
"chaincodeKey": "accelZ",
"required": false
},
{
"deviceKey": "humidity",
"chaincodeKey": "humidity",
"required": false
},
{
"deviceKey": "latitude",
"chaincodeKey": "latitude",
"required": false
},
{
"deviceKey": "longitude",
"chaincodeKey": "longitude",
"required": false
},
{
"deviceKey": "eventCode",
"chaincodeKey": "eventCode",
"required": false
},
{
"deviceKey": "shipmentId",
"chaincodeKey": "shipmentId",
"required": false
},
{
"deviceKey": "temperature",
"chaincodeKey": "temperature",
"required": false
},
{
"deviceKey": "timestamp",
"chaincodeKey": "timestamp",
"required": true,
"default": "server.timestamp"
},
{
"deviceKey": "participant",
"chaincodeKey": "participant",
"required": false
}
]
}
],
"notification": false
}
A notification configuration section might look like this:
HTTP:
"notification":
{
"notifyName": "{endpoint}",
"notifyAssetUpdate": true,
"notifySettlement": true,
"notifyContractEvent": true
}
Where {endpoint} is the name of the endpoint that you created.