Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Iot hub agent
1. A cloud based IoT solution
IotHub provides an abstract solution of any IoT infrastructure including Broker system, API management,
Authentication, Agent management system, so that it can be extended to any preferable IoT solution like home
automation system, supply chain management.
Documentation
Solution Structure
IotHub.Agent
A .NET web project to establish the channel between MQTT broker and SignalR broker. This agent will
publish all MQTT broker messages to SignalR clients (dashboard, control panel) and send all commands
from SignalR clients to MQTT clients. Agent is using MQTTnet managed client to connect with MQTT
broker.
IotHub.API
A .NET web API project to provide and manage all data sources of the solution. This project use.
IotHub.Broker
A .NET web project to establish a MQTT broker server. Broker is using MQTTnet server .
IotHub.Common
A .NET classlib project to provide all common models, enums, exceptions and other stuffs.
IotHub.DataTransferObject
A .NET classlib project, using to transfer data from service layer to service, controller and other service
consumers.
IotHub.DB
A .NET classlib project, to provide all database context and settings. Solution is using MongoDB as primary
database.
IotHub.DomianModels
A .NET classlib project, to provide domain level models.
IotHub.Repositories
A .NET classlib project, to communicate with database or data source and response in domain level. Only
IotHub.Services have the access to use repository to provide a security level to access domain models.
IotHub.Services
A .NET classlib project, to provide all common services e.g authentication service, user management service,
profile management services.
No. 1 / 16
2. MongoDB
Repositories
Services
DB Context
MQTT Broker
Agent API
Common
Domain Model
DTO Model
Solution Architecture
Agent
Sensor
Sensor Actuator
Sensor
&
Actuator
MQTT
Broker
Actuator
MQTT
MQTT
MQTT
MQTT
MQTT
MQTT
SignalR
Hub
Dashboard
Control
Panel
SignalR SignalR
Broker Architecture
No. 2 / 16
3. How to use (development)
Very first clone the project using git clone https://github.com/rafiulgits/IotHub.git or download the
project by clicking on download button.
Required Environments
.NET Core 3.1 or later
MongoDB
Execution
Build the solution by dotnet build
Go to src/IotHub.API and from appsettings.json set your internal custom credential and use this
credential create some new users (including agent one) and profiles
Run the src/IotHub.Broker development server by dotnet watch run
Go to src/IotHub.Agent , set agent credentials that you created earlier and run the development server by
dotnet watch run
Development environment is ready to use!
For testing with MQTT clients, MQTT fx is a good solution. iothub-dashboard is a Reactive example dashboard
that will help to find out how to use IotHub solution.
Full Documentations
IotHub.Agent Doc
IotHub.Broker Doc
IotHub.API Doc
API Doc Broker Doc Agent Doc
IotHub Agent
A .NET solution to host an MQTT Client as Agent and SignalR Hub. This project make a channel between MQTT
Broker and SignalR Hub. SignalR Hub allow admin and other controllers to publish/request to MQTT Broker as
MQTT Agent client via SignalR Hub method invoking and can also receive all published message on any topic to
MQTT Broker.
No. 3 / 16
4. Agent
Sensor
Sensor Actuator
Sensor
&
Actuator
MQTT
Broker
Actuator
MQTT
MQTT
MQTT
MQTT
MQTT
MQTT
SignalR
Hub
Dashboard
Control
Panel
SignalR SignalR
How to Use
Agent project is mainly design to provide admin/control level communication channel (get broker internal
information and send commands to broker).
To run IotHub Agent project, IotHub Broker must be in running state, otherwise MQTT Client Agent can't connect
with MQTT Broker.
By default IotHub Agent launch settings is
Launch settings is available in IotHub.AgentPropertieslaunchSettings.json
Note MQTT Broker must run in Port 1883 as MQTT default port.
Connection
Here is an example how to connect Agent SignalR Hub using JavaScript. Hub connection endpoint is
{HOST}/agenthub
Required package
@aspnet/signalr
HTTP Port: 4000
HTTPS Port: 4001
import * as SignalR from "@aspnet/signalr";
let hubConnection = new SignalR.HubConnectionBuilder()
.withUrl(`https://localhost:4001/?access_token={bearer_token}`)
.build();
hubConnection
.start()
.then(() => {
No. 4 / 16
5. Events
There are two event method available, one is for track the Agent MQTT Client connection status and another for
MQTT Broker Broadcast.
Broadcast(string topic, string payload)
This event will fire on every MQTT broker message publish.
Here is JavaScript example code
AgentConnectionStatus(bool isConnected)
This event will fire on connected/disconnected event of Agent MQTT Client.
Here is JavaScript example code
Invoke
To make a request to MQTT Broker, invoke the method SignalR Hub RequestMqttBroker method with topic
and payload , SignalR Hub will publish this message to MQTT Broker by Agent MQTT Client. Then MQTT Broker
will take the responsibility of that publishing.
RequestMqttBroker(string topic, string payload)
Here is JavaScript example code to request MQTT Broker to disconnect a client
An example of IotHub Dashboard
API Doc Broker Doc Agent Doc
IotHub Broker
A .NET web project to host MQTT Server. Broker is responsible to receive all messages publish by clients on
particular topics, filter them, send clients who are subscribed on that topics. IotHub solution is using MQTTnet
library.
console.log("agent hub connected")
})
.catch((err) => {
console.error(err);
});
hubConnection.on("Broadcast", (topic, payload) => {
console.log(`${topic}: ${payload}`)
});
hubConnection.on("AgentConnectionStatus", (isConnected) => {
let status = isConnected ? "Connected" : "Disconnected"
console.log(status)
})
let remoteMethod = "RequestMqttBroker"
let topic = "$SYS/request/broker/clients/disconnect/command";
let payload = "5abc12345";
hubConnection.invoke(remoteMethod, topic, payload)
No. 5 / 16
7. User Name Password Client ID User Type Response
Invalid Invalid Invalid any BadUserNameOrPassword
Valid Valid Invalid any ClientIdentifierNotValid
Valid Valid Valid Other NotAuthorized
Valid Valid Valid X Success
Zero length topic levels are valid, which can lead to some slightly non-obvious behavior. For example, a topic of
a//topic would correctly match against a subscription of a/+/topic . Likewise, zero length topic levels can
exist at both the beginning and the end of a topic string, so /a/topic would match against a subscription of
+/a/topic , # or /# , and a topic a/topic/ would match against a subscription of a/topic/+ or a/topic/# .
SYS Topics
Many MQTT brokers implement SYS-Topics. These topics are special meta topics that the broker can use to
publish information about the broker itself and its MQTT client sessions. All SYS-Topics start with $SYS and are
read-only for MQTT clients. The MQTT broker should prevent clients from using such topic names to publish
messages.
https://www.hivemq.com/blog/why-you-shouldnt-use-sys-topics-for-monitoring/
A documentation about System topics is available here
How to Use
Authentication
To connect with broker a client must authenticate with valid UserName , Password and ClientID .
Here X is representing not Other type. e.g:
Admin
Agent
Sensor
Actuator
Sensor and Actuator
Subscription
IotHub Broker allow only admin/agent to subscribe any topic. Otherwise broker will check whether client has the
subscription on that topic. Every client has a list of subscription provided by admin that it can subscribe. Check
API documentation to find out how to add/remove subscription of a client/user. Make sure that $SYS topics are
allowed to subscribe. Because these topics are reserved for internal communication not for public broadcast.
SYS topics
IotHub broker allow only agent to publish $SYS to topic to make a request or command to MQTT broker to
execute some internal execution i.e Request to disconnect a client, Request to get connected clients id. Broker
doesn't broadcast this agent`s system publish. broker will perform an internal execution and broadcast all
respective clients about that execution as an response event. And thus agent will get the associated response of
its request.
No. 7 / 16
9. Status Code Reason
200 OK Successful GET , PUT request
204 No Content Successful DELETE , PATCH request
201 Created Success POST request
400 Bad Request Validation requirements or formation error.
401 Unauthorized When anonymous user want to access any authenticated endpoint
403 Forbidden User doesn't have the permission to access that endpoint
404 Not Found If requested result not found by the system
405 Method Not
Allowed
If requested method doesn't support by the endpoint
406 Not
Acceptable
If requested form ( Content-Type and Accept ) doesn't support by the system. See
Content Negotiation
500 Internal Server
Error
Whenever server is failed to execute or finish a task.
API Doc Broker Doc Agent Doc
IotHub API
A .NET web API project to provide the API support of IotHub Solution. By default this project is hosting on HTTP
5000 and HTTPS 5001 .
Open /swagger to view the Swagger interface.
Backdoor Admin login
There is a backdoor in IotHub API to allowed admin to authenticate with custom credentials. These credentials
are store in appSettings.json of IotHub API project
There is an option to turned off internal authentication by changing the parameter isActive to false . Even
admin can change this custom credential anytime. This credential has the admin level permission to access any
resource in that solution.
Status Codes
Values
"InternalAuthSettings": {
"IsActive" : true,
"UserName": "admin",
"Password": "12345678"
},
No. 9 / 16
10. Types
User Types
Admin = 1
Agent = 2
Actuator = 3
Sensor = 4
ActuatorAndSensor = 5
Other = 6
Profile Types
Agent = 1
Device = 2
People = 3
Authorize Permissions
Admin required admin type user
AgentOrAdmin required admin or agent type user
Endpoints
Authentication
Any user (including anonymous) can access authentication endpoints
POST /api/authentication/login
Request
Response
POST /api/authentication/internal-login
Request
Response
{
"name": "string",
"password": "string"
}
{
"bearer": "string"
}
{
"name": "string",
"password": "string"
}
No. 10 / 16
11. Name Located in Description Required Schema
id path Yes string
Name Located in Description Required Schema
id path Yes string
Profile
Only authenticated users can access profile endpoints
GET /api/profiles/{id}
Parameters
Permission: Admin Or Agent
Response
PUT /api/profiles/{id}
Parameters
Permission: Admin
Request
Response
{
"bearer": "string"
}
{
"displayName": "string",
"userId": "string",
"type": 1,
"createdDate": "2020-05-17T11:45:31.978Z",
"lastModifiedDate": "2020-05-17T11:45:31.978Z",
"id": "string"
}
{
"displayName": "string",
"userId": "string",
"type": 1,
"id": "string"
}
No. 11 / 16
12. Name Located in Description Required Schema
id path Yes string
DELETE /api/profiles/{id}
Parameters
Permission: Admin
Response
204 No Content
GET /api/profiles
Permission: Admin or Agent
Response
POST /api/profiles
Permission: Admin
Request
Response
{
"displayName": "string",
"userId": "string",
"type": 1,
"createdDate": "2020-05-17T11:45:31.978Z",
"lastModifiedDate": "2020-05-17T11:45:31.978Z",
"id": "string"
}
[
{
"displayName": "string",
"userId": "string",
"type": 1,
"createdDate": "2020-05-17T11:50:38.102Z",
"lastModifiedDate": "2020-05-17T11:50:38.102Z",
"id": "string"
}
]
{
"displayName": "string",
"userId": "string",
"type": 1
}
No. 12 / 16
13. Name Located in Description Required Schema
id path Yes string
Name Located in Description Required Schema
id path Yes string
Name Located in Description Required Schema
id path Yes string
PATCH /api/profiles/{id}/subscriptions
Parameters
Permission: Admin
Request
Response
204 No Content
DELETE /api/profiles/{id}/subscriptions
Parameters
Permission: Admin
Response
204 No Content
GET /api/profiles/{id}/subscriptions
Parameters
Permission: Admin or Agent
{
"displayName": "string",
"userId": "string",
"type": 1,
"createdDate": "2020-05-17T11:51:07.857Z",
"lastModifiedDate": "2020-05-17T11:51:07.857Z",
"id": "string"
}
{
"profileId": "string",
"path": "string"
}
No. 13 / 16
14. Name Located in Description Required Schema
id path Yes string
Response
User
Only authenticated users can access user endpoints
GET /api/users/{id}
Parameters
Permission: Admin or Agent
Response
POST /api/users
Permission: Admin
Request
Response
[
{
"profileId": "string",
"path": "string"
}
]
{
"name": "string",
"type": 1,
"isActive": true,
"isConnected": true,
"lastConnected": "2020-05-17T13:10:00.245Z",
"createdDate": "2020-05-17T13:10:00.245Z",
"lastModifiedDate": "2020-05-17T13:10:00.245Z",
"id": "string"
}
{
"name": "string",
"password": "string",
"type": 1,
"isActive": true,
}
No. 14 / 16
15. GET /api/users
Permission: Admin or Agent
Response
GET /api/users/connected
Permission: Admin or Agent
Response
MQTT Client ASP.NET Core
This repository is an example of how to use MQTTnet client in ASP.NET core web application with services.
MQTT Client is running in MqttClientService by IHostedService , and it is a singleton service.
To access MqttClientService from other external services inject MQTTClientServiceProvider in service
constructor.
{
"name": "string",
"type": 1,
"isActive": true,
"isConnected": true,
"lastConnected": "2020-05-17T13:11:42.274Z",
"createdDate": "2020-05-17T13:11:42.274Z",
"lastModifiedDate": "2020-05-17T13:11:42.274Z",
"id": "string"
}
[
{
"name": "string",
"type": 1,
"isActive": true,
"isConnected": true,
"lastConnected": "2020-05-17T13:12:47.765Z",
"createdDate": "2020-05-17T13:12:47.765Z",
"lastModifiedDate": "2020-05-17T13:12:47.765Z",
"id": "string"
}
]
[
{
"name": "string",
"type": 1,
"isActive": true,
"isConnected": true,
"lastConnected": "2020-05-17T13:12:47.765Z",
"createdDate": "2020-05-17T13:12:47.765Z",
"lastModifiedDate": "2020-05-17T13:12:47.765Z",
"id": "string"
}
]
No. 15 / 16
16. Here is an example
Configuration
Configure your MQTT settings in appSettings.json
Now do whatever you want to do with MQTTClientService !
public class ExtarnalService
{
private readonly IMqttClientService mqttClientService;
public ExtarnalService(MqttClientServiceProvider provider)
{
mqttClientService = provider.MqttClientService;
}
}
"BrokerHostSettings": {
"Host": "localhost",
"Port": 1883
},
"ClientSettings": {
"Id": "5eb020f043ba8930506acbdd",
"UserName": "rafiul",
"Password": "12345678"
},
No. 16 / 16