This tutorial is intended to demonstrate how to relate Fault Management alarms to the restconf equipment inventory. This test will be done on a 'port' object.
The basic steps are:
Knowledge of how to use the NSP Notification service and Fault Management is required for this tutorial.
The user has retrieved a token to be able to use the REST/RESTCONF API services. The token is refreshed before expiring ( after 60 minutes ) -- See the Access & Authentication API Tutorial for more information.
This tutorial has been tested with and is supported in NSP 23.8.
Most steps in this tutorial are provided in the <new postman collection>. Example responses for each request are also included.
This tutorial is meant to describe how an alarm object received through the kafka notification service can be mapped to an NSP inventory object. It is not intended to demonstrate any particular OSS flow.
This tutorial contains sample code that has been written in Golang and is intended to show how data can be retrieved from NSP and parsed to suit particular purposes. For readability purposes, it has not been optimized, and omits most error handling. No warranty is available, either expressed or implied, for this sample code..
The tutorial uses the NSP Kafka notification Service to monitor alarms. The steps to monitor and retrieve alarms is not described in this tutorial. For further details on using Kafka, see Kafka Notification Service
Create 2 subscriptions to the NSP kafka Notification Service:
Subscriber-1 (S1)
POST /nbi-notification/api/v1/notifications/subscriptions HTTP/1.1
Host: 135.121.154.148
Content-Type: application/json
Authorization: Bearer {{token}}
Content-Length: 63
{
"categories": [
{
"name": "NSP-FAULT"
}
]
}
Subscriber-2 (S2)
POST /nbi-notification/api/v1/notifications/subscriptions HTTP/1.1
Host: 135.121.154.148
Content-Type: application/json
Authorization: Bearer {{token}}
Content-Length: 68
{
"categories": [
{
"name": "NSP-FAULT-YANG"
}
]
}
Use your favorite kafka client API to monitor the kafka topics created for both subscibers. You can also use the kafka consumer API described in the kafka notification service.
Retrieve port objects from NSP using the NSP restconf equipment inventory API. Among all the ports that have been returned in the response (response not shown here), I select 2 ports from different sources but managed by NSP; the first one (port-1) belongs to a classic node (managed by NFM-P) and the second one (port-2) belongs to a model driven node.
For this exercise, the important attributes are the "nsp-model:schema-nodeid", the "nsp-model:identifier" and the "nsp-model:sources".
Note
The port attributes are not relevant for this exercise, so they are limited to 3.
Port-1
{
"@": {
"nsp-model:schema-nodeid": "/nsp-equipment:network/network-element/hardware-component/port",
"nsp-model:identifier": "/nsp-equipment:network/network-element[ne-id='35.121.20.70']/hardware-component/port[component-id='shelf=1/slot=1/card=1/slot=1/card=1/port=1']",
"nsp-model:last-modified-time": "2023-05-12T14:43:40.262Z",
"nsp-model:sources": [
"fdn:realm:sam:network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1"
]
},
"component-id": "shelf=1/slot=1/card=1/slot=1/card=1/port=1",
"name": "Port 1/1/1",
"ne-id": "35.121.20.70"
}
Port-2
{
"@": {
"nsp-model:schema-nodeid": "/nsp-equipment:network/network-element/hardware-component/port",
"nsp-model:identifier": "/nsp-equipment:network/network-element[ne-id='92.168.99.245']/hardware-component/port[component-id='shelf=1/cardSlot=1/card=1/mdaSlot=1/mda=1/port=1/1/10']",
"nsp-model:last-modified-time": "2023-08-02T06:48:50.797Z",
"nsp-model:sources": [
"fdn:app:mdm-ami-cmodel:92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']",
"fdn:yang:nsp-network:/nsp-network:network/node[node-id='92.168.99.245']/node-root/nokia-state:state/port[port-id='1/1/10']",
"fdn:yang:nsp-network:/nsp-network:network/node[node-id='92.168.99.245']/node-root/nokia-conf:configure/port[port-id='1/1/10']"
]
},
"component-id": "shelf=1/cardSlot=1/card=1/mdaSlot=1/mda=1/port=1/1/10",
"name": "1/1/10",
"ne-id": "92.168.99.245"
}
The next step is to use the Model Device Configurator web application to set the 'admin-state' of port-1 to 'disable'. This will cause a number of alarms to flow through the kafka topics of Subscriber-1 and Subscriber-2; a sample alarm received by each subscriber is captured as shown below.
S1-A1: subscriber 1 and Alarm 1 (NSP-FAULT category)
{
"data": {
"ietf-restconf:notification": {
"eventTime": "2023-07-26T20:05:17Z",
"nsp-fault:alarm-create": {
"originalSeverity": "minor",
"neId": "35.121.20.70",
"lastTimeAcknowledged": 0,
"acknowledged": false,
"userText": "N/A",
"sourceSystem": "fdn:realm:sam",
"additionalText": "N/A",
"affectedObject": "network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1",
"lastTimeDeEscalated": null,
"acknowledgedBy": "N/A",
"lastTimeCleared": 0,
"neName": "sim20_70",
"frequency": null,
"lastTimeEscalated": null,
"probableCause": "equipmentAdministrativelyDown",
"firstTimeDetected": 1690401915279,
"adminState": "unlocked",
"rootCause": null,
"numberOfOccurrencesSinceAck": 0,
"nodeTimeOffset": -1,
"objectId": "fdn:model:fm:Alarm:5962",
"severity": "minor",
"affectedObjectName": "Port 1/1/1",
"clearedBy": "N/A",
"serviceAffecting": false,
"numberOfOccurrences": 1,
"impact": 0,
"implicitlyCleared": true,
"alarmName": "EquipmentAdministrativelyDown",
"wasAcknowledged": false,
"numberOfOccurrencesSinceClear": 1,
"objectFullName": "faultManager:network@35.121.20.70@shelf-1@cardSlot-1@card@daughterCardSlot-1@daughterCard@port-1|alarm-455-3-326",
"previousSeverity": "indeterminate",
"highestSeverity": "minor",
"affectedObjectType": "equipment.PhysicalPort",
"alarmType": "equipmentAlarm",
"specificProblem": "Not Applicable",
"sourceType": "nfmp",
"lastTimeSeverityChanged": 0,
"lastTimeDetected": 1690401915279
}
}
}
}
S2-A1: subscriber 2 and Alarm 1 (NSP-FAULT-YANG)
{
"nsp-model-notification:object-creation": {
"schema-nodeid": "/nsp-fault:alarms/alarm-list/alarm",
"instance-id": "/nsp-fault:alarms/alarm-list/alarm[alarm-fdn='fdn:model:fm:Alarm:5998']",
"context": "NSP-Yang",
"tree": {
"/nsp-fault:alarms/alarm-list/alarm": {
"@": {
"nsp-model:schema-nodeid": "/nsp-fault:alarms/alarm-list/alarm",
"nsp-model:identifier": "/nsp-fault:alarms/alarm-list/alarm[alarm-fdn='fdn:model:fm:Alarm:5998']"
},
"node-time-offset": -1,
"number-of-occurrences-since-clear": 1,
"probable-cause-string": "equipmentAdministrativelyDown",
"alarm-type-id": "equipmentAlarm",
"last-changed": null,
"acknowledged": false,
"cleared-by": "N/A",
"original-severity": "minor",
"is-cleared": false,
"was-acknowledged": false,
"admin-state": "unlocked",
"root-cause-resource": null,
"ne-id": "35.121.20.70",
"acknowledged-by": "N/A",
"frequency": null,
"last-time-severity-changed": null,
"last-raised": "2023-07-26T20:26:31.829Z",
"user-text": "N/A",
"ne-name": "sim20_70",
"source-type": "nfmp",
"affected-object-type": "equipment.PhysicalPort",
"time-created": "2023-07-26T20:26:31.829Z",
"source-system": "fdn:realm:sam",
"alarm-type-qualifier": "EquipmentAdministrativelyDown",
"impacted-resource": null,
"additional-text": "N/A",
"last-time-de-escalated": null,
"number-of-occurrences-since-ack": 0,
"resource": "fdn:realm:sam:network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1",
"perceived-severity": "minor",
"last-time-acknowledged": null,
"number-of-occurrences": 1,
"previous-severity": "indeterminate",
"impact-count": 0,
"alarm-fdn": "fdn:model:fm:Alarm:5998",
"last-time-escalated": null,
"affected-object-name": "Port 1/1/1",
"implicitly-cleared": true,
"alt-resource": "faultManager:network@35.121.20.70@shelf-1@cardSlot-1@card@daughterCardSlot-1@daughterCard@port-1|alarm-455-3-326",
"last-time-cleared": null,
"is-root-cause": null
}
},
"event-time": "2023-07-26T20:26:32.075Z"
}
}
The next step is to use the Model Device Configurator web application to set the 'admin-state' of port-2 to 'disable'. This will cause a number of alarms to flow through the kafka topics of Subscriber-1 and Subscriber-2; a sample alarm is captured for each subscriber.
S1-A2: subscriber 1 and Alarm 2 (NSP-FAULT)
{
"data": {
"ietf-restconf:notification": {
"eventTime": "2023-08-08T14:36:47Z",
"nsp-fault:alarm-create": {
"originalSeverity": "major",
"neId": "92.168.99.245",
"lastTimeAcknowledged": null,
"acknowledged": false,
"userText": "N/A",
"sourceSystem": "fdn:app:mdm-ami-cmodel",
"additionalText": "Interface 1/1/10 is not operational",
"affectedObject": "92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']",
"lastTimeDeEscalated": null,
"acknowledgedBy": "N/A",
"lastTimeCleared": null,
"neName": null,
"frequency": 1,
"lastTimeEscalated": null,
"probableCause": "equipmentMalfunction",
"firstTimeDetected": 1691505407444,
"adminState": "unlocked",
"rootCause": null,
"numberOfOccurrencesSinceAck": 0,
"nodeTimeOffset": -1,
"objectId": "fdn:model:fm:Alarm:242679",
"severity": "major",
"affectedObjectName": "port=1/1/10",
"clearedBy": "N/A",
"serviceAffecting": null,
"numberOfOccurrences": 1,
"impact": 0,
"implicitlyCleared": true,
"alarmName": "LinkDown",
"wasAcknowledged": false,
"numberOfOccurrencesSinceClear": 0,
"objectFullName": "92.168.99.245:fm:Alarm:/port[port-id='1/1/10']/linkDown",
"previousSeverity": "indeterminate",
"highestSeverity": "major",
"affectedObjectType": "equipment.Equipment",
"alarmType": "processingErrorAlarm",
"specificProblem": null,
"sourceType": "mdm",
"lastTimeSeverityChanged": null,
"lastTimeDetected": 1691505407444
}
}
}
}
S2-A2: subscriber 2 and Alarm 2 (NSP-FAULT-YANG
{
"nsp-model-notification:object-creation": {
"schema-nodeid": "/nsp-fault:alarms/alarm-list/alarm",
"instance-id": "/nsp-fault:alarms/alarm-list/alarm[alarm-fdn='fdn:model:fm:Alarm:257293']",
"context": "NSP-Yang",
"tree": {
"/nsp-fault:alarms/alarm-list/alarm": {
"@": {
"nsp-model:schema-nodeid": "/nsp-fault:alarms/alarm-list/alarm",
"nsp-model:identifier": "/nsp-fault:alarms/alarm-list/alarm[alarm-fdn='fdn:model:fm:Alarm:257293']"
},
"node-time-offset": -1,
"number-of-occurrences-since-clear": 0,
"probable-cause-string": "equipmentMalfunction",
"alarm-type-id": "processingErrorAlarm",
"last-changed": null,
"acknowledged": false,
"cleared-by": "N/A",
"original-severity": "major",
"is-cleared": false,
"was-acknowledged": false,
"admin-state": "unlocked",
"root-cause-resource": null,
"ne-id": "92.168.99.245",
"acknowledged-by": "N/A",
"frequency": 1,
"last-time-severity-changed": null,
"last-raised": "2023-08-08T14:50:50.193Z",
"user-text": "N/A",
"ne-name": null,
"source-type": "mdm",
"affected-object-type": "equipment.Equipment",
"time-created": "2023-08-08T14:50:50.193Z",
"source-system": "fdn:app:mdm-ami-cmodel",
"alarm-type-qualifier": "LinkDown",
"impacted-resource": null,
"additional-text": "Interface 1/1/10 is not operational",
"last-time-de-escalated": null,
"number-of-occurrences-since-ack": 0,
"resource": "fdn:app:mdm-ami-cmodel:92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']",
"perceived-severity": "major",
"last-time-acknowledged": null,
"number-of-occurrences": 1,
"previous-severity": "indeterminate",
"impact-count": 0,
"alarm-fdn": "fdn:model:fm:Alarm:257293",
"last-time-escalated": null,
"affected-object-name": "port=1/1/10",
"implicitly-cleared": true,
"alt-resource": "92.168.99.245:fm:Alarm:/port[port-id='1/1/10']/linkDown",
"last-time-cleared": null,
"is-root-cause": null
}
},
"event-time": "2023-08-08T14:50:50.255Z"
}
}
The next few tables will assemble the fields required to relate the alarms to the ports.
Alarm | affectedObject | sourceSystem |
---|---|---|
S1-A1 | "network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1" | "fdn:realm:sam" |
S1-A2 | "92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']" | "fdn:app:mdm-ami-cmodel" |
nsp-model:identifier | nsp-model:sources | {{sourceSystem}}:{{affectedObject}} | |
---|---|---|---|
port-1 | "/nsp-equipment:network/network-element[ne-id='35.121.20.70']/hardware-component/port[component-id='shelf=1/slot=1/card=1/slot=1/card=1/port=1']" | "fdn:realm:sam:network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1" | "fdn:realm:sam:network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1" |
port-2 | "/nsp-equipment:network/network-element[ne-id='92.168.99.245']/hardware-component/port[component-id='shelf=1/cardSlot=1/card=1/mdaSlot=1/mda=1/port=1/1/10']" | "fdn:app:mdm-ami-cmodel:92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']" | "fdn:app:mdm-ami-cmodel:92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']" |
As shown in table-2, to relate alarms S1-A1 and S1-A2 to the NSP port object, one needs to concatenate the following alarm fields (or attributes):
- {{sourceSystem}}:{{affectedObject}}
An OSS can use the concatenated string to match the alarms to the "nsp-model:sources" field of both port-1 and port-2 saved in its system.
Alarm | resource | source-system |
---|---|---|
S2-A1 | "fdn:realm:sam:network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1" | "fdn:realm:sam" |
S2-A2 | "fdn:app:mdm-ami-cmodel:92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']" | "fdn:app:mdm-ami-cmodel" |
nsp-model:identifier | nsp-model:sources | resource | |
---|---|---|---|
port-1 | "/nsp-equipment:network/network-element[ne-id='35.121.20.70']/hardware-component/port[component-id='shelf=1/slot=1/card=1/slot=1/card=1/port=1']" | "fdn:realm:sam:network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1" | "fdn:realm:sam:network:35.121.20.70:shelf-1:cardSlot-1:card:daughterCardSlot-1:daughterCard:port-1" |
port-2 | "/nsp-equipment:network/network-element[ne-id='92.168.99.245']/hardware-component/port[component-id='shelf=1/cardSlot=1/card=1/mdaSlot=1/mda=1/port=1/1/10']" | "fdn:app:mdm-ami-cmodel:92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']" | "fdn:app:mdm-ami-cmodel:92.168.99.245:equipment:Equipment:/port[port-id='1/1/10']" |
As shown in table-4, to map alarms S2-A1 and S2-A2 to the NSP port object, one needs only the 'resource' field (or attribute) of the alarm.
An OSS can use the 'resource' attribute value to match the alarms to the "nsp-model:sources" field of both port-1 and port-2 saved in its system.
The postman collection to get the port inventory and create the 2 subscribers can be found here