Asema IoT Central

Integration and migration


Chapter 1. Introduction

An IT system rarely has the luxury of operating as an independent, single entity. While from some technical viewpoint an isolated system is feasible and usually easy to implement, secure, and operate, extracting actual business value is another thing. It usually requires data sharing between different business flows to fit the business processes. How that data sharing is done then depends on the various systems to integrate. Not surprisingly, Asema IoT Central offers several different methods for such data sharing in order to accomodate flexible integration to legacy and new systems.

When new solutions are implemented, a key design question is also which existing parts to keep and integrate, which to migrate into a new system. Usually the decisions on migration work and system integration go hand in hand. For a system like Asema IoT Central, it is therefore equally important to be able to not only offer integration APIs to plug into other systems but also development capabilities that make it possible to replicate some of the functions of the other systems.

Smart integration is one of the corner stones of Asema IoT Central and consequently Asema champions the use of smart technologies for system integration. A particular innovation is this area is the Smart API, a specification and software development kit for using object oriented, scientifically accurate linked data in Internet of Things.

The purpose of Smart API is to enable smooth data from between systems across organizational borders, such as business units or partner organizations. In such scenarios the partners have little, if any, control over the structure and architecture of the IT systems of the other partners. This of what we call external integration.

However, there are multiple cases in the use of Asema IoT Central where internal integration takes place. Examples include product and service development projects where nearly full access to mostly all the systems is available. Where in external integration the implementation is usually limited to accessing various APIs and the process is mostly about defining data for those APIs, in internal integration there is much more flexibility. Data could be shared via APIs but also through interprocess communication, shared disk and database access, and simply by reimplementing and replacing parts of the system.

This document outlines various methods of internal integration with Asema IoT Central. For more information on external integration and the Smart API, please refer to the Smart API documentation.

Chapter 2. Integration and migration alternatives

Internal integration with Asema IoT Central ("IoTC") can be done with a range of methods that can be mixed and matched. Some parts can be reimplemented while others run remotely over APIs, etc. This chapter shows some of the primary examples of common methods but it is not uncommon that during an actual implementation even further combinations and solutions eventually arise. Many of the methods outline below are based on plugins i.e. software library code that runs with the application core. When extensions to the software are needed, new features can be implemented and distributed using the plugins without changes to the core systems.

2.1. Simply move and run

This is a straightforward option where Asema IoT Central operates as the only IT system. Existing legacy code is moved onto IoTC by at least partially reimplementing some of the functionality. IoTC runs a standard HTTP server that can serve basically any text based page on it, including the standard html, JavaScript, css and other files used in browser interfaces. For backend data operations, the IoTC has a JSON API. The API can be extended with plugins and scripts to create request handlers familiar from application servers. Additionally a websocket server is available for real-time functions of the UI.

The moving and running option is often most feasible if the existing system is primarily UI driven and implements most of its functionality in JavaScript as an AJAX application. Backend operations in such case are relatively limited. The application is already or could be implemented on a basic HTTP server, such as Apache or Nginx or as a server side scripting solution such as node.js. Programmers who have done server side scripting with node.js should feel at home with IoTC's approach to request processing. Like node.js, IoTC is based on signals and an event loop. This is why the programming style is similar and the syntax mimics that of node.js.

Migration to IoTC in such case would mean copying the pages of the existing application to the HTTP server of IoTC. IoTC offers a powerful templating language, based on the syntax of Django templates, which in our opinion is one of the richest and easiest templating syntaxes available. Backend AJAX calls would be replaced with the corresponding calls of the IoTC.

Below is an example of a template. It draws a simple header and footer and includes some styles for a page. Curly brackets mark spots where the template expects content to be replaced. In this template there is one block at the title and another at main content.

<!DOCTYPE html>
<html>
<head>
	<title>{% block title %}{% endblock %}</title>
		
	<style>
		body {
			background-color: #ededed;
		}
		
		#header {
			background-color: #005e9c;
			color: #fff;
			border-bottom: 2px solid #fff;
		}
		
		#footer {
			background-color: #123456;
			border-top: 1px solid #000;
			color: #fff;
			text-align: center;
		}
	</style>
</head>
<body>
<div id="header">
	<ul>
		<li><a href="#">Navi 1</a></li>
		<li><a href="#">Navi 2</a></li>
		<li><a href="#">Navi 3</a></li>
	</ul>
</div>

<div id="content">
	{% block content %}{% endblock %}
</div>

<div id="footer">Copyright © 2017 Acme Ltd</div>
</body>
</html>
				

This is a page that uses the template. It defines the blocks where it wants new content. When the page is requested, values are replaced by block, giving the pages that use the template one common look and feel.

{% extends "templates/headerfooter.html" %}

{% block title %}This is my hello page{% endblock %}

{% block content %}Well, hello there. World.{% endblock %}

<span class="further_text">Just wanted to say hi to everyone.</span>
				

As a large part of modern user interfaces use templating of some kind, the templating engine offers a familiar way to do the migration and retain the structure of the user interface. The Django templating language is very expressive and usually all features of other templating systems can be replicated.

IoTC supplies an easy to use object management library for JavaScript that makes backend integration painless. The library automatically handles AJAX calls to the backend and tracks the properties of objects using WebSocket technology. With the library, implementing features for typical IoT controls such as buttons, gauges and graphs is very straightforward. The library can be used to implement completely new controls or to act as a glue between the backend and the legacy controls of a user interface.

Below is a sample for creating an interactive button for an actuator out of a standard HTML checkbox. The control ("btn") is bound to the property of the object loaded from IoTC's backend. When something changes the state of the actuator, the check box changes accordingly automatically. Similarly, checking and unchecking the box will control the actual device, in this case a TV set.

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript" src="/inc/libs/jquery.min.js"></script>
	<script async defer type="text/javascript" src="jarvis-1.0/import?callback=load"></script>
</head>
<body>
<div class="btnholder">
	<input type="checkbox" class="tgl tgl-ios" id="btn"></input>
</div>
<script type="text/javascript">
	var objectManager = null;
	var actuator = null;
	
	function actuatorPropertyChanged(key, value) {
		if (key == "controller_state") $("#btn").prop("checked", value);
	}
	
	function loadedObjectsReady(propertyName) {
		if (propertyName == "demoActuator") {
			actuator = objectManager.objects.demoActuator.list[0];
			actuator.propertyChanged.connect(actuatorPropertyChanged);
		}
	}

	function objectManagerReady() {
		objectManager.findObjectsByName("demoActuator", "TV");
	}
	
	function load() {
		objectManager = new ObjectManager();
		objectManager.ready.connect(objectManagerReady);
		objectManager.objectsReady.connect(loadedObjectsReady);
		objectManager.start();
	
		$("#btn").change(function (e) {
			actuator.setProperty("controller_state", $(e.target).prop("checked"));
		});
	}
</script>
				

2.2. Asema IoT Central as a proxy for other systems

In this integration option the IoTC sits in front of other systems and proxies calls from user interfaces and APIs to the other systems. In this option IoTC offers one common front for all incoming calls and handles issues such as authentication and cross-site call protection.

Having the IoTC operate as a proxy is usually feasible when the other systems are request and logic driven but has a relatively light user interface for end-users. There could be for instance a Java based application server (say Tomcat or Glassfish) that has a significant amount of code for analyzing data. It would make no commercial sense to port all this code to a new environment so it is better to run it where it currently is. IoTC has methods to make and forward such calls so that the logic can remain in the existing application server while device connectivity and the user interface facade is handled by IoTC.

As a result, the existing investment on the application server is retained, engineers can continue to work with the technology familiar to them, and the users see one seamless service.

2.2.1. Proxied HTTP requests

IoTC has HTTP proxy functionality that can be used to filter and forward any HTTP call (GET, POST, etc). Forwarded URLs can be defined to determine to which system calls to a particular URL go to. For instance, if the user interface has the URL http://www.example.com/sensorlist, this could be processed by IoTC itself while http://www.example.com/proxy/schedules would automatically be forwarded to some other server. Once a result for the call is obtained, IoTC again automatically forwards it to the browser of the user.

2.2.2. Proxied AJAX calls

If the application server has an API that works with structured data (JSON, XML), it may not make sense or be technically feasible to address the whole HTTP request but to make it as a standard AJAX request. For this purpose IoTC has an AJAX forwarder. Instead of calling the application server, the user interface code calls the IoTC forwarder plugin, which then relays the call and the results back and forth.

Below is an example page that displays random numbers from an external service. This is done with a plugin called "forwarder". The forwarder takes as arguments some payload to be forwarded to the other system and the payload to be forwarded. In the example, the other service is requested to send back a random number between 10 and 100. To do this, the page loads a component called PluginManager which handles connections to plugins and automatically relays back the data from the plugin processes. The manager works fully asynchronously, the call can take as long as needed without blocking operating or causing a timeout. Once the PluginManager is connected, it calls the forwarder plugin and displays results once they are received by the plugin.

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript" src="/inc/libs/jquery.min.js"></script>
	<script async defer type="text/javascript" src="jarvis-1.0/import?callback=load"></script>
	<style>
		body {
			background-color: #ededed;
		}
		#content {
			text-align: center;
		}
		#randomdisplay {
			font-size: 200px;
		}
	</style>
</head>
<body>
<div id="content">
	<span id="randomdisplay"></span>
</div>
<script type="text/javascript">
	var pluginManager = null;
	
	function fetchRandomNumber() {
		var params = { 
			'rangeMin': 10,
			'rangeMax': 100
		};
		var request = {
			'payload': JSON.stringify(params),
			'contentType': 'application/json',
			'forwardTo': "http://127.0.0.1:8099/json/"
		}
		
		numberRequestCallId = pluginManager.invoke("forwarder", request);
	}
	
	function onPluginManagerReady() {
		fetchRandomNumber();
	}
	
	function onPluginDataReceived(callId, data) {
		if (callId == numberRequestCallId) {
			var resultJson = JSON.parse(data.data);
			$("#randomdisplay").html(resultJson.result);
		}
	}
		
	function onPluginCallError(error) {}
	
	function load() {
		pluginManager = new PluginManager();
		pluginManager.ready.connect(onPluginManagerReady);
		pluginManager.received.connect(onPluginDataReceived);
		pluginManager.error.connect(onPluginCallError);
		pluginManager.start();
	}
</script>
</body>
</html>
					

2.3. Other systems as proxies for Asema IoT Central

If there already is an existing application that has an integrated user interface and backend, implemented for instance with tools such as GWT, it may not be reasonable to break the harmony between the automatically generated user interface and the backend. In such case it is most likely more feasible to have IoTC working "behind" the other system.

For such integration IoTC has a JSON interface that offers full access to its event and processing system. Other application servers can integrate into it by subscribing to notifications via WebSockets, HTTP Push or MQTT protocols. Simple HTTP calls let the other system query the database of the IoTC efficiently and access the various gateways, sensors and actuators that the IoTC manages.

The JSON interface is easy to use and uses standard JSON-RPC as the request format. Each object is recognized by a unique GID which can be used to address the item in case. Below is a simple payload for fetching the temperature from a sensor

{
	"id": 1
	"method": "get_object_property",
	"params": ["thisisasamplegid", "temperature_celsius"]
}
				

As a response, the call will receive something similar to the following

{
	"id": 1
	"result": {
		"gid": "thisisasamplegid",
		"property": "temperature_celsius",
		"value": 23.48
	}
	"errors": null
}
				

The Javascript user interface library that comes with IoTC runs equally well on a remote system than it runs on IoTC itself (or, to be absolutely precise, on a browser served by some other server, combined with the user interface code from that other server). Library dependencies have been minimized, the only requirement is a relatively recent version of jQuery. With such minimal system requirements, it should be possible to integrate IoTC's helper libraries to nearly any existing user interface. Once in place, the library will handle the data traffic to IoTC mostly automatically, making system integration work easy.

2.4. Third party proxy

For security, performance and various other reasons it may be beneficial to set up a dedicated proxy server, such as Nginx, to stand in front off all systems that constitute a service. A high performance proxy is a tool to then balance traffic, filter out unwanted requests, and grant access to various parts of the system.

While performing the task of filtering and guiding traffic, the proxy can also function as an integration tool. Based on the paths of the URIs, some traffic can be directed to IoTC, some to other systems. Behind the proxy, the systems can then operate independently or exchange data via their APIs as is necessary.

IoTC supports the use of frontend proxies in many ways. For instance all the URIs of IoTC can be prefixed with one simple configuration option, making it possible to set up a unique URI path for IoTC at the proxy. Further, IoTC's user management supports standard HTTP auth calls. For instance the popular Nginx proxy can be set up with a couple of simple configuration lines to authenticate incoming sessions against the user database of IoTC and then forwarding the session keys to other services. The result is one common user database and a seamless single sign-on to all services behind the proxy.

Below is a sample configuration for Nginx for setting up the IoTC as a single sign-on server. It confirms the cookie in each request against the authentication backend of IoTC. If no proper session exists, Nginx redirects the user to a login page.

user  nginx;
worker_processes  1;

http {
	include       mime.types;
	default_type  application/octet-stream;
	include conf.d/*.conf;

	server {
		listen       80;
		server_name  www.example.com;

		# Authenticate all requests to this server by making an internal call
		auth_request /auth;
	
		# The authentication path, hook to the API that will respond
		# whether the cookies in the request have a valid session or not
		location = /auth {
			internal;
			proxy_pass http://127.0.0.1:8080;
			proxy_set_header Content-Length "";
			proxy_set_header X-Original-URI $request_uri;
			proxy_set_header Host $http_host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;

			if ($http_cookie ~* "x-login_token=([^;]+)(?:;|$)") {
				set $token "$1";
			}
			proxy_set_header X-SSO-Token $token;
		}
	
		# React to 401 codes => redirect to the login page which will
		# allow user to login and set the cookie to the appropriate value
		error_page 401 = @error401;
		location @error401 {
			return 302 http://www.example.com/login;
		}
	
		# The login path.
		location /login {
			proxy_pass http://127.0.0.1:8080;
	
			proxy_set_header Host $http_host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
		}

	}
	include vhosts.d/*.conf;
}
				

2.5. Database sharing

In some applications the existing systems are purely computation based. An example could be the big data analysis of sensoring data that runs at given intervals, extracts large amounts of data from the database, runs some statistics with software such as R, and writes the calculated values back to the database.

IoTC supports a specific integration technology called Database Objects for this purpose. Database Objects offer the same APIs, proprty management and control functionality as any other object in IoTC but their origin is the data in the database. In effect, they create controllable objects from the database data and react automatically to changes in the values stored to the database with the help of database triggers.

When the calculation algorithm changes values in the database or feeds in new calculated data, IoTC's database objects pick up the changes and store them to the properties. Events of the changes are sent through the system, triggering user interfaces, business rules and APIs. The end result is again a seamless user experience of the integrated system.

Further information and support

Asema's website at www.asema.com gives you more information about Asema's products and their technology. Visit the support site for latest products announcements, compatibility information and latest online versions of manuals.