shadows

package
v0.43.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

README

Shadows Service

The Shadows service maintains a device shadow for each thing — a persisted record holding the thing's last reported state and its desired state. It lets users read and set a device's state even while the device is offline, and aligns the two whenever the device reconnects.

Shadows

A shadow is a single record per thing.

Field Description
thing_id ID of the thing the shadow belongs to (UUID)
state Nested object holding the desired, reported, and delta states (see below)
reported_at Unix timestamp (seconds) of the last reported-state update
updated_at Unix timestamp (seconds) of the last desired-state update
State

desired, reported, and delta are each a free-form JSON object (a set of key/value pairs).

Field Description
desired State the application wants the device to reach.
reported State the device last reported. Merged from the device's telemetry messages.
delta Computed subset of desired whose values differ from (or are absent in) reported. Omitted when empty.

The delta is derived on read and on every state change; it is never stored directly. Keys present only in reported are not part of the delta.

How it works

  • Desired state is set by a user through the HTTP API (PUT /things/{id}/shadows). On update, the service recomputes the delta and publishes it to the device on its command subject (things.<id>.commands.shadow, protocol shadows).
  • Reported state is updated automatically as the thing publishes messages. The service consumes messages from the broker, flattens each into a state patch, and merges the patch into reported (no-op writes are skipped).
  • On each reported-state change, any still-pending delta is re-published, so a reconnecting device receives commands it missed while offline.

Authorization is delegated to the Things service: reading a shadow requires viewer access on the thing's group, while updating or removing a shadow requires editor access.

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.

Variable Description Default
MF_SHADOWS_LOG_LEVEL Log level for the Shadows service (debug, info, warn, error) error
MF_BROKER_URL Message broker instance URL nats://localhost:4222
MF_SHADOWS_HTTP_PORT Shadows service HTTP port 9031
MF_JAEGER_URL Jaeger server URL for distributed tracing. Leave empty to disable tracing.
MF_SHADOWS_DB_HOST Database host address localhost
MF_SHADOWS_DB_PORT Database host port 5432
MF_SHADOWS_DB_USER Database user mainflux
MF_SHADOWS_DB_PASS Database password mainflux
MF_SHADOWS_DB Name of the database used by the service shadows
MF_SHADOWS_DB_SSL_MODE Database connection SSL mode (disable, require, verify-ca, verify-full) disable
MF_SHADOWS_DB_SSL_CERT Path to the PEM encoded certificate file
MF_SHADOWS_DB_SSL_KEY Path to the PEM encoded key file
MF_SHADOWS_DB_SSL_ROOT_CERT Path to the PEM encoded root certificate file
MF_SHADOWS_CLIENT_TLS Flag that indicates if TLS should be turned on false
MF_SHADOWS_CA_CERTS Path to trusted CAs in PEM format
MF_SHADOWS_SERVER_CERT Path to server certificate in PEM format
MF_SHADOWS_SERVER_KEY Path to server key in PEM format
MF_THINGS_AUTH_GRPC_URL Things service Auth gRPC URL localhost:8183
MF_THINGS_AUTH_GRPC_TIMEOUT Things service Auth gRPC request timeout in seconds 1s
MF_AUTH_GRPC_URL Auth service gRPC URL localhost:8181
MF_AUTH_GRPC_TIMEOUT Auth service gRPC request timeout in seconds 1s
MF_SHADOWS_ES_URL Event store URL redis://localhost:6379/0

Deployment

The service itself is distributed as Docker container. Check the shadows service section in docker-compose to see how service is deployed.

To start the service, execute the following shell script:

# Download the latest version of the service
git clone https://github.com/MainfluxLabs/mainflux

cd mainflux

# compile the shadows service
make shadows

# Copy binary to bin
make install

# Set the environment variables and run the service
MF_SHADOWS_LOG_LEVEL=[Shadows log level] \
MF_BROKER_URL=[Message broker instance URL] \
MF_SHADOWS_HTTP_PORT=[Shadows service HTTP port] \
MF_SHADOWS_DB_HOST=[Database host address] \
MF_SHADOWS_DB_PORT=[Database host port] \
MF_SHADOWS_DB_USER=[Database user] \
MF_SHADOWS_DB_PASS=[Database password] \
MF_SHADOWS_DB=[Shadows database name] \
MF_THINGS_AUTH_GRPC_URL=[Things service Auth gRPC URL] \
MF_THINGS_AUTH_GRPC_TIMEOUT=[Things service Auth gRPC request timeout] \
MF_AUTH_GRPC_URL=[Auth service gRPC URL] \
MF_AUTH_GRPC_TIMEOUT=[Auth service gRPC request timeout] \
$GOBIN/mainfluxlabs-shadows

Usage

For the full HTTP API reference, see the OpenAPI specification.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Service

type Service interface {
	// UpdateDesiredState replaces the thing's desired state, pushes the
	// resulting delta to the device, and returns the updated shadow.
	UpdateDesiredState(ctx context.Context, token, thingID string, desired State) (Shadow, error)

	// ViewShadow returns the thing's shadow with its delta populated.
	ViewShadow(ctx context.Context, token, thingID string) (Shadow, error)

	// RemoveShadow removes the thing's shadow.
	RemoveShadow(ctx context.Context, token, thingID string) error

	// RemoveByThing removes the shadow for the given thing without an auth check.
	RemoveByThing(ctx context.Context, thingID string) error

	consumers.MessageConsumer
}

Service specifies the API offered by the shadows service. All methods that accept a token use it to identify and authorize the user.

func New

New instantiates the shadows service.

type Shadow

type Shadow struct {
	ThingID    string
	Desired    State
	Reported   State
	Delta      State
	ReportedAt int64
	UpdatedAt  int64
}

Shadow is the persisted state of a single thing. Delta is derived from Desired and Reported and populated by the service on read.

type ShadowRepository

type ShadowRepository interface {
	// UpsertDesiredState sets the thing's desired state.
	UpsertDesiredState(ctx context.Context, thingID string, desired State, updatedAt int64) (Shadow, error)

	// UpsertReportedState sets the thing's reported state.
	UpsertReportedState(ctx context.Context, thingID string, reported State, reportedAt int64) error

	// RetrieveByThing returns the shadow for the given thing ID.
	RetrieveByThing(ctx context.Context, thingID string) (Shadow, error)

	// Remove deletes the shadow for the given thing ID.
	Remove(ctx context.Context, thingID string) error
}

ShadowRepository specifies the persistence API for shadows.

type State

type State map[string]any

State is a free-form set of key/value pairs describing device state.

Directories

Path Synopsis
api

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL