Skip to content

Commit

Permalink
Lead Resource Type documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielius1922 committed Jul 19, 2024
1 parent 0c16b29 commit 8c03c05
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 57 deletions.
1 change: 1 addition & 0 deletions content/en/docs/configuration/cloud2cloud-connector.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ plgd hub uses NATS messaging system as an event bus.
| `clients.eventBus.nats.tls.keyFile` | string | `File name of private key in PEM format.` | `""` |
| `clients.eventBus.nats.tls.certFile` | string | `File name of certificate in PEM format.` | `""` |
| `clients.eventBus.nats.tls.useSystemCAPool` | bool | `If true, use system certification pool.` | `false` |
| `clients.eventBus.nats.leadResourceType.enabled` | bool | `If true, subscribe to NATS with lead resource type subject token included.` | `false` |

### GRPC Gateway Client

Expand Down
1 change: 1 addition & 0 deletions content/en/docs/configuration/cloud2cloud-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ plgd hub uses NATS messaging system as an event bus.
| `clients.eventBus.nats.tls.keyFile` | string | `File name of private key in PEM format.` | `""` |
| `clients.eventBus.nats.tls.certFile` | string | `File name of certificate in PEM format.` | `""` |
| `clients.eventBus.nats.tls.useSystemCAPool` | bool | `If true, use system certification pool.` | `false` |
| `clients.eventBus.nats.leadResourceType.enabled` | bool | `If true, subscribe to NATS with lead resource type subject token included.` | `false` |

### GRPC Gateway Client

Expand Down
1 change: 1 addition & 0 deletions content/en/docs/configuration/coap-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ plgd hub uses NATS messaging system as an event bus.
| `clients.eventBus.nats.tls.keyFile` | string | `File name of private key in PEM format.` | `""` |
| `clients.eventBus.nats.tls.certFile` | string | `File name of certificate in PEM format.` | `""` |
| `clients.eventBus.nats.tls.useSystemCAPool` | bool | `If true, use system certification pool.` | `false` |
| `clients.eventBus.nats.leadResourceType.enabled` | bool | `If true, subscribe to NATS with lead resource type subject token included.` | `false` |

### Identity Store Client

Expand Down
1 change: 1 addition & 0 deletions content/en/docs/configuration/grpc-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ plgd hub uses NATS messaging system as a event bus.
| `clients.eventBus.nats.tls.keyFile` | string | `File name of private key in PEM format.` | `""` |
| `clients.eventBus.nats.tls.certFile` | string | `File name of certificate in PEM format.` | `""` |
| `clients.eventBus.nats.tls.useSystemCAPool` | bool | `If true, use system certification pool.` | `false` |
| `clients.eventBus.nats.leadResourceType.enabled` | bool | `If true, subscribe to NATS with lead resource type subject token included.` | `false` |

### Resource Aggregate Client

Expand Down
6 changes: 5 additions & 1 deletion content/en/docs/configuration/resource-aggregate.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,15 @@ plgd hub uses NATS messaging system as a event bus.
| ---------- | -------- | -------------- | ------- |
| `clients.eventBus.nats.url` | string | `URL to nats messaging system.` | `"nats://localhost:4222"` |
| `clients.eventBus.nats.flusherTimeout` | string | `Define flush timeout for publishing message.` | `"30s"` |
| `clients.eventBus.nats.jetstream`| bool | `If true, events will be published to jetstream.` | `false` |
| `clients.eventBus.nats.tls.caPool` | []string | `File paths to the root certificates in PEM format. The file may contain multiple certificates.` | `[]` |
| `clients.eventBus.nats.tls.keyFile` | string | `File name of private key in PEM format.` | `""` |
| `clients.eventBus.nats.tls.certFile` | string | `File name of certificate in PEM format.` | `""` |
| `clients.eventBus.nats.tls.useSystemCAPool` | bool | `If true, use system certification pool.` | `false` |
| `clients.eventBus.nats.jetstream`| bool | `If true, events will be published to jetstream.` | `false` |
| `clients.eventBus.nats.leadResourceType.enabled` | bool | `If true, publish events to NATS with lead resource type subject token included.` | `false` |
| `clients.eventBus.nats.leadResourceType.regexFilter` | []string | `List of regex expressions used to find resouce type that will be used as the lead resource type subject for resource-level events. The expressions are iterated in order and the first matched resource type of the resource associated with the event is used in the NATS subject.` | `[]` |
| `clients.eventBus.nats.leadResourceType.filter` | string | `Can contain values "first", "last" or be kept empty (""). If "first" is used then the first resource type of the resource associated with the event will be used as the lead resource type in the NATS subject. If "last" is used then the last resource type is used in the NATS subject. If both "regexFilter" and "filter" properties are set then "regexFilter" takes precedence and "filter" is only examined if no resource type is matched by "regexFilter".` | `""` |
| `clients.eventBus.nats.leadResourceType.useUUID` | bool | `If true then do not use the selected resource type as a token directly, but encode it into a UUID string.` | `false` |

### Event Store

Expand Down
1 change: 1 addition & 0 deletions content/en/docs/configuration/resource-directory.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ plgd hub uses NATS messaging system as a event bus.
| `clients.eventBus.nats.tls.keyFile` | string | `File name of private key in PEM format.` | `""` |
| `clients.eventBus.nats.tls.certFile` | string | `File name of certificate in PEM format.` | `""` |
| `clients.eventBus.nats.tls.useSystemCAPool` | bool | `If true, use system certification pool.` | `false` |
| `clients.eventBus.nats.leadResourceType.enabled` | bool | `If true, subscribe to NATS with lead resource type subject token included.` | `false` |

### Event Store

Expand Down
56 changes: 0 additions & 56 deletions content/en/docs/features/control-plane/jetstream.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,62 +17,6 @@ There are still some edge-cases when the plgd event couldn't be published to the
More information about the JetStream can be found [here](https://docs.nats.io/jetstream).
{{< /note >}}

## NATS subjects overview

### Definitions

- `ownerID` is the owner of the device. It is calculated as `uuid.NewV5(uuid.NamespaceURL, value of JWT ownerClaim)`.
- `deviceID` is the UUID of the device.
- `hrefID` is the identifier of resource. It is calculated as `uuid.NewV5(uuid.NamespaceURL, href)`, where the `href` is a resource path. (eg "/oic/d").

### Device events

Each event is compressed by [snappy](https://github.com/google/snappy) and encoded in protobuf [devices event envelope](https://github.com/plgd-dev/hub/blob/main/resource-aggregate/cqrs/eventbus/pb/eventbus.proto). The event envelope consist of `Event.data` containing the event and `Event.event_type` describing the type of the event.

#### Resource links

- `plgd.owners.{ownerID}.devices.{deviceID}.resource-links.{eventType}` publishes resource-links events of types `resourcelinkspublished`, `resourcelinksunpublished`, `resourcelinkssnapshottaken` for device `deviceID` and `ownerID`

#### Metadata events

- `plgd.owners.{ownerID}.devices.{deviceID}.metadata.{eventType}` publishes metadata events of types `devicemetadataupdatepending`,`devicemetadataupdated`, `devicemetadatasnapshottaken` for device `deviceID` and `ownerID`

#### Resources events

- `plgd.owners.{ownerID}.devices.{deviceID}.resources.{hrefID}.{eventType}` publishes resources events of types `resourcechanged`, `resourcecreated`, `resourcecreatepending`, `resourcedeleted` `resourcedeletepending`, `resourceretrieved`, `resourceretrievepending`, `resourcestatesnapshottaken`, `resourceupdated`, `resourceupdatepending` for resource `hrefID`, `deviceID` and `ownerID`.

### Owner events

Each event is encoded in protobuf [event envelope](https://github.com/plgd-dev/hub/blob/main/authorization/pb/events.proto) and then compressed by [snappy](https://github.com/google/snappy).

#### Registration events

- `plgd.owners.{ownerID}.registrations.{eventType}` publishes owner events of types `devicesregistered`,`devicesunregistered` for `ownerID`.

### Consumer subscriptions options

For the consumers of events you can subscribe to:

- `plgd.owners.>` retrieves all events of the hub.
- `plgd.owners.{ownerId}.>` retrieves all events of the owner with the `ownerId`.
- `plgd.owners.*.devices.{deviceId}.>` retrieves all events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resource-links.>` retrieves all resource link events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resource-links.resourcelinkspublished` retrieves the `resourcelinkspublished` event of the device with the `deviceId`.
- `plgd.owners.*.devices.*.resource-links.>` retrieves all resource link events of all devices.
- `plgd.owners.{ownerId}.devices.*.resource-links.>` retrieves all resource link events of all devices belonging to the owner with the `ownerId`.
- `plgd.owners.*.devices.{deviceId}.metadata.>` retrieves all metadata events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.metadata.devicemetadataupdated` retrieves the `devicemetadataupdated` event of the device with the `deviceId`.
- `plgd.owners.*.devices.*.metadata.>` retrieves all metadata events of all devices.
- `plgd.owners.{ownerId}.devices.*.metadata.>` retrieves all metadata events of all devices belonging to the owner with the `ownerId`.
- `plgd.owners.*.devices.{deviceId}.resources.>` retrieves all resource events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resources.{hrefId}.>` retrieves all events of the resource with the `hrefId` for the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resources.{hrefId}.resourcechanged` retrieves the `resourcechanged` events of the resource with the `hrefId` for the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resources.*.resourcechanged` retrieves the `resourcechanged` events of all resources for the device with the `deviceId`.
- `plgd.owners.*.devices.*.resources.*.resourcechanged` retrieves the `resourcechanged` events of all resources for all devices.
- `plgd.owners.*.devices.*.resources.{hrefId}.resourcechanged` retrieves the `resourcechanged` events of the resource with the `hrefId` for all devices.
- `plgd.owners.{ownerId}.devices.*.resources.*.resourcechanged` retrieves the `resourcechanged` events of all resources for all devices belonging to the owner with the `ownerId`.
- `plgd.owners.{ownerId}.devices.*.resources.{hrefId}.resourcechanged` retrieves the `resourcechanged` events of the resource with the `hrefId` for all devices belonging to the owner with the `ownerId`.

## Enable JetStream

{{< note >}}
Expand Down
192 changes: 192 additions & 0 deletions content/en/docs/features/control-plane/nats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
---
title: 'NATS'
description: 'How does plgd publish and subscribe to events?'
date: '2024-07-18'
categories: [features]
keywords: ['events', 'nats']
weight: 75
---

Plgd hub services use NATS as an EventBus and MongoDB as an EventStore.

## NATS Subjects Overview

### Definitions

- `ownerID`: The owner of the device, calculated as `uuid.NewV5(uuid.NamespaceURL, value of JWT ownerClaim)`.
- `deviceID`: The UUID of the device.
- `hrefID`: The identifier of a resource, calculated as `uuid.NewV5(uuid.NamespaceURL, href)`, where `href` is a resource path (e.g., "/oic/d").
- `leadResourceType`: The selected resource type for resource events.
- `leadResourceTypeID`: The identifier of the selected resource type, calculated as `uuid.NewV5(uuid.NamespaceURL, resourceType)`, where `resourceType` is a resource type (e.g., "oic.wk.d").

### Device Events

Each event is compressed by [snappy](https://github.com/google/snappy) and encoded in protobuf [devices event envelope](https://github.com/plgd-dev/hub/blob/main/resource-aggregate/cqrs/eventbus/pb/eventbus.proto). The event envelope consists of `Event.data` containing the event and `Event.event_type` describing the type of the event.

#### Resource Links

- `plgd.owners.{ownerID}.devices.{deviceID}.resource-links.{eventType}` publishes resource-links events of types `resourcelinkspublished`, `resourcelinksunpublished`, and `resourcelinkssnapshottaken` for device `deviceID` and `ownerID`.

#### Metadata Events

- `plgd.owners.{ownerID}.devices.{deviceID}.metadata.{eventType}` publishes metadata events of types `devicemetadataupdatepending`, `devicemetadataupdated`, and `devicemetadatasnapshottaken` for device `deviceID` and `ownerID`.

#### Resource Events

- `plgd.owners.{ownerID}.devices.{deviceID}.resources.{hrefID}.{eventType}` publishes resource events of types `resourcechanged`, `resourcecreated`, `resourcecreatepending`, `resourcedeleted`, `resourcedeletepending`, `resourceretrieved`, `resourceretrievepending`, `resourcestatesnapshottaken`, `resourceupdated`, and `resourceupdatepending` for resource `hrefID`, `deviceID`, and `ownerID`.

##### Lead Resource Type

The Lead Resource Type feature in the plgd hub allows for the specification and handling of a primary resource type for resource events. It is disabled by default but can be enabled through configuration settings for both NATS publishers and subscribers.

###### Configuration

To enable the Lead Resource Type feature, modify the YAML configuration files of your service:

1. **Publisher Configuration:**

```yaml
leadResourceType:
enabled: {bool value}
regexFilter: {array of REGEX expressions}
filter: {"first", "last", or ""}
useUUID: {bool value}
```
2. **Subscriber Configuration:**
```yaml
leadResourceType:
enabled: {bool value}
```
###### Subjects with Lead Resource Type
When enabled, the subject is modified based on the selected resource type. If the resource type is not empty, the subject will include the `leadrt` prefix and the resource type as a string. If `useUUID` is set to true, the resource type is encoded to a UUID string. The subject format is modified as follows:

1. **With `useUUID=false`:**

```text
plgd.owners.{ownerID}.devices.{deviceID}.resources.{hrefID}.{eventType}.leadrt.{leadResourceType}
```

2. **With `useUUID=true`:**

```text
plgd.owners.{ownerID}.devices.{deviceID}.resources.{hrefID}.{eventType}.leadrt.{leadResourceTypeID}
```

3. **When the resource type is empty:**

```text
plgd.owners.{ownerID}.devices.{deviceID}.resources.{hrefID}.{eventType}.leadrt
```

Even when no resource type is selected, the `leadrt` token is added to the subject, allowing the use of the `.>` wildcard to subscribe to resource events with no or any lead resource type.

###### Selecting the Lead Resource Type

The lead resource type for a given resource is selected based on the following criteria:

- **Regex Filter:**
- `regexFilter` is an array of regex expressions used to match resource types.
- The first matching resource type in the array is used.

- **Filter:**
- `filter` is an enumeration of string values ("first", "last").
- If `regexFilter` does not match any resource type, the `filter` property determines which resource type to use:
- If `filter` is "first", the first resource type is used.
- If `filter` is "last", the last resource type is used.
- Otherwise, no resource type is used.

The algorithm for selecting the lead resource type is as follows:

```pseudocode
# Iterate regexFilter first
iterate resource types of given resource
iterate regexFilter expressions
if the expression matches the resource type
use the resource type
# regexFilter was empty or no resource type was matched
if filter equals "first"
use the first resource type
else if filter equals "last"
use the last resource type
else
don't use resource type
```

###### Configure Lead Resource Type at plgd #bundle

The following environmental variables can be used to configure the Lead Resource Type feature for plgd #bundle:

- set `LEAD_RESOURCE_TYPE_ENABLED`, `LEAD_RESOURCE_TYPE_USE_UUID` to boolean values
- set `LEAD_RESOURCE_TYPE_FILTER` to "first", "last" or ""
- set `LEAD_RESOURCE_TYPE_REGEX_FILTER` to comma separated list of REGEX expressions

For example:

```bash
LEAD_RESOURCE_TYPE_ENABLED=true
LEAD_RESOURCE_TYPE_FILTER="last"
LEAD_RESOURCE_TYPE_REGEX_FILTER="^oic.*,core.*"
LEAD_RESOURCE_TYPE_USE_UUID=true
```

```bash
docker run -it --rm -e LEAD_RESOURCE_TYPE_ENABLED=true -e LEAD_RESOURCE_TYPE_FILTER="last" -e LEAD_RESOURCE_TYPE_REGEX_FILTER="^oic.*,core.*" -e LEAD_RESOURCE_TYPE_USE_UUID=true --network=host -v `pwd`/.tmp/data:/data ghcr.io/plgd-dev/hub/bundle:latest
```

The Lead Resource Type feature modifies the way resource events are published and subscribed to in NATS, allowing more granular control over the subjects used. This enhances the efficiency and clarity of event handling within the plgd hub.

### Owner events

Each event is encoded in protobuf [event envelope](https://github.com/plgd-dev/hub/blob/main/authorization/pb/events.proto) and then compressed by [snappy](https://github.com/google/snappy).

#### Registration events

- `plgd.owners.{ownerID}.registrations.{eventType}` publishes owner events of types `devicesregistered`,`devicesunregistered` for `ownerID`.

### Consumer subscriptions options

For the consumers of events you can subscribe to:

- `plgd.owners.>` retrieves all events of the hub.
- `plgd.owners.{ownerId}.>` retrieves all events of the owner with the `ownerId`.
- `plgd.owners.*.devices.{deviceId}.>` retrieves all events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resource-links.>` retrieves all resource link events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resource-links.resourcelinkspublished` retrieves the `resourcelinkspublished` event of the device with the `deviceId`.
- `plgd.owners.*.devices.*.resource-links.>` retrieves all resource link events of all devices.
- `plgd.owners.{ownerId}.devices.*.resource-links.>` retrieves all resource link events of all devices belonging to the owner with the `ownerId`.
- `plgd.owners.*.devices.{deviceId}.metadata.>` retrieves all metadata events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.metadata.devicemetadataupdated` retrieves the `devicemetadataupdated` event of the device with the `deviceId`.
- `plgd.owners.*.devices.*.metadata.>` retrieves all metadata events of all devices.
- `plgd.owners.{ownerId}.devices.*.metadata.>` retrieves all metadata events of all devices belonging to the owner with the `ownerId`.
- `plgd.owners.*.devices.{deviceId}.resources.>` retrieves all resource events of the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resources.{hrefId}.>` retrieves all events of the resource with the `hrefId` for the device with the `deviceId`.

If the Lead Resource Type feature is disabled:

- `plgd.owners.*.devices.{deviceId}.resources.{hrefId}.resourcechanged` retrieves the `resourcechanged` events of the resource with the `hrefId` for the device with the `deviceId`.
- `plgd.owners.*.devices.{deviceId}.resources.*.resourcechanged` retrieves the `resourcechanged` events of all resources for the device with the `deviceId`.
- `plgd.owners.*.devices.*.resources.*.resourcechanged` retrieves the `resourcechanged` events of all resources for all devices.
- `plgd.owners.*.devices.*.resources.{hrefId}.resourcechanged` retrieves the `resourcechanged` events of the resource with the `hrefId` for all devices.
- `plgd.owners.{ownerId}.devices.*.resources.*.resourcechanged` retrieves the `resourcechanged` events of all resources for all devices belonging to the owner with the `ownerId`.
- `plgd.owners.{ownerId}.devices.*.resources.{hrefId}.resourcechanged` retrieves the `resourcechanged` events of the resource with the `hrefId` for all devices belonging to the owner with the `ownerId`.

With the Lead Resource Type feature enabled, the equivalent subjects are modified to:

- `plgd.owners.*.devices.{deviceId}.resources.{hrefId}.resourcechanged.leadrt.{leadResourceType}`
- `plgd.owners.*.devices.{deviceId}.resources.*.resourcechanged.>`
- `plgd.owners.*.devices.*.resources.*.resourcechanged.>`
- `plgd.owners.*.devices.*.resources.{hrefId}.resourcechanged.>`
- `plgd.owners.{ownerId}.devices.*.resources.*.resourcechanged.>`
- `plgd.owners.{ownerId}.devices.*.resources.{hrefId}.resourcechanged.>`

These subscription options provide flexibility for consumers to filter events based on specific criteria, such as device ID, owner ID, and resource ID, and they also support wildcard subscriptions for broader event capture.

## Conclusion

This documentation provides an overview of how plgd hub services utilize NATS for publishing and subscribing to events. By understanding the structure of NATS subjects and the configuration options available, users can effectively manage and consume events within the plgd ecosystem.
The Lead Resource Type feature adds an additional layer of control, enabling more precise event handling based on resource types.

0 comments on commit 8c03c05

Please sign in to comment.