Stellio Create Subscription
The node creates an NGSI-LD subscription that instructs the broker to send a notification to a URL whenever entities of a type are created or changed, typically to a time series database. Before creating it, the node checks whether a subscription for the type already exists and thus avoids duplicates.
- Node type
- stellio-create-subscription
- Package
- @htag/node-red-contrib-hypertegrity-ngsi-ld
- Inputs / outputs
- 1 / 1
- Target
- Stellio context broker (NGSI-LD)
When to use this node
For historical values to end up in a time series database, the context broker has to report every change. A subscription per entity type takes care of that. This node sets it up with a proven default configuration: it watches one or more attributes, fires on created and updated entities and delivers notifications in normalised format.
Typical use cases are:
- Build time series: create a subscription to the time series database (for example QuantumLeap) after the first import of a new entity type.
- Deployment flows: make sure the subscription exists when a flow starts, triggered by an Inject node, without duplicating it on every run.
- Several types: pass the entity type via
msg.dataModeland create several subscriptions in a loop.
How the node works
Check configuration
API URL, tenant and data model must be present; placeholders in URLs are replaced from environment variables.
Check for duplicates
The node checks whether a subscription for the entity type already exists in the tenant.
Create or report
If no matching subscription exists, it is created via POST; otherwise the node reports the existing id.
Emit result
msg.payload contains the id and the status created or exists.
Result: Exactly one active subscription per entity type, whose id can be reused in the flow.
The node is message-driven and runs the sequence described above once per incoming message.
Configuration
| Field | Type | Default | Meaning |
|---|---|---|---|
| Name | Text | empty | Display name of the node in the flow. |
| NGSILD-Tenant | Text (required) | empty | Value of the NGSILD-Tenant header, for example ds_public_parking. |
| API URL | Text | ${STELLIO_API_URL} | Base URL of the broker. Placeholders ${VAR} are replaced from environment variables at runtime. |
| Data Model | Text (required) | empty | Entity type the subscription applies to, for example OffStreetParking. |
| Watched Attr. | Text | dateObserved | Watched attributes, comma-separated. Only changes to these attributes trigger a notification; this avoids duplicate notifications. |
| Notify URL | Text | see below | Receiver of the notifications. The default points to the notify endpoint of a QuantumLeap instance. Placeholders are replaced. |
| Context URL | Text | see below | JSON-LD context written into the @context field of the subscription. Placeholders are replaced. |
Default values of the URL fields:
Notify URL: ${QL_LD_API_URL}/v2/notify
Context URL: https://context.${DOMAIN}/main-context.jsonld
Input
| Property | Type | Meaning |
|---|---|---|
msg.tenant | string | Overrides the configured tenant. |
msg.dataModel | string | Overrides the configured data model (entity type). |
msg.payload | any | Not evaluated; the message only acts as trigger. |
Output
When a new subscription is created, msg.payload contains:
{
"id": "urn:ngsi-ld:Subscription:7f3a2c1e-0000-4000-8000-000000000001",
"status": "created",
"response": ""
}
If a subscription for the type already exists:
{
"id": "urn:ngsi-ld:Subscription:7f3a2c1e-0000-4000-8000-000000000001",
"status": "exists"
}
| Field | Meaning |
|---|---|
id | URN of the newly created subscription from the broker Location header, or of the already existing subscription. If the header is missing, the value is created. |
status | created (newly created) or exists (already present, nothing changed). |
response | Only for created: response body of the broker, usually empty with Stellio. |
The created subscription has the following structure (example for WeatherObserved):
{
"type": "Subscription",
"subscriptionName": "Subscription for entity type WeatherObserved.",
"description": "This subscription triggers everytime an entity from type WeatherObserved is updated. Only watching attribute dateObserved to avoid duplications.",
"entities": [{"type": "WeatherObserved"}],
"watchedAttributes": ["dateObserved"],
"notificationTrigger": ["entityCreated", "attributeCreated", "attributeUpdated"],
"notification": {
"format": "normalized",
"endpoint": {"uri": "https://quantumleap.exampletown.example/v2/notify", "accept": "application/json"}
},
"@context": ["https://context.exampletown.example/main-context.jsonld"]
}
Example flow
The package ships with a shared example flow for several Stellio nodes. Import it in Node-RED via Menu → Import → Examples → @htag/node-red-contrib-hypertegrity-ngsi-ld → stellio-helper-nodes. Alternatively download stellio-helper-nodes.json and import it via Menu → Import.
Inject
An Inject node triggers the creation manually, for example once after deploying the flow.
Create Subscription
The node creates a subscription for OffStreetParking that watches the attribute accessModified.
Debug
A Debug node shows id and status (created or exists).
Show example flow as JSON (Create Subscription excerpt)
[
{"id": "tab1", "type": "tab", "label": "Stellio Helper Nodes", "disabled": false, "info": ""},
{"id": "inject1", "type": "inject", "z": "tab1", "name": "", "props": [{"p": "payload"}], "repeat": "", "once": false, "payload": "", "payloadType": "date", "x": 100, "y": 540, "wires": [["create1"]]},
{"id": "create1", "type": "stellio-create-subscription", "z": "tab1", "name": "", "tenant": "ds_public_parking", "apiUrl": "${STELLIO_API_URL}", "dataModel": "OffStreetParking", "watchedAttributes": "accessModified", "notificationUrl": "${QL_LD_API_URL}/v2/notify", "contextUrl": "https://context.${DOMAIN}/main-context.jsonld", "x": 290, "y": 540, "wires": [["debug1"]]},
{"id": "debug1", "type": "debug", "z": "tab1", "name": "Subscription", "active": true, "tosidebar": true, "complete": "false", "x": 510, "y": 540, "wires": []}
]
Status and errors
| Indicator | Meaning |
|---|---|
| Blue dot "checking..." | Existing subscriptions are being loaded. |
| Blue dot "creating..." | The new subscription is being created. |
| Green dot "created" | Subscription created successfully. |
| Yellow dot "exists" | A subscription for the type already exists. The warnings "There is already a subscription for this type." and "Subscription already exists for type …" appear as well. |
| Red ring "error" with error message | The broker answered with an error status (for example "Request failed with status code 400") or is unreachable. No message is sent. |
| Error "Missing required configuration (API URL, Tenant, or Data Model)" | At least one required value is missing. No message is sent. |
Typical broker status codes: 201 (created), 400 (invalid subscription body or context), 409 (id already taken). Errors are reported via node.error and can be handled with a Catch node.
Notes
- Duplicate check: Before creating, the node checks whether a subscription for the entity type already exists and in that case creates no new one.
- Notification format: Notifications are normalised and sent as
application/json. The receiver must be able to resolve the NGSI-LD context itself. - Authentication: The node sends no authentication headers; access to the broker is protected by the network or an upstream gateway.
- Placeholders:
${STELLIO_API_URL},${QL_LD_API_URL}and${DOMAIN}must be set as environment variables of the Node-RED process; otherwise the placeholders remain in the text and the requests fail. - Personal data: The subscription itself contains no personal data. Note however that all entity changes of the type are forwarded to the receiver through it.