SMQ-3026 - Update READMEs and make them use the same l&f (#3239)

Signed-off-by: Musilah <nataleigh.nk@gmail.com>
This commit is contained in:
Nataly Musilah
2025-12-01 20:52:53 +03:00
committed by GitHub
parent c5a4336d43
commit 15e756a5a3
45 changed files with 2236 additions and 304 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ hosted on the [Abstract Machines Organization](https://github.com/absmach) on Gi
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
By participating, you are expected to uphold this code. Please report unacceptable behavior to
[abuse@abstractmachines.fr](mailto:abuse@abstractmachines.fr).
[abuse@absmach.eu](mailto:abuse@absmach.eu).
## Reporting issues
+11 -26
View File
@@ -1,30 +1,15 @@
# SuperMQ follows the timeless, highly efficient and totally unfair system
# known as [Benevolent dictator for
# life](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), with
# Drasko DRASKOVIC in the role of BDFL.
# SuperMQ Maintainers
[bdfl]
[[drasko]]
Name = "Drasko Draskovic"
Email = "drasko@abstractmachines.fr"
GitHub = "drasko"
SuperMQ follows a BDFL model for dead-lock situations; day-to-day decisions happen through discussion and pull requests.
# However, this role serves only in dead-lock events, or in a special and very rare cases
# when BDFL completely disagrees with the decisions made.
# In the normal flow of events, decisions on the project design are made through discussions,
# most often on the Pull Requests.
#
# Maintainers have the special role in the project in managing and accepting PRs,
# overall leading the project and making design decisions on the maintained subsystems.
#
# A reference list of all maintainers of the SuperMQ project.
## BDFL
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
- **Drasko Draskovic** — [drasko@absmach.eu](mailto:drasko@absmach.eu) — [GitHub: drasko](https://github.com/drasko)
[maintainers]
[[dusan]]
Name = "Dusan Borovcanin"
Email = "dusan.borovcanin@abstractmachines.fr"
GitHub = "dborovcanin"
## Maintainers
Add yourself below in alphabetical order.
| Name | Email | GitHub |
| --- | --- | --- |
| Dusan Borovcanin | [dusan.borovcanin@absmach.eu](mailto:dusan.borovcanin@absmach.eu) | [dborovcanin](https://github.com/dborovcanin) |
+18 -21
View File
@@ -1,26 +1,24 @@
<div align="center">
# SuperMQ
# SuperMQ
**Planetary event-driven infrastructure**
### Planetary event-driven infrastructure
**Made with ❤️ by [Abstract Machines](https://absmach.eu/)**
[![Build Status](https://github.com/absmach/supermq/actions/workflows/build.yaml/badge.svg?branch=main)](https://github.com/absmach/supermq/actions/workflows/build.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/absmach/supermq)](https://goreportcard.com/report/github.com/absmach/supermq)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/absmach/supermq)
[![Check License Header](https://github.com/absmach/supermq/actions/workflows/check-license.yaml/badge.svg?branch=main)](https://github.com/absmach/supermq/actions/workflows/check-license.yaml)
[![Check Generated Files](https://github.com/absmach/supermq/actions/workflows/check-generated-files.yaml/badge.svg?branch=main)](https://github.com/absmach/supermq/actions/workflows/check-generated-files.yaml)
[![Coverage](https://codecov.io/gh/absmach/supermq/graph/badge.svg?token=nPCEr5nW8S)](https://codecov.io/gh/absmach/supermq)
[![License](https://img.shields.io/badge/license-Apache%20v2.0-blue.svg)](LICENSE)
[![Matrix](https://img.shields.io/matrix/supermq%3Amatrix.org?label=Chat&style=flat&logo=matrix&logoColor=white)](https://matrix.to/#/#supermq:matrix.org)
**Made with ❤️ by [Abstract Machines](https://absmach.eu/)**
### [Guide](https://docs.supermq.absmach.eu) | [Contributing](CONTRIBUTING.md) | [Website](https://absmach.eu/) | [Chat](https://matrix.to/#/#supermq:matrix.org)
[![Build Status](https://github.com/absmach/supermq/actions/workflows/build.yaml/badge.svg?branch=main)](https://github.com/absmach/supermq/actions/workflows/build.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/absmach/supermq)](https://goreportcard.com/report/github.com/absmach/supermq)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/absmach/supermq)
[![Check License Header](https://github.com/absmach/supermq/actions/workflows/check-license.yaml/badge.svg?branch=main)](https://github.com/absmach/supermq/actions/workflows/check-license.yaml)
[![Check Generated Files](https://github.com/absmach/supermq/actions/workflows/check-generated-files.yaml/badge.svg?branch=main)](https://github.com/absmach/supermq/actions/workflows/check-generated-files.yaml)
[![Coverage](https://codecov.io/gh/absmach/supermq/graph/badge.svg?token=nPCEr5nW8S)](https://codecov.io/gh/absmach/supermq)
[![License](https://img.shields.io/badge/license-Apache%20v2.0-blue.svg)](LICENSE)
[![Matrix](https://img.shields.io/matrix/supermq%3Amatrix.org?label=Chat&style=flat&logo=matrix&logoColor=white)](https://matrix.to/#/#supermq:matrix.org)
### [Guide](https://docs.supermq.absmach.eu) | [Contributing](CONTRIBUTING.md) | [Website](https://absmach.eu/) | [Chat](https://matrix.to/#/#supermq:matrix.org)
</div>
## Introduction 📖
SuperMQ is a distributed, highly scalable, and secure open-source cloud platform for messaging and event-driven architecture (EDA). It is a planetarily distributed, highly scalable, and secure platform that serves as a robust foundation for building advanced real-time and reactive systems.
@@ -61,11 +59,11 @@ Or use the [Makefile](Makefile) for a simpler command:
make run
```
For production deployments, check our [Kubernetes guide](https://docs.supermq.abstractmachines.fr/kubernetes). ⚙️
For production deployments, check our [Kubernetes guide](https://docs.supermq.absmach.eu/kubernetes). ⚙️
### Usage 📤📥
#### Using the CLI:
**Using the CLI :**
```bash
make cli
@@ -74,7 +72,7 @@ make cli
This command retrieves the status of the SuperMQ server and outputs it to the console.
#### Using HTTP with Curl:
**Using HTTP with Curl :**
```bash
curl -X GET http://localhost:8080/status
@@ -82,11 +80,11 @@ curl -X GET http://localhost:8080/status
This request fetches the server status over HTTP and provides a JSON response.
See our [CLI documentation](https://docs.supermq.abstractmachines.fr/cli) for more details.
See our [CLI documentation](https://docs.supermq.absmach.eu/cli) for more details.
## Documentation 📚
The official documentation is hosted at [SuperMQ docs page](https://docs.supermq.abstractmachines.fr).
The official documentation is hosted at [SuperMQ docs page](https://docs.supermq.absmach.eu/).
Documentation is auto-generated, check out the instructions in the [docs repository](https://github.com/absmach/supermq-docs).
If you spot an error or a need for corrections, please let us know - or even better: send us a PR! 💌
@@ -116,4 +114,3 @@ SuperMQ is open-source software licensed under the [Apache License 2.0](LICENSE)
Special thanks to the amazing contributors who make SuperMQ possible. Check out the [MAINTAINERS](MAINTAINERS) file to see the team behind the magic.
Ready to build the future of messaging and event-driven systems? Let's get started! 🚀
+1 -1
View File
@@ -9,7 +9,7 @@ info:
contact:
name: SuperMQ Team
url: 'https://github.com/absmach/supermq'
email: info@abstractmachines.fr
email: info@absmach.eu
description: |
MQTT adapter provides an MQTT API for sending messages through the platform. MQTT adapter uses [mProxy](https://github.com/absmach/mproxy) for proxying traffic between client and MQTT broker.
Additionally, the MQTT adapter and the message broker are replicating the traffic between brokers.
+1 -1
View File
@@ -10,7 +10,7 @@ info:
contact:
name: SuperMQ Team
url: 'https://github.com/absmach/supermq'
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: 'https://github.com/absmach/supermq/blob/main/LICENSE'
+1 -1
View File
@@ -2,4 +2,4 @@
This folder contains an OpenAPI specifications for SuperMQ API.
View specification in Swagger UI at [docs.api.supermq.abstractmachines.fr](https://docs.api.supermq.abstractmachines.fr)
View specification in Swagger UI at [docs.api.supermq.absmach.eu](https://docs.api.supermq.absmach.eu)
+4 -4
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,17 +24,17 @@ tags:
description: Everything about your Keys.
externalDocs:
description: Find out more about keys
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: PATs
description: Everything about your Personal Access Tokens.
externalDocs:
description: Find out more about Personal Access Tokens
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Health
description: Service health check endpoint.
externalDocs:
description: Find out more about health check
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/keys:
+4 -4
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,17 +24,17 @@ tags:
description: CRUD operations for your channels
externalDocs:
description: Find out more about channels
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Connections
description: All operations involving channel and client connections
externalDocs:
description: Find out more about channel and client connections
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Health
description: Health check operations
externalDocs:
description: Find out more about health checks
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/{domainID}/channels:
+69 -5
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,17 +24,17 @@ tags:
description: CRUD operations for your clients
externalDocs:
description: Find out more about clients
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Roles
description: All operations involving roles for clients
externalDocs:
description: Find out more about roles
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Health
description: Health check operations
externalDocs:
description: Find out more about health checks
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/{domainID}/clients:
@@ -323,7 +323,7 @@ paths:
- bearerAuth: []
responses:
"200":
$ref: "#/components/responses/ClientRes"
$ref: "#/components/responses/DisabledClientRes"
"400":
description: Failed due to malformed client's ID.
"401":
@@ -1130,6 +1130,63 @@ components:
items:
type: string
DisabledClient:
type: object
properties:
id:
type: string
format: uuid
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
description: Client unique identifier.
name:
type: string
example: clientName
description: Client name.
tags:
type: array
minItems: 0
items:
type: string
example: ["tag1", "tag2"]
description: Client tags.
domain_id:
type: string
format: uuid
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
description: ID of the domain to which client belongs.
credentials:
type: object
properties:
identity:
type: string
example: clientIDentity
description: Client Identity for example email address.
secret:
type: string
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
description: Client secret password.
metadata:
type: object
example: { "model": "example" }
description: Arbitrary, object-encoded client's data.
status:
type: string
description: Client Status
format: string
example: disabled
created_at:
type: string
format: date-time
example: "2019-11-26 13:31:52"
description: Time when the channel was created.
updated_at:
type: string
format: date-time
example: "2019-11-26 13:31:52"
description: Time when the channel was created.
xml:
name: client
ClientSecret:
type: object
properties:
@@ -1447,6 +1504,13 @@ components:
schema:
$ref: "#/components/schemas/Client"
DisabledClientRes:
description: Data retrieved.
content:
application/json:
schema:
$ref: "#/components/schemas/DisabledClient"
ClientPageRes:
description: Data retrieved.
content:
+5 -5
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,22 +24,22 @@ tags:
description: CRUD operations for your domains
externalDocs:
description: Find out more about domains
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Roles
description: All operations involving roles for domains
externalDocs:
description: Find out more about roles
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Invitations
description: All operations involving invitations for domains
externalDocs:
description: Find out more about Invitations
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Health
description: Service health check endpoint.
externalDocs:
description: Find out more about health check
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/domains:
+4 -4
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,17 +24,17 @@ tags:
description: CRUD operations for your groups
externalDocs:
description: Find out more about users groups
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Roles
description: All operations involving roles for groups
externalDocs:
description: Find out more about roles
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Health
description: Health check operations
externalDocs:
description: Find out more about health checks
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/{domainID}/groups:
+2 -2
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,7 +24,7 @@ tags:
description: Everything about your Messages
externalDocs:
description: Find out more about messages
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/m/{domainPrefix}/c/{channelPrefix}:
+2 -2
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,7 +24,7 @@ tags:
description: Everything about your Twins
externalDocs:
description: Find out more about twins
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/twins:
+3 -3
View File
@@ -9,7 +9,7 @@ info:
Some useful links:
- [The SuperMQ repository](https://github.com/absmach/supermq)
contact:
email: info@abstractmachines.fr
email: info@absmach.eu
license:
name: Apache 2.0
url: https://github.com/absmach/supermq/blob/main/LICENSE
@@ -24,12 +24,12 @@ tags:
description: Everything about your Users
externalDocs:
description: Find out more about users
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
- name: Health
description: Health check operations
externalDocs:
description: Find out more about health checks
url: https://docs.supermq.abstractmachines.fr/
url: https://docs.supermq.absmach.eu/
paths:
/users:
+49 -49
View File
@@ -40,7 +40,7 @@ The following actions are supported:
## Domains
Domains are used to group users and clients. Each domain has a unique route that is associated with the domain. Domains are used to group users and their entities.
Domains are used to group users and clients. Each domain has a unique `route` that is associated with the domain. Domains are used to group users and their entities.
Domain consists of the following fields:
@@ -59,50 +59,50 @@ Domain consists of the following fields:
The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.
| Variable | Description | Default |
| ----------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------ |
| SMQ_AUTH_LOG_LEVEL | Log level for the Auth service (debug, info, warn, error) | info |
| SMQ_AUTH_DB_HOST | Database host address | localhost |
| SMQ_AUTH_DB_PORT | Database host port | 5432 |
| SMQ_AUTH_DB_USER | Database user | supermq |
| SMQ_AUTH_DB_PASSWORD | Database password | supermq |
| SMQ_AUTH_DB_NAME | Name of the database used by the service | auth |
| SMQ_AUTH_DB_SSL_MODE | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| SMQ_AUTH_DB_SSL_CERT | Path to the PEM encoded certificate file | "" |
| SMQ_AUTH_DB_SSL_KEY | Path to the PEM encoded key file | "" |
| SMQ_AUTH_DB_SSL_ROOT_CERT | Path to the PEM encoded root certificate file | "" |
| SMQ_AUTH_HTTP_HOST | Auth service HTTP host | "" |
| SMQ_AUTH_HTTP_PORT | Auth service HTTP port | 8189 |
| SMQ_AUTH_HTTP_SERVER_CERT | Path to the PEM encoded HTTP server certificate file | "" |
| SMQ_AUTH_HTTP_SERVER_KEY | Path to the PEM encoded HTTP server key file | "" |
| SMQ_AUTH_GRPC_HOST | Auth service gRPC host | "" |
| SMQ_AUTH_GRPC_PORT | Auth service gRPC port | 8181 |
| SMQ_AUTH_GRPC_SERVER_CERT | Path to the PEM encoded gRPC server certificate file | "" |
| SMQ_AUTH_GRPC_SERVER_KEY | Path to the PEM encoded gRPC server key file | "" |
| SMQ_AUTH_GRPC_SERVER_CA_CERTS | Path to the PEM encoded gRPC server CA certificate file | "" |
| SMQ_AUTH_GRPC_CLIENT_CA_CERTS | Path to the PEM encoded gRPC client CA certificate file | "" |
| SMQ_AUTH_SECRET_KEY | String used for signing tokens | secret |
| SMQ_AUTH_ACCESS_TOKEN_DURATION | The access token expiration period | 1h |
| SMQ_AUTH_REFRESH_TOKEN_DURATION | The refresh token expiration period | 24h |
| SMQ_AUTH_INVITATION_DURATION | The invitation token expiration period | 168h |
| SMQ_AUTH_CACHE_URL | Redis URL for caching PAT scopes | redis://localhost:6379/0 |
| SMQ_AUTH_CACHE_KEY_DURATION | Duration for which PAT scope cache keys are valid | 10m |
| SMQ_SPICEDB_HOST | SpiceDB host address | localhost |
| SMQ_SPICEDB_PORT | SpiceDB host port | 50051 |
| SMQ_SPICEDB_PRE_SHARED_KEY | SpiceDB pre-shared key | 12345678 |
| SMQ_SPICEDB_SCHEMA_FILE | Path to SpiceDB schema file | ./docker/spicedb/schema.zed |
| SMQ_JAEGER_URL | Jaeger server URL | <http://jaeger:4318/v1/traces> |
| SMQ_JAEGER_TRACE_RATIO | Jaeger sampling ratio | 1.0 |
| SMQ_SEND_TELEMETRY | Send telemetry to supermq call home server | true |
| SMQ_ADAPTER_INSTANCE_ID | Adapter instance ID | "" |
| SMQ_CALLOUT_URLS | Comma-separated list of callout URLs | "" |
| SMQ_CALLOUT_METHOD | Callout method | POST |
| SMQ_CALLOUT_TLS_VERIFICATION | Enable TLS verification for callouts | true |
| SMQ_CALLOUT_TIMEOUT | Callout timeout | 10s |
| SMQ_CALLOUT_CA_CERT | Path to CA certificate file | "" |
| SMQ_CALLOUT_CERT | Path to client certificate file | "" |
| SMQ_CALLOUT_KEY | Path to client key file | "" |
| SMQ_CALLOUT_OPERATIONS | Invoke callout if the authorization permission matches any of the given permissions. | "" |
| Variable | Description | Default |
| :--- | :--- | :--- |
| `SMQ_AUTH_LOG_LEVEL` | Log level for the Auth service (debug, info, warn, error) | info |
| `SMQ_AUTH_DB_HOST` | Database host address | localhost |
| `SMQ_AUTH_DB_PORT` | Database host port | 5432 |
| `SMQ_AUTH_DB_USER` | Database user | supermq |
| `SMQ_AUTH_DB_PASSWORD` | Database password | supermq |
| `SMQ_AUTH_DB_NAME` | Name of the database used by the service | auth |
| `SMQ_AUTH_DB_SSL_MODE` | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| `SMQ_AUTH_DB_SSL_CERT` | Path to the PEM encoded certificate file | "" |
| `SMQ_AUTH_DB_SSL_KEY` | Path to the PEM encoded key file | "" |
| `SMQ_AUTH_DB_SSL_ROOT_CERT` | Path to the PEM encoded root certificate file | "" |
| `SMQ_AUTH_HTTP_HOST` | Auth service HTTP host | "" |
| `SMQ_AUTH_HTTP_PORT` | Auth service HTTP port | 8189 |
| `SMQ_AUTH_HTTP_SERVER_CERT` | Path to the PEM encoded HTTP server certificate file | "" |
| `SMQ_AUTH_HTTP_SERVER_KEY` | Path to the PEM encoded HTTP server key file | "" |
| `SMQ_AUTH_GRPC_HOST` | Auth service gRPC host | "" |
| `SMQ_AUTH_GRPC_PORT` | Auth service gRPC port | 8181 |
| `SMQ_AUTH_GRPC_SERVER_CERT` | Path to the PEM encoded gRPC server certificate file | "" |
| `SMQ_AUTH_GRPC_SERVER_KEY` | Path to the PEM encoded gRPC server key file | "" |
| `SMQ_AUTH_GRPC_SERVER_CA_CERTS` | Path to the PEM encoded gRPC server CA certificate file | "" |
| `SMQ_AUTH_GRPC_CLIENT_CA_CERTS` | Path to the PEM encoded gRPC client CA certificate file | "" |
| `SMQ_AUTH_SECRET_KEY` | String used for signing tokens | secret |
| `SMQ_AUTH_ACCESS_TOKEN_DURATION` | The access token expiration period | 1h |
| `SMQ_AUTH_REFRESH_TOKEN_DURATION` | The refresh token expiration period | 24h |
| `SMQ_AUTH_INVITATION_DURATION` | The invitation token expiration period | 168h |
| `SMQ_AUTH_CACHE_URL` | Redis URL for caching PAT scopes | redis://localhost:6379/0 |
| `SMQ_AUTH_CACHE_KEY_DURATION` | Duration for which PAT scope cache keys are valid | 10m |
| `SMQ_SPICEDB_HOST` | SpiceDB host address | localhost |
| `SMQ_SPICEDB_PORT` | SpiceDB host port | 50051 |
| `SMQ_SPICEDB_PRE_SHARED_KEY` | SpiceDB pre-shared key | 12345678 |
| `SMQ_SPICEDB_SCHEMA_FILE` | Path to SpiceDB schema file | ./docker/spicedb/schema.zed |
| `SMQ_JAEGER_URL` | Jaeger server URL | <http://jaeger:4318/v1/traces> |
| `SMQ_JAEGER_TRACE_RATIO` | Jaeger sampling ratio | 1.0 |
| `SMQ_SEND_TELEMETRY` | Send telemetry to supermq call home server | true |
| `SMQ_ADAPTER_INSTANCE_ID` | Adapter instance ID | "" |
| `SMQ_CALLOUT_URLS` | Comma-separated list of callout URLs | "" |
| `SMQ_CALLOUT_METHOD` | Callout method | POST |
| `SMQ_CALLOUT_TLS_VERIFICATION` | Enable TLS verification for callouts | true |
| `SMQ_CALLOUT_TIMEOUT` | Callout timeout | 10s |
| `SMQ_CALLOUT_CA_CERT` | Path to CA certificate file | "" |
| `SMQ_CALLOUT_CERT` | Path to client certificate file | "" |
| `SMQ_CALLOUT_KEY` | Path to client key file | "" |
| `SMQ_CALLOUT_OPERATIONS` | Invoke callout if the authorization permission matches any of the given permissions. | "" |
## Deployment
@@ -183,7 +183,7 @@ PATs in SuperMQ are designed with the following features:
A PAT consists of three parts separated by underscores:
```
```bash
pat_<encoded-user-and-pat-id>_<random-string>
```
@@ -318,7 +318,7 @@ curl --location --request PATCH 'http://localhost:9001/pats/a2500226-95dc-4285-8
When making API requests, include the PAT in the Authorization header:
```
```bash
Authorization: Bearer pat_<encoded-user-and-pat-id>_<random-string>
```
@@ -444,6 +444,6 @@ When a PAT is used for authentication:
## Usage
For more information about service capabilities and its usage, please check out the [API documentation](https://docs.api.supermq.abstractmachines.fr/?urls.primaryName=auth.yaml).
For more information about service capabilities and its usage, please check out the [API documentation](https://docs.api.supermq.absmach.eu/?urls.primaryName=auth.yaml).
[doc]: https://docs.supermq.abstractmachines.fr
[doc]: https://docs.supermq.absmach.eu/
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ Auth service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+216
View File
@@ -0,0 +1,216 @@
# Channels
The Channels service is a core component of SuperMQ that manages communication channels between devices and applications. It handles channel creation, configuration, access control and message routing within the SuperMQ ecosystem.
## Configuration
The service is configured using the following environment variables (unset variables use default values):
| Variable | Description | Default |
|-----------------------------|--------------------------------------------------------------|-------------|
| `SMQ_CHANNELS_LOG_LEVEL` | Log level (debug, info, warn, error) | info |
| `SMQ_CHANNELS_HTTP_HOST` | HTTP host for Channels service | localhost |
| `SMQ_CHANNELS_HTTP_PORT` | HTTP port for Channels service | 9005 |
| `SMQ_CHANNELS_SERVER_CERT` | Path to PEM encoded server certificate | "" |
| `SMQ_CHANNELS_SERVER_KEY` | Path to PEM encoded server key file | "" |
| `SMQ_CHANNELS_GRPC_HOST` | gRPC host for Channels service | localhost |
| `SMQ_CHANNELS_GRPC_PORT` | gRPC port for Channels service | 7005 |
| `SMQ_CHANNELS_DB_HOST` | Database host address | localhost |
| `SMQ_CHANNELS_DB_PORT` | Database port | 5432 |
| `SMQ_CHANNELS_DB_USER` | Database user | supermq |
| `SMQ_CHANNELS_DB_PASS` | Database password | supermq |
| `SMQ_CHANNELS_DB_NAME` | Name of the database used by the service | channels |
| `SMQ_CHANNELS_DB_SSL_MODE` | Database connection SSL mode | disable |
| `SMQ_CHANNELS_CACHE_URL` | Cache database URL | <redis://localhost:6379/0> |
| `SMQ_JAEGER_URL` | Jaeger tracing server URL | <http://jaeger:4318/v1/traces> |
| `SMQ_SEND_TELEMETRY` | Send telemetry to SuperMQ call-home server | true |
## Features
- **Channel Management**: Create, update, delete and list channels
- **Access Control**: Manage channel permissions and user access
- **Message Routing**: Route messages between connected devices and services
- **Channel Groups**: Organize channels into logical groups
- **Metadata Support**: Attach custom metadata to channels
- **Real-time Updates**: Live channel state synchronization
## Architecture
The service is built using:
- **Go**: Core service implementation
- **gRPC**: Inter-service communication
- **PostgreSQL**: Primary data storage
- **Redis**: Caching and pub/sub messaging
- **Docker**: Containerized deployment
### Channels Table
| Column | Type | Description |
|--------------------|----------------|----------------------------------------------------------------|
| `id` | VARCHAR(36) | UUID of the channel (primary key) |
| `name` | VARCHAR(1024) | Human-readable name |
| `domain_id` | VARCHAR(36) | Domain to which the channel belongs |
| `parent_group_id` | VARCHAR(36) | Optional group parent |
| `tags` | TEXT[] | Array of tags |
| `metadata` | JSONB | Free-form structured metadata |
| `created_by` | VARCHAR(254) | User that created the channel |
| `created_at` | TIMESTAMPTZ | Timestamp of creation |
| `updated_at` | TIMESTAMPTZ | Timestamp of last update |
| `updated_by` | VARCHAR(254) | User that performed last update |
| `status` | SMALLINT | 0 = enabled, 1 = disabled |
| `route` | VARCHAR(36) | Optional route identifier unique within domain if set |
### Connections Table
| Column | Type | Description |
|---------------|--------------|------------------------------------------------------|
| `channel_id` | VARCHAR(36) | Channel UUID |
| `domain_id` | VARCHAR(36) | Domain of channel and client |
| `client_id` | VARCHAR(36) | Client UUID |
| `type` | SMALLINT | Connection type: `1 = Publish`, `2 = Subscribe` |
## Deployment
The service is available as a Docker container. Refer to the Docker Compose section for the `channels` service in `docker-compose.yaml` for deployment configuration.
To build and run locally:
```bash
# download the latest version of the service
git clone https://github.com/absmach/supermq
cd supermq
# compile the channels
make channels
make install
SMQ_CHANNELS_HTTP_HOST=localhost \
SMQ_CHANNELS_HTTP_PORT=9005 \
SMQ_CHANNELS_DB_HOST=localhost \
SMQ_CHANNELS_DB_PORT=5432 \
SMQ_CHANNELS_DB_USER=supermq \
SMQ_CHANNELS_DB_PASS=supermq \
SMQ_CHANNELS_DB_NAME=channels \
$GOBIN/supermq-channels
```
### Running the Service
```bash
# Set environment variables
export MQ_CHANNELS_DB_HOST=localhost
export MQ_CHANNELS_DB_PORT=5432
# Run the service
go run cmd/main.go
```
### Docker Deployment
```bash
docker run -p 8180:8180 supermq/channels
```
## Testing
```bash
# Run unit tests
go test ./...
# Run integration tests
make test-integration
```
## Usage
The Channels service supports the following operations:
| Operation | Description |
|------------------|---------------------------------------------------------------|
| `create` | Create a new channel |
| `list` | Retrieve all channels (paged) |
| `get` | Retrieve a single channel by ID |
| `update` | Update a channels name & metadata |
| `delete` | Permanently delete a channel |
| `enable` | Enable a previously disabled channel |
| `disable` | Disable an active channel |
| `set-parent` | Assign a parent group to a channel |
| `remove-parent` | Remove parent group from a channel |
| `connect` | Connect one or more clients to channels |
| `disconnect` | Disconnect one or more clients from channels |
### Example: Create a Channel
```bash
curl -X POST http://localhost:9005/<domainID>/channels \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "myChannel",
"metadata": { "location": "lab" },
"route": "sensor-data",
"tags": ["sensor","edge"],
"status": "enabled"
}'
```
### Example: Connect Clients & Channels
```bash
curl -X POST http://localhost:9005/<domainID>/channels/connect \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"channel_ids": ["<chanID1>", "<chanID2>"],
"client_ids": ["<clientID1>", "<clientID2>"],
"types": ["publish", "subscribe"]
}'
```
### Example: Disconnect Clients from a Channel
```bash
curl -X POST http://localhost:9005/<domainID>/channels/disconnect \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"channel_ids": ["<chanID>"],
"client_ids": ["<clientID>"],
"types": ["publish"]
}'
```
## Best Practices
- Use tags and metadata to manage and categorize channels (e.g., environment, region, purpose).
- Assign `route` thoughtfully when channels need a predictable identifier.
- Keep channel hierarchies shallow for easier navigation (avoid deep nesting unless required).
- Use `disable` rather than immediate delete when you want to suspend a channel temporarily.
- Clean up unused connections: regularly review which clients are connected to channels and remove stale links.
- Enforce minimal privileges: only allow clients to connect to channels they truly need.
- Monitoring: use the `/health` endpoint and version metadata for service stability.
## Versioning & Health Check
The Channels service exposes a `/health` endpoint to provide operational status and version info.
### Health Check Request
```bash
curl -X GET http://localhost:9005/health \
-H "accept: application/health+json"
```
### Example Response
```json
{
"status": "pass",
"version": "0.18.0",
"commit": "<commit-hash>",
"description": "channels service",
"build_time": "2025-11-19T..."
}
```
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ Channels Service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+254 -5
View File
@@ -1,6 +1,6 @@
# Clients
Clients service provides an HTTP API for managing platform resources: clients and channels.
Clients service provides an HTTP API for managing platform resources: `clients` and `channels`.
Through this API clients are able to do the following actions:
- provision new clients
@@ -55,7 +55,7 @@ default values.
## Deployment
The service itself is distributed as Docker container. Check the [`clients `](https://github.com/absmach/supermq/blob/main/docker/docker-compose.yaml#L167-L194) service section in
The service itself is distributed as Docker container. Check the [`clients`](https://github.com/absmach/supermq/blob/main/docker/docker-compose.yaml#L167-L194) service section in
docker-compose file to see how service is deployed.
To start the service outside of the container, execute the following shell script:
@@ -116,7 +116,256 @@ To run service in a standalone mode, set `Clients_STANDALONE_EMAIL` and `Clients
## Usage
For more information about service capabilities and its usage, please check out
the [API documentation](https://docs.api.supermq.abstractmachines.fr/?urls.primaryName=clients-openapi.yaml).
SuperMQ supports the following operations for Clients:
[doc]: https://docs.supermq.abstractmachines.fr
| Operation | Description |
| ------------- | ------------------------------------------------------------------ |
| `create` | Create a new client |
| `get` | Retrieve a single client or list all clients |
| `update` | Update a clients name and metadata |
| `delete` | Permanently delete a client |
| `enable` | Enable a previously disabled client |
| `disable` | Disable an active client |
| `setClientParentGroup` | Add a Parent Group to a client |
| `removeClientParentGroup` | Remove a Parent Group from a client |
### API Examples
#### Create a Client
```bash
curl -X POST http://localhost:9006/<domainID>/clients \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "clientName",
"tags": [
"tag1",
"tag2"
],
"credentials": {
"identity": "clientIDentity",
"secret": "bb7edb32-2eac-4aad-aebe-ed96fe073879"
},
"metadata": {
"model": "example"
},
"status": "enabled"
}'
```
The expected response should be:
```bash
{
"id": "bb7edb32-2eac-4aad-aebe-ed96fe073879",
"name": "clientName",
"tags": [
"tag1",
"tag2"
],
"domain_id": "bb7edb32-2eac-4aad-aebe-ed96fe073879",
"credentials": {
"identity": "clientIDentity",
"secret": "bb7edb32-2eac-4aad-aebe-ed96fe073879"
},
"metadata": {
"model": "example"
},
"status": "enabled",
"created_at": "2019-11-26 13:31:52",
"updated_at": "2019-11-26 13:31:52"
}
```
#### Get Clients
List all clients:
```bash
curl -X GET "http://localhost:9006/<domainID>/clients?limit=10" \
-H "Authorization: Bearer <your_access_token>"
```
List a singular client:
```bash
curl -X GET http://localhost:9006/<domainID>/clients/<clientID> \
-H "Authorization: Bearer <your_access_token>"
```
#### Update a Client
Update is performed by replacing the current resource data with values provided in a request payload. Note that the client's type and ID cannot be changed.
```bash
curl -X PATCH http://localhost:9006/<domainID>/clients/<clientID> \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "clientName",
"metadata": {"role": "general"}
}'
```
The expected response is
```bash
{
"id": "bb7edb32-2eac-4aad-aebe-ed96fe073879",
"name": "clientName",
"tags": [
"tag1",
"tag2"
],
"domain_id": "bb7edb32-2eac-4aad-aebe-ed96fe073879",
"credentials": {
"identity": "clientIDentity",
"secret": "bb7edb32-2eac-4aad-aebe-ed96fe073879"
},
"metadata": { "model": "example" },
"status": "enabled",
"created_at": "2019-11-26 13:31:52",
"updated_at": "2019-11-26 13:31:52"
}
```
#### Delete a Client
Delete client removes a client with the given id from repo and removes all the policies related to this client.
```bash
curl -X DELETE http://localhost:9006/<domainID>/clients/<clientID> \
-H "Authorization: Bearer <your_access_token>"
```
#### Disable a Client
Disables a specific client that is identified by the client ID.
```bash
curl -X POST http://localhost:9006/<domainID>/clients/<clientID>/disable \
-H "Authorization: Bearer <your_access_token>"
```
#### Enable a Client
Enable logically enables the client identified with the provided ID
```bash
curl -X POST http://localhost:9006/<domainID>/clients/<clientID>/enable \
-H "Authorization: Bearer <your_access_token>"
```
## Roles Management for Clients
In addition to standard client lifecycle operations (create, get, update, delete, enable, disable), the Clients service supports robust rolebased operations for managing permissions and associations for each client.
### Supported Role Operations
| Operation | Description |
|------------------------------|-----------------------------------------------------------------------------|
| `create-role` | Create a new role for a client |
| `list-roles` | List all roles assigned to a client |
| `get-role` | Retrieve details for a specific client role |
| `update-role` | Update a specific client role |
| `delete-role` | Delete a specific client role |
| `add-role-action` | Add one or more actions (permissions) to a client role |
| `list-role-actions` | List all actions associated with a client role |
| `delete-role-action` | Remove a specific action from a client role |
| `delete-all-role-actions` | Remove all actions from a client role |
| `add-role-member` | Associate one or more users or entities to a client role |
| `list-role-members` | List all members of a client role |
| `delete-role-member` | Remove one or more members from a client role |
| `delete-all-role-members` | Remove all members from a client role |
| `list-available-actions` | Retrieve the global list of available actions key for role creation |
### Example: Create a Client Role
```bash
curl -X POST http://localhost:9006/<domainID>/clients/<clientID>/roles \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "publisher",
"actions": ["publish"],
"members": []
}'
```
## Implementation Details
Clients in SuperMQ are persisted in PostgreSQL using a schema optimized for identity management, authorization, and relationship tracking (channels, groups, and users).
### Clients Table Structure
The main `clients` table tracks all metadata, identity, and lifecycle information for each client:
| Column | Type | Description |
|------------------ | -------------- | --------------------------------------------------------------------------- |
| `id` | VARCHAR(36) | UUID of the client (primary key). |
| `name` | VARCHAR(1024) | Humanreadable name. |
| `domain_id` | VARCHAR(36) | Domain to which the client belongs. |
| `parent_group_id` | VARCHAR(36) | Optional group parent (for inheritance/scoping). |
| `identity` | VARCHAR(254) | Login identity (often an email or unique ID). |
| `secret` | VARCHAR(4096) | Hashed authentication secret. |
| `tags` | TEXT[] | Arbitrary list of client tags. |
| `metadata` | JSONB | Freeform structured metadata. |
| `created_at` | TIMESTAMPTZ | Timestamp when the client was created. |
| `updated_at` | TIMESTAMPTZ | Timestamp when the client was last updated. |
| `updated_by` | VARCHAR(254) | Identifier of the actor who performed the last update. |
| `status` | SMALLINT | 0 = enabled, 1 = disabled. |
#### Connections Table Structure
Client ↔ Channel relationships are stored in the `connections` table:
| Column | Type | Description |
|-------------- | ------------ | ---------------------------------------------------------------------- |
| `channel_id` | VARCHAR(36) | Channel UUID. |
| `domain_id` | VARCHAR(36) | Domain of the client & channel. |
| `client_id` | VARCHAR(36) | Client UUID. |
| `type` | SMALLINT | Connection type: `1 = Publish`, `2 = Subscribe`. |
This guarantees that when a client is deleted, all channel connections are automatically removed.
## Best Practices
To ensure robust and secure usage of the Clients service, consider the following recommendations:
- **Use metadata and tags meaningfully**: Store useful attributes like model, location, environment (e.g., `production`, `test`) to filter and manage clients efficiently.
- **Keep credentials secure**: Rotate client secrets periodically. Avoid using guessable strings.
- **Disable unused clients**: Use the `disable` operation to revoke access instead of deleting clients when deactivation is preferred.
- **Audit regularly**: Periodically list client roles and connections to ensure expected configuration.
- **Prefer standalone mode for edge deployments**: Use environment variables to configure standalone mode in isolated environments without needing the Auth service.
## Versioning and Health Check
The Clients service exposes a `/health` endpoint to verify operational status and version information.
### Health Check Request
```bash
curl -X 'GET' \
'http://localhost:9006/health' \
-H 'accept: application/health+json'
```
The expected response is:
```bash
{
"status": "pass",
"version": "0.14.0",
"commit": "7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62",
"description": "clients service",
"build_time": "1970-01-01_00:00:00"
}
```
This endpoint can be used for monitoring, CI/CD readiness checks, or basic diagnostics.
For more information about service capabilities and its usage, please check out
the [API documentation](https://docs.api.supermq.absmach.eu/?urls.primaryName=api%2Fclients.yaml).
[doc]: https://docs.supermq.absmach.eu/
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ Clients Service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+64 -24
View File
@@ -6,30 +6,30 @@ SuperMQ CoAP adapter provides an [CoAP](http://coap.technology/) API for sending
The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.
| Variable | Description | Default |
| ----------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------- |
| SMQ_COAP_ADAPTER_LOG_LEVEL | Log level for the CoAP Adapter (debug, info, warn, error) | info |
| SMQ_COAP_ADAPTER_HOST | CoAP service listening host | "" |
| SMQ_COAP_ADAPTER_PORT | CoAP service listening port | 5683 |
| SMQ_COAP_ADAPTER_SERVER_CERT | CoAP service server certificate | "" |
| SMQ_COAP_ADAPTER_SERVER_KEY | CoAP service server key | "" |
| SMQ_COAP_ADAPTER_HTTP_HOST | Service HTTP listening host | "" |
| SMQ_COAP_ADAPTER_HTTP_PORT | Service listening port | 5683 |
| SMQ_COAP_ADAPTER_HTTP_SERVER_CERT | Service server certificate | "" |
| SMQ_COAP_ADAPTER_HTTP_SERVER_KEY | Service server key | "" |
| SMQ_COAP_ADAPTER_CACHE_NUM_COUNTERS | Number of cache counters to keep that hold access frequency information | 200000 |
| SMQ_COAP_ADAPTER_CACHE_MAX_COST | Maximum size of the cache(in bytes) | 1048576 |
| SMQ_COAP_ADAPTER_CACHE_BUFFER_ITEMS | Number of cache `Get` buffers | 64 |
| SMQ_CLIENTS_GRPC_URL | Clients service Auth gRPC URL | <localhost:7000> |
| SMQ_CLIENTS_GRPC_TIMEOUT | Clients service Auth gRPC request timeout in seconds | 1s |
| SMQ_CLIENTS_GRPC_CLIENT_CERT | Path to the PEM encoded clients service Auth gRPC client certificate file | "" |
| SMQ_CLIENTS_GRPC_CLIENT_KEY | Path to the PEM encoded clients service Auth gRPC client key file | "" |
| SMQ_CLIENTS_GRPC_SERVER_CERTS | Path to the PEM encoded clients server Auth gRPC server trusted CA certificate file | "" |
| SMQ_MESSAGE_BROKER_URL | Message broker instance URL | <amqp://guest:guest@rabbitmq:5672/> |
| SMQ_JAEGER_URL | Jaeger server URL | <http://localhost:4318/v1/traces> |
| SMQ_JAEGER_TRACE_RATIO | Jaeger sampling ratio | 1.0 |
| SMQ_SEND_TELEMETRY | Send telemetry to supermq call home server | true |
| SMQ_COAP_ADAPTER_INSTANCE_ID | CoAP adapter instance ID | "" |
| Variable | Description | Default |
| ------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------- |
| `SMQ_COAP_ADAPTER_LOG_LEVEL` | Log level for the CoAP Adapter (`debug`, `info`, `warn`, `error`) | info |
| `SMQ_COAP_ADAPTER_HOST` | CoAP service listening host | "" |
| `SMQ_COAP_ADAPTER_PORT` | CoAP service listening port | 5683 |
| `SMQ_COAP_ADAPTER_SERVER_CERT` | Path to the PEM-encoded CoAP server certificate | "" |
| `SMQ_COAP_ADAPTER_SERVER_KEY` | Path to the PEM-encoded CoAP server key | "" |
| `SMQ_COAP_ADAPTER_HTTP_HOST` | Service HTTP listening host | "" |
| `SMQ_COAP_ADAPTER_HTTP_PORT` | Service HTTP listening port | 5683 |
| `SMQ_COAP_ADAPTER_HTTP_SERVER_CERT` | Path to the PEM-encoded HTTP server certificate | "" |
| `SMQ_COAP_ADAPTER_HTTP_SERVER_KEY` | Path to the PEM-encoded HTTP server key | "" |
| `SMQ_COAP_ADAPTER_CACHE_NUM_COUNTERS` | Number of cache counters that track topic parsing frequency | 200000 |
| `SMQ_COAP_ADAPTER_CACHE_MAX_COST` | Maximum cache size (bytes) | 1048576 |
| `SMQ_COAP_ADAPTER_CACHE_BUFFER_ITEMS` | Number of cache `Get` buffer items | 64 |
| `SMQ_CLIENTS_GRPC_URL` | Clients service Auth gRPC URL | <localhost:7000> |
| `SMQ_CLIENTS_GRPC_TIMEOUT` | Clients service Auth gRPC request timeout | 1s |
| `SMQ_CLIENTS_GRPC_CLIENT_CERT` | Path to the PEM-encoded clients service Auth gRPC client certificate file | "" |
| `SMQ_CLIENTS_GRPC_CLIENT_KEY` | Path to the PEM-encoded clients service Auth gRPC client key file | "" |
| `SMQ_CLIENTS_GRPC_SERVER_CERTS` | Path to the PEM-encoded clients server Auth gRPC trusted CA certificate file | "" |
| `SMQ_MESSAGE_BROKER_URL` | Message broker instance URL | <amqp://guest:guest@rabbitmq:5672/> |
| `SMQ_JAEGER_URL` | Jaeger server URL | <http://localhost:4318/v1/traces> |
| `SMQ_JAEGER_TRACE_RATIO` | Jaeger sampling ratio | 1.0 |
| `SMQ_SEND_TELEMETRY` | Send telemetry to SuperMQ call-home server | true |
| `SMQ_COAP_ADAPTER_INSTANCE_ID` | CoAP adapter instance ID | "" |
## Deployment
@@ -84,3 +84,43 @@ Setting `SMQ_CLIENTS_GRPC_CLIENT_CERT` and `SMQ_CLIENTS_GRPC_CLIENT_KEY` will en
If CoAP adapter is running locally (on default 5683 port), a valid URL would be: `coap://localhost/m/<domain_id>/c/<channel_id>/<subtopic>?auth=<client_auth_key>`.
Since CoAP protocol does not support `Authorization` header (option) and options have limited size, in order to send CoAP messages, valid `auth` value (a valid Client key) must be present in `Uri-Query` option.
## Best Practices
- Use distinct client auth keys and rotate them frequently for better security.
- Use meaningful channel IDs and subtopics so you know exactly where your messages go.
- Leverage metadata/tags in channels and clients (via clients service) to filter and manage messaging paths.
- Ensure the auth query parameter is not exposed publicly (use secure networks or DTLS if available).
- Monitor message broker load and usage patterns — CoAP traffic can burst.
- Use the /health endpoint (if exposed) to monitor service status and integrate with your observability stack.
## Versioning and Health Check
If the service exposes a /health endpoint, you can use it for monitoring and version readiness checks.
```bash
curl -X GET coap://localhost/health \
-H "accept: application/health+json"
```
The expected response is:
```bash
{
"status": "pass",
"version": "0.xx.x",
"commit": "<commithash>",
"description": "coapadapter service",
"build_time": "YYYYMMDDT…"
}
```
## CLI
SuperMQ provides a CoAP CLI for testing and interacting with the CoAP Adapter.
To learn more about this visit the [SuperMQ CoAp CLI page](https://github.com/absmach/coap-cli/tree/main).
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ COAP service.
//
// For more details about tracing instrumentation for SuperMQ messaging refer
// to the documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// to the documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+99 -11
View File
@@ -1,18 +1,106 @@
# Consumers
Consumers provide an abstraction of various `SuperMQ consumers`.
SuperMQ consumer is a generic service that can handle received messages - consume them.
The message is not necessarily a SuperMQ message - before consuming, SuperMQ message can
be transformed into any valid format that specific consumer can understand. For example,
writers are consumers that can take a SenML or JSON message and store it.
Consumers provide an abstraction for various SuperMQ consumers.
Consumers are optional services and are treated as plugins. In order to
run consumer services, core services must be up and running.
A consumer is a generic pluginstyle service that handles received messages — for example, writing them to a database, sending notifications, or transforming them. Before consuming, messages from SuperMQ can be transformed (e.g. to JSON or SenML) to match what a specific consumer expects.
This service (Notifiers) is optional — to use it, core services must be running (e.g. message broker + clients + channels etc.).
## Concepts & Consumer Types
### Consumer Interfaces
The service supports two main consumer interfaces in code:
- **BlockingConsumer** — a synchronous consumer interface. Such a consumer processes the incoming message and returns an error if something goes wrong.
- **AsyncConsumer** — an asynchronous consumer interface. The consumer receives messages and processes them asynchronously; errors can be monitored via an error channel returned by `Errors()`.
A consumer implementation may wrap message parsing or transformation logic (e.g. converting to SenML/JSON) before invoking its own consume logic.
### Message Flow
When a subscriber receives messages from the message broker:
1. Messages may be transformed (e.g. via a transformer for SenML or JSON) based on configuration.
2. The transformed message is passed to a consumer — either synchronously (BlockingConsumer) or asynchronously (AsyncConsumer).
3. The consumer handles the message (e.g. storing to DB, sending notifications, writing files, etc.).
Consumers are decoupled from core messaging logic, making them flexible and pluggable.
## Supported Consumers
The following consumer plugins are supported within the [Magistrala](https://github.com/absmach/magistrala) repository:
| Consumer | Type | Description | Link |
|----------|-------------|-------------|------|
| **SMPP** | Notifier | Sends SMS messages via SMPP | [smpp consumer](https://github.com/absmach/magistrala/tree/main/consumers/notifiers/smpp) |
| **SMTP** | Notifier | Sends email notifications via SMTP | [smtp consumer](https://github.com/absmach/magistrala/tree/main/consumers/notifiers/smtp) |
| **Postgres** | Writer | Stores messages in a PostgreSQL database | [postgres writer](https://github.com/absmach/magistrala/tree/main/consumers/writers/postgres) |
| **Timescale** | Writer | Stores messages in TimescaleDB (optimized for time-series) | [timescale writer](https://github.com/absmach/magistrala/tree/main/consumers/writers/timescale) |
> Each consumer has its own README with deployment instructions, configuration, and usage examples.
## Notifier API (for Notifications)
The Notifiers service exposes an HTTP API to manage subscriptions and send notifications when messages are consumed. The API supports:
- Creating subscriptions
- Listing and filtering subscriptions
- Viewing a subscription by ID
- Deleting a subscription
### Available Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/subscriptions` | POST | Create a new subscription (topic + contact) |
| `/subscriptions` | GET | List subscriptions (with optional filters) |
| `/subscriptions/{id}` | GET | Retrieve a specific subscription by ID |
| `/subscriptions/{id}` | DELETE | Remove a subscription |
### Example: Create Subscription
```bash
curl -X POST http://localhost:9014/subscriptions \
-H "Authorization: Bearer <user_access_token>" \
-H "Content-Type: application/json" \
-d '{
"topic": "some.topic.subtopic",
"contact": "user@example.com"
}'
```
For more information about service capabilities and its usage, please check out the [API documentation](https://docs.api.magistrala.absmach.eu/?urls.primaryName=api%2Fnotifiers.yaml).
## Best Practices
- **Use async consumers** when message processing is long or non-blocking (e.g. writing to external APIs).
- **Always read from error channels** in async consumers to avoid silent failures.
- **Use message transformers** to adapt data format (SenML or JSON) to consumer needs.
- **Configure each consumer independently**, allowing clear isolation and debugging.
- **Monitor subscription usage** and prune stale entries regularly.
## Versioning & Health Check
If the consumer exposes a `/health` endpoint, use it for service monitoring.
```bash
curl -X GET http://localhost:<port>/health \
-H "accept: application/health+json"
```
Example response:
```bash
{
"status": "pass",
"version": "0.15.1",
"description": "notifiers service",
"build_time": "YYYYMMDDTHH:MM:SSZ"
}
```
For an in-depth explanation of the usage of `consumers`, as well as thorough
understanding of SuperMQ, please check out the [official documentation][doc].
For more information about service capabilities and its usage, please check out
the [API documentation](https://docs.api.supermq.abstractmachines.fr/?urls.primaryName=consumers-notifiers-openapi.yaml).
[doc]: https://docs.supermq.abstractmachines.fr
[doc]: https://docs.supermq.absmach.eu/
+1 -1
View File
@@ -3,5 +3,5 @@
// Package supermq acts as an umbrella package containing multiple different
// microservices and defines all shared domain concepts.
// For detailed documentation of the platform, please visit https://docs.supermq.abstractmachines.fr.
// For detailed documentation of the platform, please visit https://docs.supermq.absmach.eu.
package supermq
+65 -24
View File
@@ -2,11 +2,11 @@
Configure environment variables and run SuperMQ Docker Composition.
\*Note\*\*: `docker-compose` uses `.env` file to set all environment variables. Ensure that you run the command from the same location as .env file.
> \*Note\*\*: `docker-compose` uses `.env` file to set all environment variables. Ensure that you run the command from the same location as .env file.
## Installation
Follow the [official documentation](https://docs.docker.com/compose/install/).
Follow the [official Docker Compose installation guide](https://docs.docker.com/compose/install/) to install Docker Compose.
## Usage
@@ -16,6 +16,8 @@ Run the following commands from the project root directory.
docker compose -f docker/docker-compose.yaml up
```
To start additional addon services:
```bash
docker compose -f docker/addons/<path>/docker-compose.yaml up
```
@@ -26,33 +28,37 @@ To pull docker images from a specific release you need to change the value of `S
SuperMQ supports configurable MQTT broker and Message broker, which also acts as an events store. SuperMQ uses two types of brokers:
1. MQTT_BROKER: Handles MQTT communication between MQTT adapters and message broker. This can either be 'RabbitMQ' or 'NATS'.
2. MESSAGE_BROKER: Manages message exchange between SuperMQ core, optional, and external services. This can either be 'NATS' or 'RabbitMQ'. This is used to store messages for distributed processing.
1. **MQTT_BROKER**: Handles MQTT communication between MQTT adapters and message broker. This can either be `RabbitMQ` or `NATS`.
2. **MESSAGE_BROKER**: Manages message exchange between SuperMQ core, optional, and external services. This can either be `NATS` or `RabbitMQ`. This is used to store messages for distributed processing.
Events store: This is used by SuperMQ services to store events for distributed processing. SuperMQ uses a single service to be the message broker and events store. This can either be 'NATS' or 'RabbitMQ'. Redis can also be used as an events store, but it requires a message broker to be deployed along with it for message exchange.
Events store: This is used by SuperMQ services to store events for distributed processing. SuperMQ uses a single service to be the message broker and events store. This can either be `NATS` or `RabbitMQ`. Redis can also be used as an events store, but it requires a message broker to be deployed along with it for message exchange.
This is the same as MESSAGE_BROKER. This can either be 'NATS' or 'RabbitMQ' or 'Redis'. If Redis is used as an events store, then RabbitMQ or NATS is used as a message broker.
## Supported Combinations
This is the same as MESSAGE_BROKER. This can either be `NATS` or `RabbitMQ` or `Redis`. If Redis is used as an events store, then RabbitMQ or NATS is used as a message broker.
The current deployment strategy for SuperMQ in `docker/docker-compose.yaml` is to use RabbitMQ as a MQTT_BROKER and NATS as a MESSAGE_BROKER and EVENTS_STORE.
Therefore, the following combinations are possible:
Depending on the desired setup, the following broker configurations are valid:
- MQTT_BROKER: RabbitMQ, MESSAGE_BROKER: NATS, EVENTS_STORE: NATS
- MQTT_BROKER: RabbitMQ, MESSAGE_BROKER: NATS, EVENTS_STORE: Redis
- MQTT_BROKER: RabbitMQ, MESSAGE_BROKER: RabbitMQ, EVENTS_STORE: RabbitMQ
- MQTT_BROKER: RabbitMQ, MESSAGE_BROKER: RabbitMQ, EVENTS_STORE: Redis
- MQTT_BROKER: NATS, MESSAGE_BROKER: RabbitMQ, EVENTS_STORE: RabbitMQ
- MQTT_BROKER: NATS, MESSAGE_BROKER: RabbitMQ, EVENTS_STORE: Redis
- MQTT_BROKER: NATS, MESSAGE_BROKER: NATS, EVENTS_STORE: NATS
- MQTT_BROKER: NATS, MESSAGE_BROKER: NATS, EVENTS_STORE: Redis
- `MQTT_BROKER: RabbitMQ`, `MESSAGE_BROKER: NATS`, `EVENTS_STORE: NATS`
- `MQTT_BROKER: RabbitMQ`, `MESSAGE_BROKER: NATS`, `EVENTS_STORE: Redis`
- `MQTT_BROKER: RabbitMQ`, `MESSAGE_BROKER: RabbitMQ`, `EVENTS_STORE: RabbitMQ`
- `MQTT_BROKER: RabbitMQ`, `MESSAGE_BROKER: RabbitMQ`, `EVENTS_STORE: Redis`
- `MQTT_BROKER: NATS`, `MESSAGE_BROKER: RabbitMQ`, `EVENTS_STORE: RabbitMQ`
- `MQTT_BROKER: NATS`, `MESSAGE_BROKER: RabbitMQ`, `EVENTS_STORE: Redis`
- `MQTT_BROKER: NATS`, `MESSAGE_BROKER: NATS`, `EVENTS_STORE: NATS`
- `MQTT_BROKER: NATS`, `MESSAGE_BROKER: NATS`, `EVENTS_STORE: Redis`
For Message brokers other than NATS, you would need to build the docker images with RabbitMQ as the build tag and change the `docker/.env`. For example, to use RabbitMQ as a message broker:
> For non-default brokers (e.g. RabbitMQ as message broker), adjust the environment variables appropriately and rebuild Docker images. Example:
```bash
SMQ_MESSAGE_BROKER_TYPE=msg_rabbitmq make dockers
```
```env
Then in `.env`:
```text
SMQ_MESSAGE_BROKER_TYPE=msg_rabbitmq
SMQ_MESSAGE_BROKER_URL=${SMQ_RABBITMQ_URL}
```
@@ -84,7 +90,7 @@ SMQ_MQTT_ADAPTER_WS_TARGET_PORT=8080
SMQ_MQTT_ADAPTER_WS_TARGET_PATH=${SMQ_NATS_WS_TARGET_PATH}
```
### RabbitMQ configuration
### RabbitMQ configuration (as MQTT broker or MESSAGE_BROKER)
```yaml
services:
@@ -104,7 +110,7 @@ services:
- supermq-base-net
```
### Redis configuration
### Redis configuration (as events store)
```yaml
services:
@@ -123,12 +129,47 @@ services:
Nginx is the entry point for all traffic to SuperMQ.
By using environment variables file at `docker/.env` you can modify the below given Nginx directive.
`SMQ_NGINX_SERVER_NAME` environmental variable is used to configure nginx directive `server_name`. If environmental variable `SMQ_NGINX_SERVER_NAME` is empty then default value `localhost` will set to `server_name`.
| Environment Variable | Description |
|----------------------|-------------|
| `SMQ_NGINX_SERVER_NAME` | `SMQ_NGINX_SERVER_NAME` environmental variable is used to configure nginx directive `server_name`. If environmental variable `SMQ_NGINX_SERVER_NAME` is empty then default value `localhost` will set to `server_name`. |
| `SMQ_NGINX_SERVER_CERT` | `SMQ_NGINX_SERVER_CERT` environmental variable is used to configure nginx directive `ssl_certificate`. If environmental variable `SMQ_NGINX_SERVER_CERT` is empty then by default server certificate in the path `docker/ssl/certs/supermq-server.crt` will be assigned. |
| `SMQ_NGINX_SERVER_KEY` | `SMQ_NGINX_SERVER_KEY` environmental variable is used to configure nginx directive `ssl_certificate_key`. If environmental variable `SMQ_NGINX_SERVER_KEY` is empty then by default server certificate key in the path `docker/ssl/certs/supermq-server.key` will be assigned. |
| `SMQ_NGINX_SERVER_CLIENT_CA` | `SMQ_NGINX_SERVER_CLIENT_CA` environmental variable is used to configure nginx directive `ssl_client_certificate`. If environmental variable `SMQ_NGINX_SERVER_CLIENT_CA` is empty then by default certificate in the path `docker/ssl/certs/ca.crt` will be assigned. |
| `SMQ_NGINX_SERVER_DHPARAM` | `SMQ_NGINX_SERVER_DHPARAM` environmental variable is used to configure nginx directive `ssl_dhparam`. If environmental variable `SMQ_NGINX_SERVER_DHPARAM` is empty then by default file in the path `docker/ssl/dhparam.pem` will be assigned. |
`SMQ_NGINX_SERVER_CERT` environmental variable is used to configure nginx directive `ssl_certificate`. If environmental variable `SMQ_NGINX_SERVER_CERT` is empty then by default server certificate in the path `docker/ssl/certs/supermq-server.crt` will be assigned.
Adjust these values in `.env` to configure TLS / SSL behavior for your deployment.
`SMQ_NGINX_SERVER_KEY` environmental variable is used to configure nginx directive `ssl_certificate_key`. If environmental variable `SMQ_NGINX_SERVER_KEY` is empty then by default server certificate key in the path `docker/ssl/certs/supermq-server.key` will be assigned.
## Makefile Integration
`SMQ_NGINX_SERVER_CLIENT_CA` environmental variable is used to configure nginx directive `ssl_client_certificate`. If environmental variable `SMQ_NGINX_SERVER_CLIENT_CA` is empty then by default certificate in the path `docker/ssl/certs/ca.crt` will be assigned.
The included `Makefile` defines build and Dockerbuild targets for all SuperMQ services. Key points:
`SMQ_NGINX_SERVER_DHPARAM` environmental variable is used to configure nginx directive `ssl_dhparam`. If environmental variable `SMQ_NGINX_SERVER_DHPARAM` is empty then by default file in the path `docker/ssl/dhparam.pem` will be assigned.
- `SERVICES`: list of core services (auth, clients, channels, http, coap, mqtt, ws, etc.)
- `DOCKERS`, `DOCKERS_DEV`: build targets for production and development Docker images
- Build arguments embed version, commit hash, and build timestamp into the binary
Build all services:
```bash
make all # builds all services
make dockers # builds all Docker images
```
Start services with Docker compose:
```bash
docker compose -f docker/docker-compose.yaml up
```
To clean up:
```bash
make cleandocker
```
To run tests(unit tests + API tests)
```bash
make test
```
+428
View File
@@ -0,0 +1,428 @@
# Domains
The Domains service provides an HTTP API for managing platform domains in SuperMQ. Through this API you can create, list, retrieve, update, enable/disable/freeze domains, manage roles & invitations associated with domains, and more.
For more background on SuperMQ concepts, see the [official documentation][doc].
## Configuration
The service is configured through environment variables (unset variables fall back to defaults).
| Variable | Description | Default |
| ------------------------------------ | -------------------------------------------------------------------------------------------- | ------------------------------------- |
| `SMQ_DOMAINS_LOG_LEVEL` | Log level for Domains (debug, info, warn, error) | debug |
| `SMQ_DOMAINS_HTTP_HOST` | Domains service HTTP host | domains |
| `SMQ_DOMAINS_HTTP_PORT` | Domains service HTTP port | 9003 |
| `SMQ_DOMAINS_HTTP_SERVER_CERT` | Path to PEM-encoded HTTP server certificate | "" |
| `SMQ_DOMAINS_HTTP_SERVER_KEY` | Path to PEM-encoded HTTP server key | "" |
| `SMQ_DOMAINS_GRPC_PORT` | Domains service gRPC port | 7003 |
| `SMQ_DOMAINS_GRPC_SERVER_CERT` | Path to PEM-encoded gRPC server certificate | "" |
| `SMQ_DOMAINS_GRPC_SERVER_KEY` | Path to PEM-encoded gRPC server key | "" |
| `SMQ_DOMAINS_GRPC_SERVER_CA_CERTS` | Path to trusted CA bundle for the gRPC server | "" |
| `SMQ_DOMAINS_GRPC_CLIENT_CA_CERTS` | Path to client CA bundle to require gRPC mTLS | "" |
| `SMQ_DOMAINS_DB_HOST` | Database host address | domains-db |
| `SMQ_DOMAINS_DB_PORT` | Database host port | 5432 |
| `SMQ_DOMAINS_DB_USER` | Database user | supermq |
| `SMQ_DOMAINS_DB_PASS` | Database password | supermq |
| `SMQ_DOMAINS_DB_NAME` | Name of the database used by the service | domains |
| `SMQ_DOMAINS_DB_SSL_MODE` | Database connection SSL mode (disable, require, verify-ca, verify-full) | "" |
| `SMQ_DOMAINS_DB_SSL_CERT` | Path to the PEM-encoded certificate file | "" |
| `SMQ_DOMAINS_DB_SSL_KEY` | Path to the PEM-encoded key file | "" |
| `SMQ_DOMAINS_DB_SSL_ROOT_CERT` | Path to the PEM-encoded root certificate file | "" |
| `SMQ_DOMAINS_CACHE_URL` | Cache database URL | redis://domains-redis:6379/0 |
| `SMQ_DOMAINS_CACHE_KEY_DURATION` | Cache key duration for domain status/route lookups | 10m |
| `SMQ_DOMAINS_INSTANCE_ID` | Domains instance ID (auto-generated when empty) | "" |
| `SMQ_SPICEDB_HOST` | SpiceDB host for policy checks | supermq-spicedb |
| `SMQ_SPICEDB_PORT` | SpiceDB port | 50051 |
| `SMQ_SPICEDB_SCHEMA_FILE` | Path to SpiceDB schema file used to seed available actions | ./docker/spicedb/schema.schema.zed |
| `SMQ_SPICEDB_PRE_SHARED_KEY` | SpiceDB preshared key | 12345678 |
| `SMQ_ES_URL` | Event store URL | nats://localhost:4222 |
| `SMQ_JAEGER_URL` | Jaeger server URL | <http://localhost:4318/v1/traces> |
| `SMQ_JAEGER_TRACE_RATIO` | Trace sampling ratio | 1.0 |
| `SMQ_SEND_TELEMETRY` | Send telemetry to the SuperMQ call-home server | true |
| `SMQ_AUTH_GRPC_URL` | Auth service gRPC URL | "" |
| `SMQ_AUTH_GRPC_TIMEOUT` | Auth service gRPC request timeout | 1s |
| `SMQ_AUTH_GRPC_CLIENT_CERT` | Path to the PEM-encoded Auth gRPC client certificate | "" |
| `SMQ_AUTH_GRPC_CLIENT_KEY` | Path to the PEM-encoded Auth gRPC client key | "" |
| `SMQ_AUTH_GRPC_SERVER_CA_CERTS` | Path to the PEM-encoded Auth gRPC trusted CA bundle | "" |
| `SMQ_DOMAINS_CALLOUT_URLS` | Comma-separated list of HTTP callout targets invoked on domain operations | "" |
| `SMQ_DOMAINS_CALLOUT_METHOD` | HTTP method for callouts (POST or GET) | POST |
| `SMQ_DOMAINS_CALLOUT_TLS_VERIFICATION` | Verify TLS certificates for callouts | true |
| `SMQ_DOMAINS_CALLOUT_TIMEOUT` | Callout request timeout | 10s |
| `SMQ_DOMAINS_CALLOUT_KEY` | Client key for mTLS callouts | "" |
| `SMQ_DOMAINS_CALLOUT_OPERATIONS` | Comma-separated list of operation names that should trigger callouts | "" |
**Note**: Set `SMQ_DOMAINS_CALLOUT_OPERATIONS` to a subset of `OpCreateDomain`, `OpRetrieveDomain`, `OpUpdateDomain`, `OpEnableDomain`, `OpDisableDomain`, `OpFreezeDomain`, `OpListDomains`, `OpViewDomainInvitation`, `OpSendInvitation`, `OpAcceptInvitation`, `OpListInvitations`, `OpListDomainInvitations`, `OpRejectInvitation`, or `OpDeleteInvitation` to filter which actions produce callouts.
## Deployment
The service is distributed as a Docker container. See the [`domains` section](https://github.com/absmach/supermq/blob/main/docker/docker-compose.yaml#L215-L310) of the compose file for an example deployment.
To run the service outside of a container:
```bash
# download the latest version of the service
git clone https://github.com/absmach/supermq
cd supermq
# compile the domains service
make domains
# copy binary to $GOBIN
make install
# set the environment variables and run the service
SMQ_DOMAINS_LOG_LEVEL=debug \
SMQ_DOMAINS_CACHE_URL=redis://domains-redis:6379/0 \
SMQ_DOMAINS_CACHE_KEY_DURATION=10m \
SMQ_DOMAINS_HTTP_HOST=domains \
SMQ_DOMAINS_HTTP_PORT=9003 \
SMQ_DOMAINS_HTTP_SERVER_CERT="" \
SMQ_DOMAINS_HTTP_SERVER_KEY="" \
SMQ_DOMAINS_GRPC_HOST=domains \
SMQ_DOMAINS_GRPC_PORT=7003 \
SMQ_DOMAINS_GRPC_SERVER_CERT="" \
SMQ_DOMAINS_GRPC_SERVER_KEY="" \
SMQ_DOMAINS_GRPC_SERVER_CA_CERTS="" \
SMQ_DOMAINS_GRPC_CLIENT_CA_CERTS="" \
SMQ_DOMAINS_DB_HOST=domains-db \
SMQ_DOMAINS_DB_PORT=5432 \
SMQ_DOMAINS_DB_USER=supermq \
SMQ_DOMAINS_DB_PASS=supermq \
SMQ_DOMAINS_DB_NAME=domains \
SMQ_DOMAINS_DB_SSL_MODE="" \
SMQ_DOMAINS_DB_SSL_CERT="" \
SMQ_DOMAINS_DB_SSL_KEY="" \
SMQ_DOMAINS_DB_SSL_ROOT_CERT="" \
SMQ_AUTH_GRPC_URL="" \
SMQ_AUTH_GRPC_TIMEOUT=1s \
SMQ_AUTH_GRPC_CLIENT_CERT="" \
SMQ_AUTH_GRPC_CLIENT_KEY="" \
SMQ_AUTH_GRPC_SERVER_CA_CERTS="" \
SMQ_SPICEDB_HOST=localhost \
SMQ_SPICEDB_PORT=50051 \
SMQ_SPICEDB_SCHEMA_FILE=./docker/spicedb/schema.schema.zed \
SMQ_SPICEDB_PRE_SHARED_KEY=12345678 \
SMQ_ES_URL=nats://localhost:4222 \
SMQ_JAEGER_URL=<http://localhost:4318/v1/traces> \
SMQ_JAEGER_TRACE_RATIO=1.0 \
SMQ_DOMAINS_CALLOUT_URLS="" \
SMQ_DOMAINS_CALLOUT_METHOD=POST \
SMQ_DOMAINS_CALLOUT_TLS_VERIFICATION=true \
SMQ_DOMAINS_CALLOUT_TIMEOUT=10s \
SMQ_DOMAINS_CALLOUT_KEY="" \
SMQ_DOMAINS_CALLOUT_OPERATIONS="" \
SMQ_SEND_TELEMETRY=true \
SMQ_DOMAINS_INSTANCE_ID="" \
$GOBIN/supermq-domains
```
## Usage
Domains supports the following operations:
| Operation | Description |
| -------------------- | ------------------------------------------------------------------------------------- |
| `create` | Create a new domain with a unique route |
| `get` | Retrieve a domain (optionally with role memberships) or list accessible domains |
| `update` | Update a domains name, tags, or metadata |
| `enable` | Enable a previously disabled domain |
| `disable` | Disable an active domain |
| `freeze` | Freeze a domain (platform administrators only) |
| `invite` | Send an invitation for a user to join a domain with a specific role |
| `invitations` | List invitations for the current user or for a specific domain |
| `accept/reject` | Accept or reject a pending domain invitation |
| `delete-invitation` | Delete an invitation (inviter, invitee, or admin) |
| `roles` | Create/list/update/delete domain roles; manage role actions and members; list actions |
### API Examples
#### Create a Domain
```bash
curl -X POST http://localhost:9004/domains \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Edge Tenant",
"route": "edge",
"tags": ["iot", "prod"],
"metadata": { "region": "eu-west-1" }
}'
```
Expected response:
```json
{
"id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
"name": "Edge Tenant",
"tags": ["iot", "prod"],
"route": "edge",
"metadata": { "region": "eu-west-1" },
"status": "enabled",
"created_by": "a5b6c7d8-e901-4fab-9bcd-123456789abc",
"created_at": "2024-10-24T13:31:52Z"
}
```
#### List Domains
```bash
curl -X GET "http://localhost:9004/domains?limit=10&status=enabled" \
-H "Authorization: Bearer <your_access_token>"
```
```json
{
"total": 2,
"offset": 0,
"limit": 10,
"domains": [
{
"id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
"name": "Edge Tenant",
"route": "edge",
"status": "enabled",
"created_at": "2024-10-24T13:31:52Z"
},
{
"id": "7f6a5b4c-3210-4fed-ba98-76543210fedc",
"name": "Sandbox",
"route": "sandbox",
"status": "disabled",
"created_at": "2024-10-10T08:12:04Z"
}
]
}
```
#### Retrieve a Domain (with Roles)
```bash
curl -X GET "http://localhost:9004/domains/<domainID>?roles=true" \
-H "Authorization: Bearer <your_access_token>"
```
```json
{
"id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
"name": "Edge Tenant",
"route": "edge",
"status": "enabled",
"roles": [
{
"role_id": "b83d25e7-6a49-4c2e-98c5-9323d4d9af7d",
"role_name": "admin",
"actions": ["manage_role_permission", "update_permission", "add_role_users_permission"]
}
],
"created_at": "2024-10-24T13:31:52Z",
"updated_at": "2024-10-24T13:31:52Z"
}
```
#### Update a Domain
```bash
curl -X PATCH http://localhost:9004/domains/<domainID> \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Edge Operations",
"tags": ["iot", "ops"],
"metadata": { "region": "eu-west-1", "env": "prod" }
}'
```
#### Enable, Disable, or Freeze a Domain
```bash
curl -X POST http://localhost:9004/domains/<domainID>/disable \
-H "Authorization: Bearer <your_access_token>"
curl -X POST http://localhost:9004/domains/<domainID>/enable \
-H "Authorization: Bearer <your_access_token>"
curl -X POST http://localhost:9004/domains/<domainID>/freeze \
-H "Authorization: Bearer <your_access_token>"
```
#### Send an Invitation
```bash
curl -X POST http://localhost:9004/domains/<domainID>/invitations \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"invitee_user_id": "<userID>",
"role_id": "<roleID>",
"resend": false
}'
```
#### List Domain or User Invitations
```bash
# For a specific domain
curl -X GET "http://localhost:9004/domains/<domainID>/invitations?limit=10&state=pending" \
-H "Authorization: Bearer <your_access_token>"
# For the current user
curl -X GET "http://localhost:9004/invitations?limit=10" \
-H "Authorization: Bearer <your_access_token>"
```
```json
{
"total": 1,
"offset": 0,
"limit": 10,
"invitations": [
{
"invited_by": "a5b6c7d8-e901-4fab-9bcd-123456789abc",
"invitee_user_id": "2c4d6e8f-0a12-4b3c-9d8e-7f6a5b4c3d2e",
"domain_id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
"domain_name": "Edge Tenant",
"role_id": "b83d25e7-6a49-4c2e-98c5-9323d4d9af7d",
"role_name": "admin",
"actions": ["manage_role_permission", "update_permission"],
"created_at": "2024-10-25T11:03:42Z"
}
]
}
```
#### Accept, Reject, or Delete an Invitation
```bash
# Accept
curl -X POST http://localhost:9004/invitations/accept \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{ "domain_id": "<domainID>" }'
# Reject
curl -X POST http://localhost:9004/invitations/reject \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{ "domain_id": "<domainID>" }'
# Delete
curl -X DELETE http://localhost:9004/domains/<domainID>/invitations \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{ "user_id": "<inviteeUserID>" }'
```
## Roles Management for Domains
Domain roles reuse the shared role manager. Supported operations:
| Operation | Description |
| -------------------------- | ----------------------------------------------------------------------- |
| `create-role` | Create a new role for a domain |
| `list-roles` | List all roles assigned to a domain |
| `get-role` | Retrieve details for a specific domain role |
| `update-role` | Update a domain role name |
| `delete-role` | Delete a domain role |
| `add-role-action` | Add one or more actions to a domain role |
| `list-role-actions` | List all actions associated with a domain role |
| `delete-role-action` | Remove a specific action from a domain role |
| `delete-all-role-actions` | Remove all actions from a domain role |
| `add-role-member` | Associate one or more members with a domain role |
| `list-role-members` | List all members of a domain role |
| `delete-role-member` | Remove one or more members from a domain role |
| `delete-all-role-members` | Remove all members from a domain role |
| `list-available-actions` | Retrieve the global list of available domain actions from the schema |
Example: create a domain role
```bash
curl -X POST http://localhost:9004/domains/<domainID>/roles \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"role_name": "domain-editor",
"optional_actions": ["update_permission", "read_permission"],
"optional_members": ["<userID>"]
}'
```
To discover allowed actions before creating roles, call:
```bash
curl -X GET http://localhost:9004/domains/roles/available-actions \
-H "Authorization: Bearer <your_access_token>"
```
## Implementation Details
- Domains and invitations are persisted in PostgreSQL; migrations also create role tables with a `domains_` prefix.
- Redis caches domain status and route-to-ID lookups to speed up authorization.
- Domain lifecycle events are published to the configured event store (`SMQ_ES_URL`).
- Authorization and role checks are enforced via SpiceDB-backed policy service.
- Optional HTTP callouts can be triggered before operations, using the `SMQ_DOMAINS_CALLOUT_*` settings.
- Observability: Jaeger tracing, Prometheus metrics at `/metrics`, and a `/health` endpoint.
### Domains Table
| Column | Type | Description |
| ----------- | ------------- | ------------------------------------------------------------ |
| `id` | VARCHAR(36) | UUID of the domain (primary key) |
| `name` | VARCHAR(254) | Human-readable domain name |
| `tags` | TEXT[] | Domain tags |
| `metadata` | JSONB | Arbitrary metadata |
| `route` | VARCHAR(254) | Unique domain route/alias |
| `created_at`| TIMESTAMPTZ | Creation timestamp |
| `updated_at`| TIMESTAMPTZ | Last update timestamp |
| `updated_by`| VARCHAR(254) | Actor who last updated the domain |
| `created_by`| VARCHAR(254) | Actor who created the domain |
| `status` | SMALLINT | 0 = enabled, 1 = disabled, 2 = freezed, 3 = deleted |
### Invitations Table
| Column | Type | Description |
| ----------------- | ----------- | --------------------------------------------------- |
| `invited_by` | VARCHAR(36) | User who sent the invitation |
| `invitee_user_id` | VARCHAR(36) | User being invited |
| `domain_id` | VARCHAR(36) | Domain to join (FK to `domains.id`) |
| `role_id` | VARCHAR(36) | Role to grant on acceptance |
| `created_at` | TIMESTAMPTZ | Invitation creation time |
| `updated_at` | TIMESTAMPTZ | Last modification time |
| `confirmed_at` | TIMESTAMPTZ | When the invitation was accepted (if applicable) |
| `rejected_at` | TIMESTAMPTZ | When the invitation was rejected (if applicable) |
## Best Practices
- Reserve concise, DNS-friendly `route` values for external-facing domains.
- Use metadata and tags to capture environment, region, and ownership for filtering.
- Prefer `disable` over delete when you need reversible off-boarding; use `freeze` for emergency locks by admins.
- Keep role definitions minimal; grant only the actions needed and audit with `list-role-members`.
- Clean up stale invitations regularly using the domain/user invitation listing endpoints.
- When enabling callouts, narrow `SMQ_DOMAINS_CALLOUT_OPERATIONS` to the events you must observe.
## Versioning and Health Check
The Domains service exposes `/health` with status and build metadata.
```bash
curl -X GET http://localhost:9004/health \
-H "accept: application/health+json"
```
Example response:
```json
{
"status": "pass",
"version": "0.18.0",
"commit": "7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62",
"description": "domains service",
"build_time": "1970-01-01_00:00:00"
}
```
For full API coverage, see the [Domains API documentation](https://docs.api.supermq.absmach.eu/?urls.primaryName=api%2Fdomains.yaml).
[doc]: https://docs.supermq.absmach.eu/
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ Domains service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+309
View File
@@ -0,0 +1,309 @@
# Groups
The Groups service exposes HTTP and gRPC APIs for organizing entities into hierarchical groups within a domain, managing membership, permissions, and roles. It handles group lifecycle (create/update/enable/disable/delete), parent/child relationships, listings (flat or tree), and role-based access.
For a deeper overview of SuperMQ, see the [official documentation][doc].
## Configuration
The service is configured via environment variables (unset values fall back to defaults).
| Variable | Description | Default |
| -------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------- |
| `SMQ_GROUPS_LOG_LEVEL` | Log level for Groups (debug, info, warn, error) | debug |
| `SMQ_GROUPS_HTTP_HOST` | Groups service HTTP host | groups |
| `SMQ_GROUPS_HTTP_PORT` | Groups service HTTP port | 9004 |
| `SMQ_GROUPS_HTTP_SERVER_CERT` | Path to PEM-encoded HTTP server certificate | "" |
| `SMQ_GROUPS_HTTP_SERVER_KEY` | Path to PEM-encoded HTTP server key | "" |
| `SMQ_GROUPS_HTTP_SERVER_CA_CERTS` | Path to trusted CA bundle for the HTTP server | "" |
| `SMQ_GROUPS_HTTP_CLIENT_CA_CERTS` | Path to client CA bundle to require HTTP mTLS | "" |
| `SMQ_GROUPS_GRPC_HOST` | Groups service gRPC host | groups |
| `SMQ_GROUPS_GRPC_PORT` | Groups service gRPC port | 7004 |
| `SMQ_GROUPS_GRPC_SERVER_CERT` | Path to PEM-encoded gRPC server certificate | "" |
| `SMQ_GROUPS_GRPC_SERVER_KEY` | Path to PEM-encoded gRPC server key | "" |
| `SMQ_GROUPS_GRPC_SERVER_CA_CERTS` | Path to trusted CA bundle for the gRPC server | "" |
| `SMQ_GROUPS_GRPC_CLIENT_CA_CERTS` | Path to client CA bundle to require gRPC mTLS | "" |
| `SMQ_GROUPS_DB_HOST` | Database host address | groups-db |
| `SMQ_GROUPS_DB_PORT` | Database host port | 5432 |
| `SMQ_GROUPS_DB_USER` | Database user | supermq |
| `SMQ_GROUPS_DB_PASS` | Database password | supermq |
| `SMQ_GROUPS_DB_NAME` | Name of the database used by the service | groups |
| `SMQ_GROUPS_DB_SSL_MODE` | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| `SMQ_GROUPS_DB_SSL_CERT` | Path to the PEM-encoded certificate file | "" |
| `SMQ_GROUPS_DB_SSL_KEY` | Path to the PEM-encoded key file | "" |
| `SMQ_GROUPS_DB_SSL_ROOT_CERT` | Path to the PEM-encoded root certificate file | "" |
| `SMQ_GROUPS_INSTANCE_ID` | Groups instance ID (auto-generated when empty) | "" |
| `SMQ_GROUPS_EVENT_CONSUMER` | NATS consumer name for domain events | groups |
| `SMQ_SPICEDB_HOST` | SpiceDB host for policy checks | supermq-spicedb |
| `SMQ_SPICEDB_PORT` | SpiceDB port | 50051 |
| `SMQ_SPICEDB_SCHEMA_FILE` | Path to SpiceDB schema file used to seed available actions | "/schema.zed" |
| `SMQ_SPICEDB_PRE_SHARED_KEY` | SpiceDB preshared key | 12345678 |
| `SMQ_ES_URL` | Event store URL | nats://nats:4222 |
| `SMQ_JAEGER_URL` | Jaeger server URL | <http://jaeger:4318/v1/traces> |
| `SMQ_JAEGER_TRACE_RATIO` | Trace sampling ratio | 1.0 |
| `SMQ_SEND_TELEMETRY` | Send telemetry to the SuperMQ call-home server | true |
| `SMQ_AUTH_GRPC_URL` | Auth service gRPC URL | "" |
| `SMQ_AUTH_GRPC_TIMEOUT` | Auth service gRPC request timeout | 1s |
| `SMQ_AUTH_GRPC_CLIENT_CERT` | Path to the PEM-encoded Auth gRPC client certificate | "" |
| `SMQ_AUTH_GRPC_CLIENT_KEY` | Path to the PEM-encoded Auth gRPC client key | "" |
| `SMQ_AUTH_GRPC_SERVER_CA_CERTS` | Path to the PEM-encoded Auth gRPC trusted CA bundle | "" |
| `SMQ_GROUPS_CALLOUT_URLS` | Comma-separated list of HTTP callout targets invoked on group operations | "" |
| `SMQ_GROUPS_CALLOUT_METHOD` | HTTP method for callouts (POST or GET) | POST |
| `SMQ_GROUPS_CALLOUT_TLS_VERIFICATION` | Verify TLS certificates for callouts | false |
| `SMQ_GROUPS_CALLOUT_TIMEOUT` | Callout request timeout | 10s |
| `SMQ_GROUPS_CALLOUT_CA_CERT` | CA bundle for verifying callout targets | "" |
| `SMQ_GROUPS_CALLOUT_CERT` | Client certificate for mTLS callouts | "" |
| `SMQ_GROUPS_CALLOUT_KEY` | Client key for mTLS callouts | "" |
| `SMQ_GROUPS_CALLOUT_OPERATIONS` | Comma-separated list of operation names that should trigger callouts | "" |
**Note**: Set `SMQ_GROUPS_CALLOUT_OPERATIONS` to a subset of `OpCreateGroup`, `OpViewGroup`, `OpUpdateGroup`, `OpEnableGroup`, `OpDisableGroup`, `OpDeleteGroup`, `OpListGroups`, `OpHierarchy`, `OpAddParentGroup`, `OpRemoveParentGroup`, `OpAddChildrenGroups`, `OpRemoveChildrenGroups`, `OpRemoveAllChildrenGroups`, or `OpListChildrenGroups` to filter which actions produce callouts.
## Deployment
The service ships as a Docker container. See the [`groups` section](https://github.com/absmach/supermq/blob/main/docker/docker-compose.yaml#L950-L1035) in `docker-compose.yaml` for deployment configuration.
To build and run locally:
```bash
# download the latest version of the service
git clone https://github.com/absmach/supermq
cd supermq
# compile the groups service
make groups
# copy binary to $GOBIN
make install
# set the environment variables and run the service
SMQ_GROUPS_LOG_LEVEL=debug \
SMQ_GROUPS_HTTP_HOST=groups \
SMQ_GROUPS_HTTP_PORT=9004 \
SMQ_GROUPS_HTTP_SERVER_CERT="" \
SMQ_GROUPS_HTTP_SERVER_KEY="" \
SMQ_GROUPS_GRPC_HOST=groups \
SMQ_GROUPS_GRPC_PORT=7004 \
SMQ_GROUPS_GRPC_SERVER_CERT="" \
SMQ_GROUPS_GRPC_SERVER_KEY="" \
SMQ_GROUPS_GRPC_SERVER_CA_CERTS="" \
SMQ_GROUPS_GRPC_CLIENT_CA_CERTS="" \
SMQ_GROUPS_DB_HOST=groups-db \
SMQ_GROUPS_DB_PORT=5432 \
SMQ_GROUPS_DB_USER=supermq \
SMQ_GROUPS_DB_PASS=supermq \
SMQ_GROUPS_DB_NAME=groups \
SMQ_GROUPS_DB_SSL_MODE=disable \
SMQ_GROUPS_DB_SSL_CERT="" \
SMQ_GROUPS_DB_SSL_KEY="" \
SMQ_GROUPS_DB_SSL_ROOT_CERT="" \
SMQ_AUTH_GRPC_URL="" \
SMQ_AUTH_GRPC_TIMEOUT=1s \
SMQ_AUTH_GRPC_CLIENT_CERT="" \
SMQ_AUTH_GRPC_CLIENT_KEY="" \
SMQ_AUTH_GRPC_SERVER_CA_CERTS="" \
SMQ_DOMAINS_GRPC_URL=domains:7003 \
SMQ_DOMAINS_GRPC_TIMEOUT=1s \
SMQ_DOMAINS_GRPC_CLIENT_CERT="" \
SMQ_DOMAINS_GRPC_CLIENT_KEY="" \
SMQ_DOMAINS_GRPC_SERVER_CA_CERTS="" \
SMQ_CHANNELS_GRPC_URL=channels:7005 \
SMQ_CHANNELS_GRPC_TIMEOUT=1s \
SMQ_CHANNELS_GRPC_CLIENT_CERT="" \
SMQ_CHANNELS_GRPC_CLIENT_KEY="" \
SMQ_CHANNELS_GRPC_SERVER_CA_CERTS="" \
SMQ_CLIENTS_GRPC_URL=clients:7000 \
SMQ_CLIENTS_GRPC_TIMEOUT=1s \
SMQ_CLIENTS_GRPC_CLIENT_CERT="" \
SMQ_CLIENTS_GRPC_CLIENT_KEY="" \
SMQ_CLIENTS_GRPC_SERVER_CA_CERTS="" \
SMQ_SPICEDB_HOST=localhost \
SMQ_SPICEDB_PORT=50051 \
SMQ_SPICEDB_SCHEMA_FILE=schema.zed \
SMQ_SPICEDB_PRE_SHARED_KEY=12345678 \
SMQ_ES_URL=nats://localhost:4222 \
SMQ_JAEGER_URL=<http://localhost:4318/v1/traces> \
SMQ_JAEGER_TRACE_RATIO=1.0 \
SMQ_GROUPS_CALLOUT_URLS="" \
SMQ_GROUPS_CALLOUT_METHOD=POST \
SMQ_GROUPS_CALLOUT_TLS_VERIFICATION=false \
SMQ_GROUPS_CALLOUT_TIMEOUT=10s \
SMQ_GROUPS_CALLOUT_CA_CERT="" \
SMQ_GROUPS_CALLOUT_CERT="" \
SMQ_GROUPS_CALLOUT_KEY="" \
SMQ_GROUPS_CALLOUT_OPERATIONS="" \
SMQ_SEND_TELEMETRY=true \
SMQ_GROUPS_INSTANCE_ID="" \
$GOBIN/supermq-groups
```
## Usage
Groups supports the following operations:
| Operation | Description |
| ------------------------- | --------------------------------------------------------------------------- |
| `create` | Create a new group within a domain |
| `list` | List groups (flat list or tree) with filters for metadata, tags, status |
| `get` | Retrieve a single group (optionally with role memberships) |
| `update` | Update a groups name, description, tags, or metadata |
| `enable` / `disable` | Enable or disable a group |
| `delete` | Permanently delete a group |
| `add-parent` / `remove-parent` | Assign or remove a parent group |
| `add-children` / `remove-children` | Attach or detach child groups (or remove all children) |
| `list-children` | List children at specific depth ranges |
| `hierarchy` | Fetch ancestors/descendants as a tree or list |
| `roles` | Create/list/update/delete group roles; manage role actions and members |
### API Examples
#### Create a Group
```bash
curl -X POST http://localhost:9004/<domainID>/groups \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "edge-devices",
"description": "All edge devices",
"metadata": { "region": "eu-west-1" },
"tags": ["iot","edge"],
"parent_id": "",
"status": "enabled"
}'
```
#### List Groups (flat)
```bash
curl -X GET "http://localhost:9004/<domainID>/groups?limit=10&status=enabled" \
-H "Authorization: Bearer <your_access_token>"
```
#### Retrieve a Group (with Roles)
```bash
curl -X GET "http://localhost:9004/<domainID>/groups/<groupID>?roles=true" \
-H "Authorization: Bearer <your_access_token>"
```
#### Update a Group
```bash
curl -X PUT http://localhost:9004/<domainID>/groups/<groupID> \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "edge-ops",
"description": "Edge operations",
"metadata": { "region": "eu-west-1", "env": "prod" },
"tags": ["iot","ops"]
}'
```
#### Enable or Disable a Group
```bash
curl -X POST http://localhost:9004/<domainID>/groups/<groupID>/enable \
-H "Authorization: Bearer <your_access_token>"
curl -X POST http://localhost:9004/<domainID>/groups/<groupID>/disable \
-H "Authorization: Bearer <your_access_token>"
```
#### Manage Hierarchy
```bash
# Add a parent
curl -X POST http://localhost:9004/<domainID>/groups/<groupID>/parents \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{ "parent_id": "<parentID>" }'
# List children between levels 1 and 2
curl -X GET "http://localhost:9004/<domainID>/groups/<groupID>/children?start_level=1&end_level=2&limit=10" \
-H "Authorization: Bearer <your_access_token>"
```
## Roles Management for Groups
Group roles use the shared role manager. Supported operations mirror domain roles (create, list, view, update, delete roles; add/list/remove actions; add/list/remove members; list available actions).
Example: create a group role
```bash
curl -X POST http://localhost:9004/<domainID>/groups/<groupID>/roles \
-H "Authorization: Bearer <your_access_token>" \
-H "Content-Type: application/json" \
-d '{
"role_name": "group-admin",
"optional_actions": ["manage_role_permission", "update_permission"],
"optional_members": ["<userID>"]
}'
```
List available actions for groups:
```bash
curl -X GET http://localhost:9004/<domainID>/groups/roles/available-actions \
-H "Authorization: Bearer <your_access_token>"
```
## Implementation Details
- Groups are stored in PostgreSQL with `ltree` paths for hierarchy queries; domain migrations are applied alongside group migrations for referential integrity.
- Role tables are provisioned per entity with a `groups_` prefix.
- Event notifications are published to `SMQ_ES_URL`; domain events are consumed to keep group data aligned.
- Authorization and roles are enforced through SpiceDB and shared policy middleware.
- Optional HTTP callouts (pre-operation hooks) are controlled via `SMQ_GROUPS_CALLOUT_*`.
- Observability: Jaeger tracing, Prometheus metrics at `/metrics`, and a `/health` endpoint.
### Groups Table
| Column | Type | Description |
| ------------- | ------------- | ------------------------------------------------------------------ |
| `id` | VARCHAR(36) | UUID of the group (primary key) |
| `parent_id` | VARCHAR(36) | Optional parent group (self-referential FK) |
| `domain_id` | VARCHAR(36) | Owning domain |
| `name` | VARCHAR(1024) | Group name |
| `description` | VARCHAR(1024) | Optional description |
| `metadata` | JSONB | Arbitrary metadata |
| `tags` | TEXT[] | Group tags |
| `path` | LTREE | Hierarchical path for fast ancestor/descendant queries |
| `created_at` | TIMESTAMPTZ | Creation timestamp |
| `updated_at` | TIMESTAMPTZ | Last update timestamp |
| `updated_by` | VARCHAR(254) | Actor who last updated the group |
| `status` | SMALLINT | 0 = enabled, 1 = disabled, 2 = deleted |
## Best Practices
- Model hierarchy deliberately: keep depth reasonable and avoid cycles by design.
- Use tags/metadata to segment groups by environment, region, or ownership for filtering.
- Prefer `disable` before `delete` when you need reversible off-boarding.
- Use roles sparingly and audit with `list-role-members`; grant only required actions.
- Fetch children with bounded levels to keep queries efficient.
- Limit callouts to necessary operations via `SMQ_GROUPS_CALLOUT_OPERATIONS`.
## Versioning and Health Check
The Groups service exposes `/health` with status and build metadata.
```bash
curl -X GET http://localhost:9004/health \
-H "accept: application/health+json"
```
Example response:
```json
{
"status": "pass",
"version": "0.18.0",
"commit": "7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62",
"description": "groups service",
"build_time": "1970-01-01_00:00:00"
}
```
For full API coverage, see the [Groups API documentation](https://docs.api.supermq.absmach.eu/?urls.primaryName=api%2Fgroups.yaml).
[doc]: https://docs.supermq.absmach.eu/
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ Domains service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+135 -42
View File
@@ -1,77 +1,170 @@
# HTTP adapter
# HTTP Adapter
HTTP adapter provides an HTTP API for sending messages through the platform.
The HTTP Adapter exposes HTTP endpoints for publishing messages into SuperMQ channels. It authenticates clients via tokens or Basic auth, resolves domains/channels over gRPC, and forwards payloads to the message broker.
For more on SuperMQ, see the [official documentation][doc].
## Configuration
The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.
Environment variables (unset values fall back to defaults):
| Variable | Description | Default |
| ----------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------- |
| SMQ_HTTP_ADAPTER_LOG_LEVEL | Log level for the HTTP Adapter (debug, info, warn, error) | info |
| SMQ_HTTP_ADAPTER_HOST | Service HTTP host | "" |
| SMQ_HTTP_ADAPTER_PORT | Service HTTP port | 80 |
| SMQ_HTTP_ADAPTER_SERVER_CERT | Path to the PEM encoded server certificate file | "" |
| SMQ_HTTP_ADAPTER_SERVER_KEY | Path to the PEM encoded server key file | "" |
| SMQ_HTTP_ADAPTER_CACHE_NUM_COUNTERS | Number of cache counters to keep that hold access frequency information | 200000 |
| SMQ_HTTP_ADAPTER_CACHE_MAX_COST | Maximum size of the cache(in bytes) | 1048576 |
| SMQ_HTTP_ADAPTER_CACHE_BUFFER_ITEMS | Number of cache `Get` buffers | 64 |
| SMQ_CLIENTS_GRPC_URL | Clients service Auth gRPC URL | <localhost:7000> |
| SMQ_CLIENTS_GRPC_TIMEOUT | Clients service Auth gRPC request timeout in seconds | 1s |
| SMQ_CLIENTS_GRPC_CLIENT_CERT | Path to the PEM encoded clients service Auth gRPC client certificate file | "" |
| SMQ_CLIENTS_GRPC_CLIENT_KEY | Path to the PEM encoded clients service Auth gRPC client key file | "" |
| SMQ_CLIENTS_GRPC_SERVER_CERTS | Path to the PEM encoded clients server Auth gRPC server trusted CA certificate file | "" |
| SMQ_MESSAGE_BROKER_URL | Message broker instance URL | <amqp://guest:guest@rabbitmq:5672/> |
| SMQ_JAEGER_URL | Jaeger server URL | <http://localhost:4318/v1/traces> |
| SMQ_JAEGER_TRACE_RATIO | Jaeger sampling ratio | 1.0 |
| SMQ_SEND_TELEMETRY | Send telemetry to supermq call home server | true |
| SMQ_HTTP_ADAPTER_INSTANCE_ID | Service instance ID | "" |
| Variable | Description | Default |
| -------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------- |
| `SMQ_HTTP_ADAPTER_LOG_LEVEL` | Log level (debug, info, warn, error) | debug |
| `SMQ_HTTP_ADAPTER_HOST` | HTTP Adapter host | http-adapter |
| `SMQ_HTTP_ADAPTER_PORT` | HTTP Adapter port | 8008 |
| `SMQ_HTTP_ADAPTER_SERVER_CERT` | Path to PEM-encoded server certificate (enables TLS) | "" |
| `SMQ_HTTP_ADAPTER_SERVER_KEY` | Path to PEM-encoded server key | "" |
| `SMQ_HTTP_ADAPTER_SERVER_CA_CERTS` | Trusted CA bundle for HTTPS server | "" |
| `SMQ_HTTP_ADAPTER_CLIENT_CA_CERTS` | Client CA bundle to require mTLS on HTTPS server | "" |
| `SMQ_HTTP_ADAPTER_CACHE_NUM_COUNTERS` | Cache counters for topic parsing | 200000 |
| `SMQ_HTTP_ADAPTER_CACHE_MAX_COST` | Maximum cache size (bytes) | 1048576 |
| `SMQ_HTTP_ADAPTER_CACHE_BUFFER_ITEMS` | Cache buffer items | 64 |
| `SMQ_MESSAGE_BROKER_URL` | Message broker URL (publishing target) | nats://nats:4222 |
| `SMQ_ES_URL` | Event store URL (publishing middleware) | nats://nats:4222 |
| `SMQ_JAEGER_URL` | Jaeger tracing endpoint | <http://jaeger:4318/v1/traces> |
| `SMQ_JAEGER_TRACE_RATIO` | Trace sampling ratio | 1.0 |
| `SMQ_SEND_TELEMETRY` | Send telemetry to SuperMQ call-home server | true |
| `SMQ_HTTP_ADAPTER_INSTANCE_ID` | Service instance ID (auto-generated when empty) | "" |
| `SMQ_CLIENTS_GRPC_URL` | Clients service gRPC URL | clients:7006 |
| `SMQ_CLIENTS_GRPC_TIMEOUT` | Clients gRPC request timeout | 300s |
| `SMQ_CLIENTS_GRPC_CLIENT_CERT` | Clients gRPC client certificate | "" |
| `SMQ_CLIENTS_GRPC_CLIENT_KEY` | Clients gRPC client key | "" |
| `SMQ_CLIENTS_GRPC_SERVER_CA_CERTS` | Clients gRPC trusted CA bundle | "" |
| `SMQ_CHANNELS_GRPC_URL` | Channels service gRPC URL | channels:7005 |
| `SMQ_CHANNELS_GRPC_TIMEOUT` | Channels gRPC request timeout | 300s |
| `SMQ_CHANNELS_GRPC_CLIENT_CERT` | Channels gRPC client certificate | "" |
| `SMQ_CHANNELS_GRPC_CLIENT_KEY` | Channels gRPC client key | "" |
| `SMQ_CHANNELS_GRPC_SERVER_CA_CERTS` | Channels gRPC trusted CA bundle | "" |
| `SMQ_DOMAINS_GRPC_URL` | Domains service gRPC URL | domains:7003 |
| `SMQ_DOMAINS_GRPC_TIMEOUT` | Domains gRPC request timeout | 300s |
| `SMQ_DOMAINS_GRPC_CLIENT_CERT` | Domains gRPC client certificate | "" |
| `SMQ_DOMAINS_GRPC_CLIENT_KEY` | Domains gRPC client key | "" |
| `SMQ_DOMAINS_GRPC_SERVER_CA_CERTS` | Domains gRPC trusted CA bundle | "" |
| `SMQ_AUTH_GRPC_URL` | Auth service gRPC URL | auth:7001 |
| `SMQ_AUTH_GRPC_TIMEOUT` | Auth service gRPC request timeout | 300s |
| `SMQ_AUTH_GRPC_CLIENT_CERT` | Auth gRPC client certificate | "" |
| `SMQ_AUTH_GRPC_CLIENT_KEY` | Auth gRPC client key | "" |
| `SMQ_AUTH_GRPC_SERVER_CA_CERTS` | Auth gRPC trusted CA bundle | "" |
## Deployment
The service itself is distributed as Docker container. Check the [`http-adapter`](https://github.com/absmach/supermq/blob/main/docker/docker-compose.yaml) service section in docker-compose file to see how service is deployed.
The adapter is shipped as a Docker container. See the [`http-adapter` section](https://github.com/absmach/supermq/blob/main/docker/docker-compose.yaml#L1226-L1365) of `docker-compose.yaml` for deployment details.
Running this service outside of container requires working instance of the message broker service, clients service and Jaeger server.
To start the service outside of the container, execute the following shell script:
To build and run locally:
```bash
# download the latest version of the service
git clone https://github.com/absmach/supermq
cd supermq
# compile the http
# compile the http adapter
make http
# copy binary to bin
# copy binary to $GOBIN
make install
# set the environment variables and run the service
SMQ_HTTP_ADAPTER_LOG_LEVEL=info \
SMQ_HTTP_ADAPTER_HOST=localhost \
SMQ_HTTP_ADAPTER_PORT=80 \
SMQ_HTTP_ADAPTER_LOG_LEVEL=debug \
SMQ_HTTP_ADAPTER_HOST=http-adapter \
SMQ_HTTP_ADAPTER_PORT=8008 \
SMQ_HTTP_ADAPTER_SERVER_CERT="" \
SMQ_HTTP_ADAPTER_SERVER_KEY="" \
SMQ_HTTP_ADAPTER_CACHE_NUM_COUNTERS=200000 \
SMQ_HTTP_ADAPTER_CACHE_MAX_COST=1048576 \
SMQ_HTTP_ADAPTER_CACHE_BUFFER_ITEMS=64 \
SMQ_CLIENTS_GRPC_URL=localhost:7000 \
SMQ_CLIENTS_GRPC_TIMEOUT=1s \
SMQ_MESSAGE_BROKER_URL=nats://nats:4222 \
SMQ_ES_URL=nats://nats:4222 \
SMQ_JAEGER_URL=<http://jaeger:4318/v1/traces> \
SMQ_JAEGER_TRACE_RATIO=1.0 \
SMQ_CLIENTS_GRPC_URL=clients:7006 \
SMQ_CLIENTS_GRPC_TIMEOUT=300s \
SMQ_CLIENTS_GRPC_CLIENT_CERT="" \
SMQ_CLIENTS_GRPC_CLIENT_KEY="" \
SMQ_CLIENTS_GRPC_SERVER_CERTS="" \
SMQ_MESSAGE_BROKER_URL=amqp://guest:guest@rabbitmq:5672/ \
SMQ_JAEGER_URL=http://localhost:14268/api/traces \
SMQ_JAEGER_TRACE_RATIO=1.0 \
SMQ_CLIENTS_GRPC_SERVER_CA_CERTS="" \
SMQ_CHANNELS_GRPC_URL=channels:7005 \
SMQ_CHANNELS_GRPC_TIMEOUT=300s \
SMQ_CHANNELS_GRPC_CLIENT_CERT="" \
SMQ_CHANNELS_GRPC_CLIENT_KEY="" \
SMQ_CHANNELS_GRPC_SERVER_CA_CERTS="" \
SMQ_DOMAINS_GRPC_URL=domains:7003 \
SMQ_DOMAINS_GRPC_TIMEOUT=300s \
SMQ_DOMAINS_GRPC_CLIENT_CERT="" \
SMQ_DOMAINS_GRPC_CLIENT_KEY="" \
SMQ_DOMAINS_GRPC_SERVER_CA_CERTS="" \
SMQ_AUTH_GRPC_URL=auth:7001 \
SMQ_AUTH_GRPC_TIMEOUT=300s \
SMQ_AUTH_GRPC_CLIENT_CERT="" \
SMQ_AUTH_GRPC_CLIENT_KEY="" \
SMQ_AUTH_GRPC_SERVER_CA_CERTS="" \
SMQ_SEND_TELEMETRY=true \
SMQ_HTTP_ADAPTER_INSTANCE_ID="" \
$GOBIN/supermq-http
```
Setting `SMQ_HTTP_ADAPTER_SERVER_CERT` and `SMQ_HTTP_ADAPTER_SERVER_KEY` will enable TLS against the service. The service expects a file in PEM format for both the certificate and the key.
Setting `SMQ_CLIENTS_GRPC_CLIENT_CERT` and `SMQ_CLIENTS_GRPC_CLIENT_KEY` will enable TLS against the clients service. The service expects a file in PEM format for both the certificate and the key. Setting `SMQ_CLIENTS_GRPC_SERVER_CERTS` will enable TLS against the clients service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs.
TLS is enabled by setting `SMQ_HTTP_ADAPTER_SERVER_CERT` and `SMQ_HTTP_ADAPTER_SERVER_KEY`. mTLS is enabled when `SMQ_HTTP_ADAPTER_CLIENT_CA_CERTS` is provided. gRPC client TLS/mTLS is enabled by setting the corresponding client cert/key/CA variables.
## Usage
HTTP Authorization request header contains the credentials to authenticate a Client. The authorization header can be a plain Client key or a Client key encoded as a password for Basic Authentication. In case the Basic Authentication schema is used, the username is ignored. For more information about service capabilities and its usage, please check out the [API documentation](https://docs.api.supermq.abstractmachines.fr/?urls.primaryName=http.yaml).
Endpoints:
- `POST /m/{domain}/c/{channel}` (and wildcard `/m/{domain}/c/{channel}/*`): publish a message.
- `POST /hc/{domain}`: health-check message path (authenticated).
- `GET /health`: service health probe.
- `GET /metrics`: Prometheus metrics.
Authentication:
- Bearer token in `Authorization` header, or
- Basic auth where the password is the token (username ignored).
Supported content types: `application/json`, `application/senml+json`, `application/senml+cbor`.
Example publish:
```bash
curl -X POST http://localhost:8008/m/<domainID>/c/<channelID>/sub/topic \
-H "Authorization: Bearer <client_token>" \
-H "Content-Type: application/json" \
-d '{ "temp": 22.5, "unit": "C" }'
```
## Implementation Details
- Publishes to the configured message broker (`SMQ_MESSAGE_BROKER_URL`) with optional event-store middleware (`SMQ_ES_URL`).
- Resolves domains and channels over gRPC to validate/route topics; authenticates via Auth gRPC; validates client identity via Clients gRPC.
- Topic parsing is cached (Ristretto) with configurable counters/cost/buffers to reduce resolver calls.
- Observability: Jaeger tracing, Prometheus metrics at `/metrics`, service health at `/health`.
- Optional call-home telemetry is enabled by default.
## Best Practices
- Use domain/channel routes consistently in publish paths; include subtopics to segment data.
- Keep cache defaults unless load patterns require tuning; monitor `/metrics` for cache hit ratios.
- Enable TLS/mTLS for production deployments (HTTP server and gRPC clients).
- Reuse a single broker URL across services (often NATS) to simplify operations.
## Versioning and Health Check
The adapter exposes `/health` with status and build metadata.
```bash
curl -X GET http://localhost:8008/health \
-H "accept: application/health+json"
```
Example response:
```json
{
"status": "pass",
"version": "0.18.0",
"commit": "7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62",
"description": "http adapter",
"build_time": "1970-01-01_00:00:00"
}
```
For endpoint details, see the [HTTP Adapter API documentation](https://docs.api.supermq.absmach.eu/?urls.primaryName=http.yaml).
[doc]: https://docs.supermq.absmach.eu/
+197
View File
@@ -0,0 +1,197 @@
# Journal
The Journal service listens to the platform event stream, persists each event to PostgreSQL for auditability and exposes HTTP endpoints to query journals or view per-client telemetry (first/last seen, subscriptions, in/out message counters).
## Configuration
The service is configured with the following environment variables (unset values fall back to defaults).
| Variable | Description | Default |
| --- | --- | --- |
| `SMQ_JOURNAL_LOG_LEVEL` | Log level for Journal (debug, info, warn, error) | info |
| `SMQ_JOURNAL_HTTP_HOST` | Journal HTTP host | localhost |
| `SMQ_JOURNAL_HTTP_PORT` | Journal HTTP port | 9021 |
| `SMQ_JOURNAL_HTTP_SERVER_CERT` | Path to PEM-encoded HTTP server certificate | "" |
| `SMQ_JOURNAL_HTTP_SERVER_KEY` | Path to PEM-encoded HTTP server key | "" |
| `SMQ_JOURNAL_HTTP_SERVER_CA_CERTS` | Path to trusted CA bundle for the HTTP server | "" |
| `SMQ_JOURNAL_HTTP_CLIENT_CA_CERTS` | Path to client CA bundle to require HTTP mTLS | "" |
| `SMQ_JOURNAL_DB_HOST` | Database host address | localhost |
| `SMQ_JOURNAL_DB_PORT` | Database host port | 5432 |
| `SMQ_JOURNAL_DB_USER` | Database user | supermq |
| `SMQ_JOURNAL_DB_PASS` | Database password | supermq |
| `SMQ_JOURNAL_DB_NAME` | Name of the database used by the service | journal |
| `SMQ_JOURNAL_DB_SSL_MODE` | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| `SMQ_JOURNAL_DB_SSL_CERT` | Path to the PEM-encoded certificate file | "" |
| `SMQ_JOURNAL_DB_SSL_KEY` | Path to the PEM-encoded key file | "" |
| `SMQ_JOURNAL_DB_SSL_ROOT_CERT` | Path to the PEM-encoded root certificate file | "" |
| `SMQ_ES_URL` | Event store URL (NATS) consumed for journal entries | nats://localhost:4222 |
| `SMQ_JAEGER_URL` | Jaeger tracing endpoint | <http://localhost:4318/v1/traces> |
| `SMQ_JAEGER_TRACE_RATIO` | Trace sampling ratio | 1.0 |
| `SMQ_SEND_TELEMETRY` | Send telemetry to the SuperMQ call-home server | true |
| `SMQ_AUTH_GRPC_URL` | Auth service gRPC URL | "" |
| `SMQ_AUTH_GRPC_TIMEOUT` | Auth service gRPC timeout | 1s |
| `SMQ_AUTH_GRPC_CLIENT_CERT` | Path to PEM-encoded Auth gRPC client certificate | "" |
| `SMQ_AUTH_GRPC_CLIENT_KEY` | Path to PEM-encoded Auth gRPC client key | "" |
| `SMQ_AUTH_GRPC_SERVER_CA_CERTS` | Path to PEM-encoded Auth gRPC trusted CA bundle | "" |
| `SMQ_DOMAINS_GRPC_URL` | Domains service gRPC URL | "" |
| `SMQ_DOMAINS_GRPC_TIMEOUT` | Domains service gRPC timeout | 1s |
| `SMQ_DOMAINS_GRPC_CLIENT_CERT` | Path to PEM-encoded Domains gRPC client certificate | "" |
| `SMQ_DOMAINS_GRPC_CLIENT_KEY` | Path to PEM-encoded Domains gRPC client key | "" |
| `SMQ_DOMAINS_GRPC_SERVER_CA_CERTS` | Path to PEM-encoded Domains gRPC trusted CA bundle | "" |
| `SMQ_JOURNAL_INSTANCE_ID` | Journal instance ID (auto-generated when empty) | "" |
| `SMQ_ALLOW_UNVERIFIED_USER` | Allow unverified users to authenticate (useful in dev) | false |
## Deployment
The service is distributed as a Docker container. Check the [`journals`](https://github.com/absmach/supermq/tree/main/docker/addons/journal) for the `journal` and `journal-db` services and how they are wired into the base stack.
To start the service outside of the container, execute the following shell script:
```bash
git clone https://github.com/absmach/supermq
cd supermq
# build and install the binary
make journal
make install
# run with the essentials; requires Postgres, Auth gRPC, Domains gRPC, and NATS running
SMQ_JOURNAL_HTTP_HOST=localhost \
SMQ_JOURNAL_HTTP_PORT=9021 \
SMQ_JOURNAL_DB_HOST=localhost \
SMQ_JOURNAL_DB_PORT=5432 \
SMQ_JOURNAL_DB_USER=supermq \
SMQ_JOURNAL_DB_PASS=supermq \
SMQ_JOURNAL_DB_NAME=journal \
SMQ_AUTH_GRPC_URL=localhost:7001 \
SMQ_DOMAINS_GRPC_URL=localhost:7003 \
SMQ_ES_URL=nats://localhost:4222 \
$GOBIN/supermq-journal
```
## HTTP API
Base URL defaults to `http://localhost:9021`. All journal and telemetry endpoints require `Authorization: Bearer <token>` (health is public).
### Usage
| Operation | Description |
| --- | --- |
| List user journals | Page through journals for a user across domains. |
| List entity journals | Page through journals for a group, client, channel, or user within a domain. |
| View client telemetry | Aggregate telemetry counters for a client in a domain. |
| Health check | Liveness and build info. |
### API examples
#### List user journals
```bash
curl -X GET "http://localhost:9021/journal/user/${USER_ID}?limit=5&with_attributes=true&dir=desc" \
-H "Authorization: Bearer $TOKEN"
```
Expected response:
```json
{
"journals": [
{
"operation": "user.create",
"occurred_at": "2024-01-11T12:05:07.449053Z",
"attributes": {
"created_at": "2024-06-12T11:34:32.991591Z",
"id": "29d425c8-542b-4614-8a4d-a5951945d720",
"identity": "Gawne-Havlicek@email.com",
"name": "Newgard-Frisina",
"status": "enabled",
"updated_at": "2024-06-12T11:34:33.116795Z",
"updated_by": "ad228f20-4741-47c5-bef7-d871b541c019"
},
"metadata": {
"Update": "Calvo-Felkins"
}
}
],
"total": 1,
"offset": 0,
"limit": 5
}
```
#### List entity journals in a domain
Retrieves telemetry data for a specific client within a domain. This includes connection status, messages sent/received, and other metrics.
```bash
curl -X GET "http://localhost:9021/${DOMAIN_ID}/journal/client/${CLIENT_ID}?operation=client.create&with_metadata=true&dir=desc&limit=10" \
-H "Authorization: Bearer $TOKEN"
```
Expected response:
```json
{
"total": 2,
"offset": 0,
"limit": 10,
"journals": [
{
"operation": "client.create",
"occurred_at": "2024-06-12T11:34:33Z",
"domain": "29d425c8-542b-4614-8a4d-a5951945d720",
"attributes": {
"id": "bb7edb32-2eac-4aad-aebe-ed96fe073879",
"domain": "29d425c8-542b-4614-8a4d-a5951945d720",
"name": "clientName",
"status": "enabled"
},
"metadata": {
"trace_id": "6efb4c24b1b4a684"
}
}
]
}
```
#### View client telemetry
Retrieves telemetry data for a specific client within a domain. This includes connection status, messages sent/received, and other metrics.
```bash
curl -X GET "http://localhost:9021/${DOMAIN_ID}/journal/client/${CLIENT_ID}/telemetry" \
-H "Authorization: Bearer $TOKEN"
```
Expected response:
```json
{
"client_id": "bb7edb32-2eac-4aad-aebe-ed96fe073879",
"domain_id": "29d425c8-542b-4614-8a4d-a5951945d720",
"subscriptions": 5,
"inbound_messages": 1234567,
"outbound_messages": 987654,
"first_seen": "2024-01-11T10:00:00Z",
"last_seen": "2024-01-11T12:05:07.449053Z"
}
```
#### Health check
```bash
curl "http://localhost:9021/health"
```
Expected response:
```json
{
"status": "pass",
"version": "0.18.0",
"commit": "ffffffff",
"description": "journal service",
"build_time": "1970-01-01_00:00:00",
"instance_id": "b4f1d5d2-4f24-4c2a-9a40-123456789abc"
}
```
-2
View File
@@ -29,8 +29,6 @@ const (
toKey = "to"
attributesKey = "with_attributes"
metadataKey = "with_metadata"
entityIDKey = "id"
entityTypeKey = "entity_type"
)
// MakeHandler returns a HTTP API handler with health check and metrics.
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ Journal service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+1 -1
View File
@@ -8,5 +8,5 @@
// SuperMQ MQTT adapter service.
//
// For more details about tracing instrumentation for SuperMQ messaging refer
// to the documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// to the documentation at https://docs.supermq.absmach.eu/tracing/.
package tracing
+35 -1
View File
@@ -1,3 +1,37 @@
# Standalone packages
The `pkg` directory (the current directory) contains a set of standalone packages that can be imported and used by external applications. The packages are specifically meant for the development of the SuperMQ based back-end applications and implement common tasks needed by the programmatic operation of SuperMQ platform.
The `pkg` directory (the current directory) contains a set of standalone packages that can be imported and used by external applications. The packages are specifically meant for the development of SuperMQ based back-end applications and implement common tasks needed by the programmatic operation of the SuperMQ platform.
## Using the packages
Fetch any package directly from the module:
```bash
go get github.com/absmach/supermq/pkg/authn
```
Then import it in your code:
```go
import "github.com/absmach/supermq/pkg/authn"
```
## Package map (selected)
| Package | Purpose |
| --- | --- |
| `authn`, `authz`, `oauth2`, `policies` | Authentication and authorization helpers, middleware, and policy utilities. |
| `grpcclient` | TLS-aware gRPC client setup with health checks and timeouts. |
| `server` | HTTP, gRPC, and COAP server bootstrap utilities (TLS, graceful shutdown). |
| `postgres` | PostgreSQL connector with migrations helpers. |
| `events` | Event store client abstractions and subscriber utilities. |
| `prometheus` | Metrics collectors for request counts/latency. |
| `jaeger`, `tracing` | OpenTelemetry tracing configuration and instrumentation helpers. |
| `channels`, `clients`, `groups`, `domains`, `roles` | Shared types and helpers for core SuperMQ domain services. |
| `messaging`, `connections`, `callout` | Messaging DTOs, connection types, and outbound callout helpers. |
| `sdk` | Go SDK for interacting with SuperMQ services. |
| `errors` | Error wrappers with consistent error typing. |
| `uuid`, `ulid`, `sid` | ID generators. |
| `transformers`, `svcutil` | Generic data transformation and service utilities. |
For detailed package-level docs, run `go doc` on the desired package or browse the [source here](https://docs.supermq.absmach.eu.).
+1 -1
View File
@@ -8,5 +8,5 @@
// SuperMQ clients policies service.
//
// For more details about tracing instrumentation for SuperMQ messaging refer
// to the documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// to the documentation at https://docs.supermq.absmach.eu/tracing/.
package tracing
+1 -1
View File
@@ -8,5 +8,5 @@
// SuperMQ clients policies service.
//
// For more details about tracing instrumentation for SuperMQ messaging refer
// to the documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// to the documentation at https://docs.supermq.absmach.eu/tracing/.
package tracing
+1 -1
View File
@@ -8,5 +8,5 @@
// SuperMQ clients policies service.
//
// For more details about tracing instrumentation for SuperMQ messaging refer
// to the documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// to the documentation at https://docs.supermq.absmach.eu/tracing/.
package tracing
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ RoleManager service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+1 -3
View File
@@ -2,6 +2,4 @@
Readers provide implementations of various `message readers`. Message readers are services that consume normalized (in `SenML` format) SuperMQ messages from data storage and expose HTTP API for message consumption.
For an in-depth explanation of the usage of `reader`, as well as thorough understanding of SuperMQ, please check out the [official documentation][doc].
[doc]: https://docs.supermq.abstractmachines.fr
For an in-depth explanation of the usage of `readers` service as well as API details, see the [Readers guide](https://docs.magistrala.absmach.eu/dev-guide/readers) and the [OpenAPI reference](https://docs.api.magistrala.absmach.eu/?urls.primaryName=api%2Freaders.yaml).
+241 -46
View File
@@ -14,49 +14,49 @@ The service is configured using the environment variables presented in the follo
| Variable | Description | Default |
| --------------------------------- | ----------------------------------------------------------------------- | --------------------------------- |
| SMQ_USERS_LOG_LEVEL | Log level for users service (debug, info, warn, error) | info |
| SMQ_USERS_ADMIN_EMAIL | Default user, created on startup | <admin@example.com> |
| SMQ_USERS_ADMIN_PASSWORD | Default user password, created on startup | 12345678 |
| SMQ_USERS_PASS_REGEX | Password regex | ^.{8,}$ |
| SMQ_USERS_HTTP_HOST | Users service HTTP host | localhost |
| SMQ_USERS_HTTP_PORT | Users service HTTP port | 9002 |
| SMQ_USERS_HTTP_SERVER_CERT | Path to the PEM encoded server certificate file | "" |
| SMQ_USERS_HTTP_SERVER_KEY | Path to the PEM encoded server key file | "" |
| SMQ_USERS_HTTP_SERVER_CA_CERTS | Path to the PEM encoded server CA certificate file | "" |
| SMQ_USERS_HTTP_CLIENT_CA_CERTS | Path to the PEM encoded client CA certificate file | "" |
| SMQ_AUTH_GRPC_URL | Auth service GRPC URL | localhost:8181 |
| SMQ_AUTH_GRPC_TIMEOUT | Auth service GRPC timeout | 1s |
| SMQ_AUTH_GRPC_CLIENT_CERT | Path to the PEM encoded client certificate file | "" |
| SMQ_AUTH_GRPC_CLIENT_KEY | Path to the PEM encoded client key file | "" |
| SMQ_AUTH_GRPC_SERVER_CA_CERTS | Path to the PEM encoded server CA certificate file | "" |
| SMQ_USERS_DB_HOST | Database host address | localhost |
| SMQ_USERS_DB_PORT | Database host port | 5432 |
| SMQ_USERS_DB_USER | Database user | supermq |
| SMQ_USERS_DB_PASS | Database password | supermq |
| SMQ_USERS_DB_NAME | Name of the database used by the service | users |
| SMQ_USERS_DB_SSL_MODE | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| SMQ_USERS_DB_SSL_CERT | Path to the PEM encoded certificate file | "" |
| SMQ_USERS_DB_SSL_KEY | Path to the PEM encoded key file | "" |
| SMQ_USERS_DB_SSL_ROOT_CERT | Path to the PEM encoded root certificate file | "" |
| SMQ_EMAIL_HOST | Mail server host | localhost |
| SMQ_EMAIL_PORT | Mail server port | 25 |
| SMQ_EMAIL_USERNAME | Mail server username | "" |
| SMQ_EMAIL_PASSWORD | Mail server password | "" |
| SMQ_EMAIL_FROM_ADDRESS | Email "from" address | "" |
| SMQ_EMAIL_FROM_NAME | Email "from" name | "" |
| SMQ_PASSWORD_RESET_URL_PREFIX | Password reset URL prefix | <http://localhost/password/reset> |
| SMQ_PASSWORD_RESET_EMAIL_TEMPLATE | Password reset email template | reset-password-email.tmpl |
| SMQ_VERIFICATION_URL_PREFIX | Verification URL prefix | <http://localhost/verify-email> |
| SMQ_VERIFICATION_EMAIL_TEMPLATE | Verification email template | verification-email.tmpl |
| SMQ_USERS_ES_URL | Event store URL | <nats://localhost:4222> |
| SMQ_JAEGER_URL | Jaeger server URL | <http://localhost:4318/v1/traces> |
| SMQ_OAUTH_UI_REDIRECT_URL | OAuth UI redirect URL | <http://localhost:9095/domains> |
| SMQ_OAUTH_UI_ERROR_URL | OAuth UI error URL | <http://localhost:9095/error> |
| SMQ_USERS_DELETE_INTERVAL | Interval for deleting users | 24h |
| SMQ_USERS_DELETE_AFTER | Time after which users are deleted | 720h |
| SMQ_JAEGER_TRACE_RATIO | Jaeger sampling ratio | 1.0 |
| SMQ_SEND_TELEMETRY | Send telemetry to supermq call home server. | true |
| SMQ_USERS_INSTANCE_ID | SuperMQ instance ID | "" |
| `SMQ_USERS_LOG_LEVEL` | Log level for users service (debug, info, warn, error) | info |
| `SMQ_USERS_ADMIN_EMAIL` | Default user, created on startup | <admin@example.com> |
| `SMQ_USERS_ADMIN_PASSWORD` | Default user password, created on startup | 12345678 |
| `SMQ_USERS_PASS_REGEX` | Password regex | ^.{8,}$ |
| `SMQ_USERS_HTTP_HOST` | Users service HTTP host | localhost |
| `SMQ_USERS_HTTP_PORT` | Users service HTTP port | 9002 |
| `SMQ_USERS_HTTP_SERVER_CERT` | Path to the PEM encoded server certificate file | "" |
| `SMQ_USERS_HTTP_SERVER_KEY` | Path to the PEM encoded server key file | "" |
| `SMQ_USERS_HTTP_SERVER_CA_CERTS` | Path to the PEM encoded server CA certificate file | "" |
| `SMQ_USERS_HTTP_CLIENT_CA_CERTS` | Path to the PEM encoded client CA certificate file | "" |
| `SMQ_AUTH_GRPC_URL` | Auth service GRPC URL | localhost:8181 |
| `SMQ_AUTH_GRPC_TIMEOUT` | Auth service GRPC timeout | 1s |
| `SMQ_AUTH_GRPC_CLIENT_CERT` | Path to the PEM encoded client certificate file | "" |
| `SMQ_AUTH_GRPC_CLIENT_KEY` | Path to the PEM encoded client key file | "" |
| `SMQ_AUTH_GRPC_SERVER_CA_CERTS` | Path to the PEM encoded server CA certificate file | "" |
| `SMQ_USERS_DB_HOST` | Database host address | localhost |
| `SMQ_USERS_DB_PORT` | Database host port | 5432 |
| `SMQ_USERS_DB_USER` | Database user | supermq |
| `SMQ_USERS_DB_PASS` | Database password | supermq |
| `SMQ_USERS_DB_NAME` | Name of the database used by the service | users |
| `SMQ_USERS_DB_SSL_MODE` | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| `SMQ_USERS_DB_SSL_CERT` | Path to the PEM encoded certificate file | "" |
| `SMQ_USERS_DB_SSL_KEY` | Path to the PEM encoded key file | "" |
| `SMQ_USERS_DB_SSL_ROOT_CERT` | Path to the PEM encoded root certificate file | "" |
| `SMQ_EMAIL_HOST` | Mail server host | localhost |
| `SMQ_EMAIL_PORT` | Mail server port | 25 |
| `SMQ_EMAIL_USERNAME` | Mail server username | "" |
| `SMQ_EMAIL_PASSWORD` | Mail server password | "" |
| `SMQ_EMAIL_FROM_ADDRESS` | Email "from" address | "" |
| `SMQ_EMAIL_FROM_NAME` | Email "from" name | "" |
| `SMQ_PASSWORD_RESET_URL_PREFIX` | Password reset URL prefix | <http://localhost/password/reset> |
| `SMQ_PASSWORD_RESET_EMAIL_TEMPLATE` | Password reset email template | reset-password-email.tmpl |
| `SMQ_VERIFICATION_URL_PREFIX` | Verification URL prefix | <http://localhost/verify-email> |
| `SMQ_VERIFICATION_EMAIL_TEMPLATE` | Verification email template | verification-email.tmpl |
| `SMQ_USERS_ES_URL` | Event store URL | <nats://localhost:4222> |
| `SMQ_JAEGER_URL` | Jaeger server URL | <http://localhost:4318/v1/traces> |
| `SMQ_OAUTH_UI_REDIRECT_URL` | OAuth UI redirect URL | <http://localhost:9095/domains> |
| `SMQ_OAUTH_UI_ERROR_URL` | OAuth UI error URL | <http://localhost:9095/error> |
| `SMQ_USERS_DELETE_INTERVAL` | Interval for deleting users | 24h |
| `SMQ_USERS_DELETE_AFTER` | Time after which users are deleted | 720h |
| `SMQ_JAEGER_TRACE_RATIO` | Jaeger sampling ratio | 1.0 |
| `SMQ_SEND_TELEMETRY` | Send telemetry to supermq call home server. | true |
| `SMQ_USERS_INSTANCE_ID` | SuperMQ instance ID | "" |
## Deployment
@@ -129,8 +129,203 @@ Setting `SMQ_USERS_HTTP_SERVER_CERT` and `SMQ_USERS_HTTP_SERVER_KEY` will enable
Setting `SMQ_AUTH_GRPC_CLIENT_CERT` and `SMQ_AUTH_GRPC_CLIENT_KEY` will enable TLS against the auth service. The service expects a file in PEM format for both the certificate and the key. Setting `SMQ_AUTH_GRPC_SERVER_CA_CERTS` will enable TLS against the auth service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs.
## Usage
## HTTP API
For more information about service capabilities and its usage, please check out the [API documentation](https://docs.api.supermq.abstractmachines.fr/?urls.primaryName=users-openapi.yaml).
Base URL defaults to `http://localhost:9002`. Unless otherwise noted, endpoints require `Authorization: Bearer <access_token>`.
[doc]: https://docs.supermq.abstractmachines.fr
### Usage
| Operation | Description |
| --- | --- |
| Register | Create a user; optionally protected if self-registration is disabled. |
| Issue token | Exchange identity (email/username) and secret for access/refresh tokens. |
| Refresh token | Exchange a refresh token for a new access token. |
| Profile | Fetch the authenticated user profile. |
| List/search users | Page and filter users. |
| View user | Retrieve a user by ID . |
| Update user | Patch names/metadata/tags/profile picture; update email/username/role/tags/password via dedicated endpoints. |
| Status | Enable/disable a user or delete a user. |
| Verification | Send verification email; verify via emailed link. |
| Password reset | Request a reset link and set a new password. |
### Best practices
- Disable self-registration in production; onboard users via admin tokens or your IdP.
- Keep `allow_unverified_user` false and require email verification before granting domain roles.
- Enforce TLS for HTTP and mTLS for gRPC by setting server/client cert env vars.
- Harden passwords with `SMQ_USERS_PASS_REGEX` and rotate credentials; purge stale accounts via `SMQ_USERS_DELETE_AFTER`.
- Rate-limit token issuance and password reset endpoints at your API gateway; export Prometheus metrics to watch for abuse.
- Store SMTP credentials and certificates in a secrets manager; avoid embedding secrets in images or repos.
### API examples
#### Register a user
```bash
curl -X POST "http://localhost:9002/users" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Ada",
"last_name": "Lovelace",
"credentials": { "username": "ada", "secret": "changeMe123" },
"email": "ada@example.com",
"role": 0,
"status": 0,
"tags": ["iot", "beta"],
"metadata": { "team": "core" }
}'
```
Expected response (201 Created):
```json
{
"id": "c0b0c68c-5b93-4a93-8f1a-5d63a3f5c3c7",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com",
"role": 0,
"status": 0,
"tags": ["iot", "beta"],
"metadata": { "team": "core" },
"created_at": "2024-10-24T13:31:52Z"
}
```
#### Issue access/refresh tokens (login)
```bash
curl -X POST "http://localhost:9002/users/tokens/issue" \
-H "Content-Type: application/json" \
-d '{ "identity": "ada@example.com", "secret": "changeMe123" }'
```
Expected response (201 Created):
```json
{
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"access_type": "Bearer"
}
```
#### View authenticated profile
```bash
curl -X GET "http://localhost:9002/users/profile" \
-H "Authorization: Bearer $ACCESS_TOKEN"
```
Expected response:
```json
{
"id": "c0b0c68c-5b93-4a93-8f1a-5d63a3f5c3c7",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com",
"role": 0,
"status": 0,
"tags": ["iot", "beta"],
"metadata": { "team": "core" },
"verified_at": "2024-10-24T14:02:00Z",
"created_at": "2024-10-24T13:31:52Z",
"updated_at": "2024-10-24T14:02:00Z"
}
```
#### List users
```bash
curl -X GET "http://localhost:9002/users?limit=5&status=enabled&dir=desc" \
-H "Authorization: Bearer $ACCESS_TOKEN"
```
Expected response:
```json
{
"total": 2,
"offset": 0,
"limit": 5,
"users": [
{
"id": "c0b0c68c-5b93-4a93-8f1a-5d63a3f5c3c7",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com",
"role": 0,
"status": 0,
"tags": ["iot", "beta"],
"created_at": "2024-10-24T13:31:52Z"
}
]
}
```
#### Update user metadata and name
```bash
curl -X PATCH "http://localhost:9002/users/${USER_ID}" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Ada",
"last_name": "Byron",
"metadata": { "team": "edge" },
"tags": ["edge", "beta"]
}'
```
Expected response:
```json
{
"id": "c0b0c68c-5b93-4a93-8f1a-5d63a3f5c3c7",
"first_name": "Ada",
"last_name": "Byron",
"email": "ada@example.com",
"tags": ["edge", "beta"],
"metadata": { "team": "edge" },
"status": 0,
"role": 0,
"updated_at": "2024-10-24T14:45:10Z",
"updated_by": "a5b6c7d8-e901-4fab-9bcd-123456789abc"
}
```
#### Request password reset
```bash
curl -X POST "http://localhost:9002/password/reset-request" \
-H "Content-Type: application/json" \
-d '{ "email": "ada@example.com" }'
```
Expected response (201 Created):
```json
{ "msg": "Email with reset link is sent" }
```
#### Health check
```bash
curl -X GET "http://localhost:9002/health"
```
Expected response:
```json
{
"status": "pass",
"version": "0.18.0",
"commit": "ffffffff",
"description": "users service",
"build_time": "1970-01-01_00:00:00",
"instance_id": "b4f1d5d2-4f24-4c2a-9a40-123456789abc"
}
```
[doc]: https://docs.supermq.absmach.eu/
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ Users Service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware
+1 -1
View File
@@ -74,4 +74,4 @@ Setting `SMQ_CLIENTS_GRPC_CLIENT_CERT` and `SMQ_CLIENTS_GRPC_CLIENT_KEY` will en
## Usage
For more information about service capabilities and its usage, please check out the [WebSocket section](https://docs.supermq.abstractmachines.fr/messaging/#websocket).
For more information about service capabilities and its usage, please check out the [WebSocket section](https://docs.supermq.absmach.eu/messaging/#websocket).
+1 -1
View File
@@ -11,5 +11,5 @@
// clients and servers.
//
// For more details about SuperMQ messaging and WebSocket adapter service,
// please refer to the documentation at https://docs.supermq.abstractmachines.fr/messaging/#websocket.
// please refer to the documentation at https://docs.supermq.absmach.eu/messaging/#websocket.
package ws
+1 -1
View File
@@ -5,5 +5,5 @@
// for SuperMQ WebSockets service.
//
// For more details about tracing instrumentation for SuperMQ refer to the
// documentation at https://docs.supermq.abstractmachines.fr/tracing/.
// documentation at https://docs.supermq.absmach.eu/tracing/.
package middleware