Main components and their functionality
The Thriot Server side consists of the following main components:
- Central Website
- Management API
- Platform API
- Platform Websocket interface
- Reporting API
- Messaging Services API
- Optional Telemetry Queueing Service
The Central Website can be used by a Web browser after user registration. Every time it requires a user/password based login and it’s responsibility is to provide management interface for the device structure, telemetry data sinks, show information about API keys, provide reporting and CSV export download functionality.
The Management API is responsible to build and query the structure, setup and query telemetry data sinks and their parameters, query API keys. Management API requires the same user-password based Login as the Central website. After logging in a security token is issued that can be used along with the Basic authentication schema. This is a REST API.
The Platform API is used to record telemetry data, send messages to a device and receive messages sent by other devices. The Platform API requires deviceId and API key based authentication (API keys can be optained from the Central Website). As API key you can use the device level, container network level and also the container service level Api key. This is a REST API.
The Platform Websocket interface is a websocket-based API unlike the previously mentioned APIs. Using this API one can open a persistent connection to the service. The API provides the same functionality as the Platform API.
The Reporting API is responsible to create reports in JSON and CSV format for the last sent telemetry data and for the time series built by telemetry data sent in a given timeframe. The Reporting API requires the same authentication mechanism as the Platform API with one additional extension: at network level reports the network id and at least network level API key should be specified. This is a REST API.
The Messaging Services API is an internal REST API. No external functionality is provided by this API. Implements the M2M messaging backend services.
The following figure shows a high-level component architecture of the system.
Thriot services are fully supported as hosting environment on Windows/IIS and Linux (Ubuntu 14 LST) and requires the full .NET Framework on Windows or Mono on Linux. It’s important to emphasize that in the future Thriot will be decoupled from the full .NET functionality and the .NET Core CLR will be the unified runtime environment on both platforms. In the current implementation the Management DB and the Telemetry data Storage can be Azure Table Storage, Microsoft SQL 2012+ (Express also) or PostgreSQL 9.4+ database. It’s also important to mention that due to the pluggable, loosely coupled architecture of Thriot arbitrary storage engine can be used. The Messaging DB is currently based on MS SQL 2012+ (Express also) and PostgreSql (for supporting Linux) in the future the plan is to support other storage engines in this place, too.
The figure shows what databases are accessed by the different components. The read line means read+write access, the purple line means read-only access. The messaging API is not intended to be used from the outside world.
These API and interface components above not only receive request from the outside world (browser and devices) rather communicate with each other, too. This is some kind of Microservice architecture that Thriot implements.
The Central website itself is a very thin piece of website, it reaches the Management API and the Reporting API to provide structure management and reporting functionality. Since Management API provides telemetry data sink setup and device setup functionality (which creates a records in the messaging DB at device creation) the Management API needs to communicate with the Platform and Reporting APIs. Besides telemetry functionality the Platform API provides M2M messaging functionality to devices that’s why it is important the reach the Messageing API from here. The Reporting API needs Platform Services for telemetry data sink enumeration. The Websocket API needs to access all of the Platform and Messaging APIs.
Since most parts of the system is stateless, or the state can be handled easily in the system, it is very easy to scale out however in the current phase it’s not the main goal.
The Management, Platform and Reporting API along with the Websocket interface are freely scalable solutions and can be deployed in several instances. Although Websockets API maintains a state, the websocket provides persistent client-server connections so the state is always bound to a dedicated instance.
It’s the Messaging API along with the Messaging DB that must run as a single instance, or in a failover cluster mode with one active node. This is a limitation that affects the overall system scalability generally in the messaging part. To overcome this limitation sharding will be implemented later.
Scaling out – queueing
To be able to scale components and functions more independently from each other the API layers shouldn’t directly communicate with the telemetry data storages since this is the data storage that can be a bottleneck. To overcome this limitation a queuing solution is implemented like Azure’s Eventhub or Apache Kafka. Currently SQL/PostgreSQL based queues (which are antipattern) and Azure Queues are supported. The reason why this is still an optional, user-selectable feature is that in most cases it just makes the architecture more complex and in case of relative small number of requests (just tens in a second) makes no sense at all.
To be able to find the entry point easier for the system when you check the source code please refer to the assembly-level component diagram below.
To make the above diagram more readable it contains only the most important components without the test projects, Azure and SQL-dependent assemblies and microservice proxies.