Skip to main content

Declarative Scenarios for Services Provisioning

For certain tasks, it is convenient to use two key concepts stored in the database:

  • Predefined scenarios (action templates)
  • A set of variables for each device

In our system:

  • ServiceDefinitions — represent the set of variables for devices (stored in the database)
  • ServiceScenario — defines the scenario, describing what needs to be done (also stored in the database)

When a service needs to be applied to devices, Services are created and executed via a campaign. The system retrieves the scenario from the database, substitutes variables from ServiceDefinitions, and performs the tasks on the device (CPE).

Thus:

  • ServiceDefinitions - define device parameters
  • ServiceScenario - define the action logic
  • Services + Campaign - create and execute specific tasks for CPE

Creating ServiceScenario Service

A ServiceScenario meta Service will contain all necessary mappings between high-level parameters and corresponding actions on the device. This abstraction layer allows service providers to define services once and apply them across different device types and data models.

Note: NB methods will simplify the transfer of all scenarios between Staging and Production environments, ensuring consistency across deployments.

ServiceScenario Structure

Each ServiceScenario consists of:

  • target_servicetype - Service being provisioned (e.g., PortMapping, WiFi, Firewall)

  • target_action - An action to perform (e.g., activate, deactivate, modify)

  • target_classname - The name of the CPE Class for which this scenario is intended, this applies to CPEs belonging to the specified class, a value of "*" indicates that the scenario applies to all CPEs, regardless of their class

  • scenario - An array of Search Path expressions and Service parameter mappings

The scenario is structured as an array of mapping objects, where each object represents a group of parameters that will be set in a single operation:

[
// Declarative parameters for Step 1
{"<Search Path expression>": "<Value>"},

// Declarative parameters for Step 2
{"<Search Path expression>": "<Value>"},

...
]

Value could be:

  • Literal: string, integer, boolean Example: "Ignore", 55, true

  • Service parameters key: value will be mapped to Service actual Example: "{internal_port}" -> "9999"

  • Dict with the Service parameters key (value) and the type to which the value should be cast (type): Example: {"value": "{external_port}", "type": "int"} -> 9999

This approach offers several advantages:

  • Logical grouping of related parameters

  • Better readability of the provisioning logic

  • Simplified troubleshooting when issues occur

  • The ability to handle device-specific parameters gracefully: you can provide groups both for TR-098 and TR-181, the one that is not supported will be ignored

CPE Class Priority Management

If a CPE is associated with multiple CPE Classes, and multiple ScenarioService instances exist for a given action and service type for those CPE Classes, the system will select the ScenarioService from the CPE Class with the highest priority.

ServiceScenario Service Definition:

{
"servicetype": "ServiceScenario",
"createNBI": true,
"allowForPortal": false,
"attachedToDefaultService": false,
"refCPE": null,
"enableActions": true,
"actions": [
"add",
"delete",
"update"
],
"enableHistory": false,
"primaryKey": [
"target_servicetype",
"target_action",
"target_classname"
],
"isMeta": true,
"parameters": [
{
"name": "target_servicetype",
"typeValue": "str",
"comment": "Target Service Type",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": true,
"optional": false,
"searchable": true
},
{
"name": "target_action",
"typeValue": "str",
"comment": "Target Service Action",
"restrictions": {
"enumeration": [
"activate",
"reactivate",
"deactivate",
"restore",
"status"
]
},
"hidden": false,
"defaultValue": null,
"changeable": true,
"optional": false,
"searchable": false
},
{
"name": "target_classname",
"typeValue": "str",
"comment": "Target CPE Class. \"*\" matches all CPE Classes",
"restrictions": {},
"hidden": false,
"defaultValue": "*",
"changeable": true,
"optional": false,
"searchable": true
},
{
"name": "comment",
"typeValue": "str",
"comment": "Comment",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": true,
"optional": true,
"searchable": true
},
{
"name": "scenario",
"typeValue": "JSON",
"comment": "Service Scenario",
"restrictions": {
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"anyOf": [
{
"$ref": "#/definitions/stepDef"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/stepDef"
}
}
],
"definitions": {
"stepDef": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
},
{
"type": "boolean"
},
{
"type": "object",
"required": [
"value",
"type"
],
"properties": {
"value": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
},
{
"type": "boolean"
}
]
},
"type": {
"type": "string",
"enum": [
"int",
"str",
"boolean"
]
}
},
"additionalProperties": false
}
]
}
}
}
}
},
"hidden": false,
"defaultValue": "{}",
"changeable": true,
"optional": false,
"searchable": false
}
]
}


Service Examples

PortMapping Service

PortMapping is a common service that requires finding the proper rule or creating a new one and setting required parameters to forward external traffic to internal devices.

Creating Service Definition

{
"servicetype": "PortMapping",
"createNBI": true,
"allowForPortal": false,
"attachedToDefaultService": false,
"refCPE": null,
"enableActions": true,
"actions": [
"activate",
"deactivate",
"status",
"restore"
],
"enableHistory": false,
"primaryKey": [
"cpeid",
"external_port"
],
"isMeta": false,
"parameters": [
{
"name": "external_port_range_end",
"typeValue": "int",
"comment": "End Port Range",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": false,
"optional": false,
"searchable": true
},
{
"name": "protocol",
"typeValue": "str",
"comment": "protocol",
"restrictions": {
"enumeration": [
"TCP",
"UDP"
]
},
"hidden": false,
"defaultValue": null,
"changeable": false,
"optional": false,
"searchable": true
},
{
"name": "internal_ip",
"typeValue": "str",
"comment": "internal_ip",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": false,
"optional": false,
"searchable": true
},
{
"name": "internal_port",
"typeValue": "int",
"comment": "Internal Port",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": false,
"optional": false,
"searchable": true
},
{
"name": "external_port",
"typeValue": "int",
"comment": "External Port",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": false,
"optional": false,
"searchable": true
},
{
"name": "name",
"typeValue": "text",
"comment": "Description",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": false,
"optional": false,
"searchable": true
}
]
}

This Service Definition allows us to create new portmapping services using a standardized format with a primary key:

{
"ServiceIdentifiers": {
"cpeid": "tp181-portmapping",
"external_port": 9999
},
"ServiceParameters": {
"external_port_range_end": 9999,
"protocol": "UDP",
"internal_ip": "192.168.1.1",
"internal_port": 9999,
"external_port": 9999,
"name": "test"
}
}

Creating a ServiceScenario

ServiceScenarios describe the mapping between ServiceParameters and parameters on the CPE device. We'll use a universal approach that works with both TR-181 and TR-98 data models.

Important Notes:

  • Parameters that cannot be found on a specific CPE will be gracefully ignored

  • This enables support for vendor-specific parameters without breaking the scenario

  • Parameter mappings are grouped and applied in steps via different SetParameterValues operations

  • This approach improves readability and troubleshooting of the provisioning logic

Activate

The activate action creates or configures a portmapping rule on the device. Here's the ServiceScenario for activation:

{
"target_action": "activate",
"target_servicetype": "PortMapping",
"target_classname": "TR098",
"scenario": [
{
"~InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].ExternalPort": "{external_port}"
},
{
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].X_AX69": "Ignore",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingEnabled": true,
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingProtocol": "{protocol}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingDescription": "{name}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalPort": "{internal_port}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalClient": "{internal_ip}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].ExternalPortEndRange": "{external_port_range_end}"
}
]
}

{
"target_action": "activate",
"target_servicetype": "PortMapping",
"target_classname": "TR181",
"scenario": [
{
"~Device.NAT.PortMapping.[ExternalPort=={external_port}].ExternalPort": "{external_port}"
},
{
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Enable": true,
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Protocol": "{protocol}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Description": "{name}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].InternalPort": "{internal_port}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].InternalClient": "{internal_ip}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].ExternalPortEndRange": "{external_port_range_end}"
}
]
}

Explanation of the Activate Scenario

First Step: Creates a portmapping entry in the TR-98 data model if it doesn't exist

  • The ~ prefix ensures the object is created if it doesn't exist

  • The search expression [ExternalPort=={external_port}] finds the rule or creates it

  • {external_port} is replaced with the actual value from ServiceParameters

Second Step: Configures all TR-98 portmapping parameters

  • Sets internal port, IP, description, and enables the rule

  • Note that X_AX69 is a vendor-specific parameter and will be ignored if not present

Third Step: Creates a portmapping entry in the TR-181 data model if it doesn't exist

  • Similar to step 1, but using the TR-181 data model path

Fourth Step: Configures all TR-181 portmapping parameters

  • Sets the protocol, description, ports, and client IP

  • Includes the external port end range for port range mappings

This structure allows the same service to work across different devices supporting either TR-98 or TR-181 data models. If a device only supports one data model, the steps for the other model will be gracefully ignored.

Deactivate

The deactivate action disables a portmapping rule on the device without removing it, allowing for easy reactivation later:

{
"target_action": "deactivate",
"target_servicetype": "PortMapping",
"target_classname": "TR098",
"scenario": [
{
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingEnabled": false
}
]
}
{
"target_action": "deactivate",
"target_servicetype": "PortMapping",
"target_classname": "TR181",
"scenario": [
{
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Enable": false
}
]
}

Explanation of the Deactivate Scenario

First Step: Disables the portmapping in the TR-181 data model

  • Sets the Enable parameter to false

  • Uses the search expression to find the correct rule by external port

Second Step: Disables the portmapping in the TR-98 data model

  • Sets the PortMappingEnabled parameter to false

  • Uses the same search expression approach

The deactivate action is simpler than activate because it only needs to disable existing rules without creating or configuring them.

Status
{
"target_action": "status",
"target_servicetype": "PortMapping",
"target_classname": "TR098",
"scenario": {
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingEnabled": true,
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingProtocol": "{protocol}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingDescription": "{name}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].ExternalPort": {
"type": "int",
"value": "{external_port}"
},
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalPort": {
"type": "int",
"value": "{internal_port}"
},
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalClient": "{internal_ip}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].ExternalPortEndRange": {
"type": "int",
"value": "{external_port_range_end}"
}
}
}

{
"target_action": "status",
"target_servicetype": "PortMapping",
"target_classname": "TR181",
"scenario": {
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Enable": true,
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Protocol": "{protocol}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Description": "{name}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].ExternalPort": {
"type": "int",
"value": "{external_port}"
},
"Device.NAT.PortMapping.[ExternalPort=={external_port}].InternalPort": {
"type": "int",
"value": "{internal_port}"
},
"Device.NAT.PortMapping.[ExternalPort=={external_port}].InternalClient": "{internal_ip}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].ExternalPortEndRange": {
"type": "int",
"value": "{external_port_range_end}"
}
}
}

Explanation of the Status Scenario

First (and only) Step: Compares CPE's actual values with target values for existing parameters

  • For TR-098 CPE TR-181 data model parameters will be ignored

  • For TR-181 CPE TR-098 data model parameters will be ignored

HSI Service

HSI is a common service that requires finding the proper WAN PPPoE connection or PPP interface or creating a new one and setting credentials and other required parameters optionally.

Creating Service Definition

{
"servicetype": "HSI",
"createNBI": true,
"allowForPortal": false,
"attachedToDefaultService": false,
"refCPE": null,
"enableActions": true,
"actions": [
"activate",
"deactivate",
"status",
"restore"
],
"enableHistory": false,
"primaryKey": [
"cpeid"
],
"isMeta": false,
"parameters": [
{
"name": "username",
"typeValue": "str",
"comment": "PPPoE Username",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": true,
"optional": false,
"searchable": true
},
{
"name": "password",
"typeValue": "str",
"comment": "PPPoE Password",
"restrictions": {},
"hidden": true,
"defaultValue": null,
"changeable": true,
"optional": false,
"searchable": false
}
]
}

This Service Definition allows us to configure WAN PPPoE connection or PPP interface for specific CPE:

{
"ServiceIdentifiers": {
"cpeid": "DMS_DEVICE"
},
"ServiceParameters": {
"username": "inet",
"password": "supersecure"
}
}

Creating a ServiceScenario

Activate

The activate action creates and/or configures a WAN PPPoE connection or PPP interface on the device. Here's the ServiceScenario for activation:

{
"target_action": "activate",
"target_servicetype": "HSI",
"target_classname": "TR098",
"scenario": [
{
"~InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.[Name=='HSI'].Name": "HSI"
},
{
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.[Name=='HSI'].Password": "{ppp_password}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.[Name=='HSI'].Username": "{ppp_username}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.[Name=='HSI'].Enable": true
}
]
}
{
"target_action": "activate",
"target_servicetype": "HSI",
"target_classname": "TR181",
"scenario": [
{
"~Device.PPP.Interface.[Name=='HSI'].Name": "HSI"
},
{
"Device.PPP.Interface.[Name=='HSI'].Password": "{ppp_password}",
"Device.PPP.Interface.[Name=='HSI'].Username": "{ppp_username}",
"Device.PPP.Interface.[Name=='HSI'].Enable": true
}
]
}

Explanation of the Activate Scenario

First Step: Creates a WAN PPPoE connection entry in the TR-98 data model if it doesn't exist

  • The ~ prefix ensures the object is created if it doesn't exist

  • The search expression [Name=='HSI'] finds the connection or creates it

Second Step: Configures all required TR-98 WAN PPPoE connection parameters

  • Sets credentials and enables it

Third Step: Creates a PPP interface entry in the TR-181 data model if it doesn't exist

  • Similar to step 1, but using the TR-181 data model path

Fourth Step: Configures all required TR-181 PPP interface parameters

  • Similar to step 2, but using the TR-181 data model path

This structure allows the same service to work across different devices supporting either TR-98 or TR-181 data models. If a device only supports one data model, the steps for the other model will be gracefully ignored.

Deactivate

The deactivate action disables a WAN PPPoE connection or PPP interface on the device without removing it, allowing for easy reactivation later:

{
"target_action": "deactivate",
"target_servicetype": "HSI",
"target_classname": "TR098",
"scenario": [
{
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.[Name=='HSI'].Enable": false
}
]
}
{
"target_action": "deactivate",
"target_servicetype": "HSI",
"target_classname": "TR181",
"scenario": [
{
"Device.PPP.Interface.[Name=='HSI'].Enable": false
}
]
}

Explanation of the Deactivate Scenario

First Step: Disables the WAN PPPoE connection in the TR-98 data model

  • Sets the Enable parameter to false

  • Uses the same search expression approach

Second Step: Disables the PPP interface in the TR-181 data model

  • Sets the Enable parameter to false

  • Uses the same search expression approach

Status
{
"target_action": "status",
"target_servicetype": "HSI",
"target_classname": "TR098",
"scenario": {
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.[Name=='HSI'].Username": "{ppp_username}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.[Name=='HSI'].Enable": true
}
}

{
"target_action": "status",
"target_servicetype": "HSI",
"target_classname": "TR181",
"scenario": {
"Device.PPP.Interface.[Name=='HSI'].Username": "{ppp_username}",
"Device.PPP.Interface.[Name=='HSI'].Enable": true
}
}

Explanation of the Status Scenario

First (and only) Step: Compares CPE's actual values of WAN PPPoE connection or PPP interface with target values for existing parameters

  • For TR-098 CPE TR-181 data model parameters will be ignored

  • For TR-181 CPE TR-098 data model parameters will be ignored

VOIP Service

VOIP is a common service that configures a Voice Line.

Creating Service Definition

{
"servicetype": "VOIP",
"createNBI": true,
"allowForPortal": false,
"attachedToDefaultService": false,
"refCPE": null,
"enableActions": true,
"actions": [
"activate",
"deactivate",
"status",
"restore"
],
"enableHistory": false,
"primaryKey": [
"cpeid",
"lineID"
],
"isMeta": false,
"parameters": [
{
"name": "lineID",
"typeValue": "int",
"comment": "SIP Line ID",
"restrictions": {
"enumeration": [
1,
2
]
},
"hidden": false,
"defaultValue": null,
"changeable": true,
"optional": false,
"searchable": true
},
{
"name": "username",
"typeValue": "str",
"comment": "SIP Username",
"restrictions": {},
"hidden": false,
"defaultValue": null,
"changeable": true,
"optional": false,
"searchable": true
},
{
"name": "password",
"typeValue": "str",
"comment": "SIP Password",
"restrictions": {},
"hidden": true,
"defaultValue": null,
"changeable": true,
"optional": true,
"searchable": false
},
{
"name": "registration_server",
"typeValue": "str",
"comment": "Registration server",
"restrictions": {},
"hidden": false,
"defaultValue": "test",
"changeable": true,
"optional": true,
"searchable": true
}
]
}

This Service Definition allows us to configure Voice Line for specific CPE:

{
"ServiceIdentifiers": {
"cpeid": "DMS_DEVICE",
"lineID": 1
},
"ServiceParameters": {
"lineID": 1,
"username": "voice",
"password": "megasecure",
"registration_server": "cool.voice.service"
}
}

Creating a ServiceScenario

Activate

The activate action configures Voice Line and Profile:

{
"target_action": "activate",
"target_servicetype": "VOIP",
"target_classname": "*",
"scenario": [
{
"Device.Services.VoiceService.1.VoiceProfile.1.SIP.RegistrarServer": "{registration_server}",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.SIP.AuthPassword": "{password}",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.SIP.AuthUserName": "{username}",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.Enable": "Enabled",
"Device.Services.VoiceService.1.VoiceProfile.1.Enable": "Enabled"
}
]
}

Explanation of the Activate Scenario

First (and only) Step: Configures Voice Line and Profile

  • Just configures existing objects

  • {lineID} in the key is also replaced with the actual value from ServiceParameters

  • Voice parameters for TR-98 or TR-181 data models are the same, the root object Device or InternetGatewayDevice will be detected automatically

Deactivate

The deactivate action disables Voice Line:

{
"target_action": "deactivate",
"target_servicetype": "VOIP",
"target_classname": "*",
"scenario": [
{
"Device.Services.VoiceService.1.VoiceProfile.1.SIP.RegistrarServer": "",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.SIP.AuthPassword": "",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.SIP.AuthUserName": "",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.Enable": "Disabled"
}
]
}

Explanation of the Deactivate Scenario

First (and only) Step: Disables the Voice Line

  • Sets the Enable parameter to "Disabled", credentials to empty strings

  • Voice parameters for TR-98 or TR-181 data models are the same, the root object Device or InternetGatewayDevice will be detected automatically

Status
{
"target_action": "status",
"target_servicetype": "VOIP",
"target_classname": "*",
"scenario": {
"Device.Services.VoiceService.1.VoiceProfile.1.SIP.RegistrarServer": "{registration_server}",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.SIP.AuthUserName": "{username}",
"Device.Services.VoiceService.1.VoiceProfile.1.Line.{lineID}.Enable": "Enabled",
"Device.Services.VoiceService.1.VoiceProfile.1.Enable": "Enabled"
}
}

Explanation of the Status Scenario

First (and only) Step: Compares CPE's actual values of Voice Line and Profile with target values for existing parameters

  • For TR-098 and TR-181 CPE parameters are the same

Scenarios Running

Swagger (API)

  • Call the /Declarative.Services.action method (for activate/deactivate)

  • Call the /Declarative.Services.status method (for status)

Support Portal

  1. Navigate to the RPC section on the target CPE

  2. Select:

  • ApplyPath — if you want to test the scenario directly described in Declarative RPC.
  • Declarative.Services.action/status — if you want to test it as a service

Scenarios

To test a declarative service provisioning scenario independently of any predefined Service Definition, use the Declarative.Services.action scenario (for activate, deactivate, etc.) or the Declarative.Services.status scenario (for status only). These methods allow you to simulate the execution of a service scenario by manually providing both the declarative scenario body and dummy service parameters.

This approach is especially useful for:

  • Prototyping new service scenarios

  • Debugging template search paths using wildcards

  • Verifying service behavior without modifying or creating actual services

To run a scenario via the Support Portal, go to the RPC tab on the target CPE device and select Declarative.Services.action or Declarative.Services.status.

Request Structure

The input JSON must include two top-level keys:

  • service — a mock Service object with:

    • servicetype: the name of the Service (e.g. "PortMapping")

    • props: a dictionary of Service parameters (used to resolve placeholders in the scenario)

  • scenario — a Declarative Scenario with placeholders ({...}) as target values, which will be replaced using actual values from Service parameters

Example Request for Activate

Method: Declarative.Services.action

Request:

{
"service": {
"servicetype": "PortMapping",
"props": {
"external_port_range_end": 779,
"protocol": "TCP",
"internal_ip": "192.168.0.100",
"internal_port": 888,
"external_port": 777,
"name": "MyRule1"
}
},
"scenario": {
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].X_AX69": "Ignore",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalPort": "{internal_port}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalClient": "{internal_ip}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingEnabled": true,
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingProtocol": "{protocol}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].ExternalPortEndRange": "{external_port_range_end}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingDescription": "{name}"
}
}

Response:

{
"code": 200,
"details": [
{
"code": 200,
"message": "Done"
}
],
"message": "Done"
}

Example Request for Deactivate

Method: Declarative.Services.action

Request:

{
"service": {
"servicetype": "PortMapping",
"props": {
"external_port_range_end": 779,
"protocol": "TCP",
"internal_ip": "192.168.0.100",
"internal_port": 888,
"external_port": 777,
"name": "MyRule1"
}
},
"scenario": {
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingEnabled": false
}
}

Response:

{
"code": 200,
"details": [
{
"code": 200,
"message": "Done"
}
],
"message": "Done"
}

Example Request for Status

Method: Declarative.Services.status

Request:

{
"service": {
"servicetype": "PortMapping",
"props": {
"external_port_range_end": 779,
"protocol": "TCP",
"internal_ip": "192.168.0.100",
"internal_port": 888,
"external_port": 777,
"name": "MyRule1"
}
},
"scenario": "scenario": {
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Enable": true,
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Protocol": "{protocol}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].Description": "{name}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].ExternalPort": {
"type": "int",
"value": "{external_port}"
},
"Device.NAT.PortMapping.[ExternalPort=={external_port}].InternalPort": {
"type": "int",
"value": "{internal_port}"
},
"Device.NAT.PortMapping.[ExternalPort=={external_port}].InternalClient": "{internal_ip}",
"Device.NAT.PortMapping.[ExternalPort=={external_port}].ExternalPortEndRange": {
"type": "int",
"value": "{external_port_range_end}"
},
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingEnabled": true,
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingProtocol": "{protocol}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].PortMappingDescription": "{name}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].ExternalPort": {
"type": "int",
"value": "{external_port}"
},
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalPort": {
"type": "int",
"value": "{internal_port}"
},
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].InternalClient": "{internal_ip}",
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping.[ExternalPort=={external_port}].ExternalPortEndRange": {
"type": "int",
"value": "{external_port_range_end}"
}
}
}

Response after Activate:

{
"code": 200,
"message": "Service is active",
"status": 1
}

Response after Deactivate:

{
"code": 200,
"message": "Service is in-active",
"status": 0
}

In those examples all {...} placeholders inside the scenarios are automatically resolved using corresponding keys from service.props.

Service Configuration

This section provides step-by-step instructions for creating a service definition, scenario, service instance, campaign, and ultimately using the REST API.

1. Creating a Service Definition

Example: Create a service template PeriodicTestService that will contain its parameters and settings.

  1. Go to the Services Admin Portal section
  2. Click the Add button to create a new record.
FieldValueDescription
Service typePeriodicTestServiceService type
Primary keycpeidService identifier
Reference CPENoneReference to CPE object
Enable actions(checked)Indicates whether service actions are enabled
Create NBI(checked)Indicates whether NBI methods are created automatically
  1. Adding a Property:
  • Click Add item
  • Name: pii
  • Comment: periodic inform interval
  • Default value: 86400 (default value in seconds)
  • Flags: leave empty
  • Restrictions: {}
  1. Click the Confirm button to save.

A new PeriodicTestService entry will appear in the service definitions list with the configured primary key and pii property.

2. Creating a Service Scenario

Example: Create a scenario that will link the activate action and the target service PeriodicTestService with a specific set of parameters.

Go to the Services Portal section

  1. Click the Add button to create a new service.

  2. On the first step, select the definition type ServiceScenario and click Next.

  3. Fill in the form

  4. Properties block:

FieldValueDescription
target_servicetypePeriodicTestServiceTarget service
target_classname*Apply to all device classes
target_actionactivateAction to perform
scenario[ { "InternetGatewayDevice.ManagementServer.PeriodicInformInterval": "{pii}" } ]A JSON array containing a parameter and a variable. Each element of the array represents an SPV (Set Parameter Values)
comment(optional)Scenario comment

  1. Click Confirm to save.

A new entry with type ServiceScenario will appear in the general services list. The Props column will show a reference to PeriodicTestService, the activate action, and the scenario itself.

3. Creating a Campaign

  1. Go to the campaign management section.
  2. Click Add to create a campaign.
  3. Fill in the fields and click Add:
FieldValueDescription
Campaign nametestServicePiiCampaign name
Enable(checked)Activate the campaign
CPE criteriaNo conditions (or configure as needed)
Script nameservices_synchronizationScript name to execute, services_synchronization must be specified
Script parametersScript parameters

Important note about the services_synchronization script:

The services_synchronization script activates all services of all types that are bound to the CPE by default. If you need to limit synchronization to a specific service type only (e.g., only PeriodicTestService), this must be explicitly specified in the script parameters:

Script parameters:

{"servicetypes": ["PeriodicTestService"]}

The campaign will be launched and will synchronize (create or update) services for all matching CPEs. Either all services or only those specified in servicetypes will be affected.

4. API Endpoint Appearance

After successfully creating the service definition (PeriodicTestService), the system automatically adds the corresponding REST endpoints.

Available API Methods:

For managing the PeriodicTestService:

MethodEndpointDescription
POST/servicestorage/api/v1/NBI/PeriodicTestService/activateService activation
GET/servicestorage/api/v1/NBI/PeriodicTestService/getResult/{taskid}Get result by task ID

5. Service Activation

After creating the service definition, scenario, and campaign, the service can be activated in one of two ways: via REST API or through the user interface (UI).

Activating the Service via API

As shown in section 4, the automatically created endpoint is used to activate the service:

Request:

'POST' \
'http://localhost/servicestorage/api/v1/NBI/PeriodicTestService/activate' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"ServiceIdentifiers": {
"cpeid": "DMS_DEVICE"
},
"ServiceParameters": {
"pii": 3600
}
}'

Response:

{
"message": "Service activation was triggered",
"code": 200,
"data": {
"taskid": 2
}

Activating the Service via UI

Example: Bind the created scenario to a specific device (CPE) and set a specific value for the pii variable.

  1. In the Services Portal section, click the Add button to create a new service.

  2. Select the Service definition PeriodicTestService and click Next.

  3. Fill in the form:

FieldValueDescription
CPEIDDMS_DEVICETarget device ID
Propertiespii: 3600Value for the variable (overrides the default value)

4. Click Confirm to save.

The services table will show an entry with:

  • ServiceType: PeriodicTestService
  • CPEID: DNS_DEVICE
  • ID: Unique identifier (e.g., 72)
  • Props: Data with the set "pii": 3600