mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
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:
+1
-1
@@ -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
@@ -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) |
|
||||
|
||||
@@ -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/)**
|
||||
|
||||
[](https://github.com/absmach/supermq/actions/workflows/build.yaml)
|
||||
[](https://goreportcard.com/report/github.com/absmach/supermq)
|
||||
[](https://deepwiki.com/absmach/supermq)
|
||||
[](https://github.com/absmach/supermq/actions/workflows/check-license.yaml)
|
||||
[](https://github.com/absmach/supermq/actions/workflows/check-generated-files.yaml)
|
||||
[](https://codecov.io/gh/absmach/supermq)
|
||||
[](LICENSE)
|
||||
[](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)
|
||||
[](https://github.com/absmach/supermq/actions/workflows/build.yaml)
|
||||
[](https://goreportcard.com/report/github.com/absmach/supermq)
|
||||
[](https://deepwiki.com/absmach/supermq)
|
||||
[](https://github.com/absmach/supermq/actions/workflows/check-license.yaml)
|
||||
[](https://github.com/absmach/supermq/actions/workflows/check-generated-files.yaml)
|
||||
[](https://codecov.io/gh/absmach/supermq)
|
||||
[](LICENSE)
|
||||
[](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! 🚀
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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}:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 channel’s 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..."
|
||||
}
|
||||
```
|
||||
@@ -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
@@ -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 client’s 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 role‑based 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) | Human‑readable 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 | Free‑form 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/
|
||||
|
||||
@@ -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
@@ -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": "<commit‑hash>",
|
||||
"description": "coap‑adapter service",
|
||||
"build_time": "YYYY‑MM‑DDT…"
|
||||
}
|
||||
```
|
||||
|
||||
## 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).
|
||||
|
||||
@@ -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
@@ -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 plugin‑style 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": "YYYY‑MM‑DDTHH: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/
|
||||
|
||||
@@ -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
@@ -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 Docker‑build 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
|
||||
```
|
||||
|
||||
@@ -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 domain’s 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/
|
||||
@@ -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
|
||||
|
||||
@@ -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 group’s 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/
|
||||
@@ -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
@@ -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/
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
```
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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.).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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/
|
||||
|
||||
@@ -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
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user