Skip to content
Snippets Groups Projects
Commit f619d55d authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

First working version of Device Monitoring including Monitoring of Emulated devices.

parent d937aecd
No related branches found
No related tags found
1 merge request!54Release 2.0.0
import logging, lxml.etree as ET
from typing import Any, Dict, List, Tuple
from device.service.database.KpiSampleType import ORM_KpiSampleType
from .Namespace import NAMESPACES
from .Tools import add_value_from_tag
from .Tools import add_value_from_collection, add_value_from_tag
LOGGER = logging.getLogger(__name__)
XPATH_PORTS = "//ocp:components/ocp:component/ocp:state[ocp:type='PORT']/.."
XPATH_INTERFACE_COUNTER = "//oci:interfaces/oci:interface[oci:name='{:s}']/state/counters/{:s}"
def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
response = []
......@@ -22,6 +24,14 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
'ocpp:port/ocpp:breakout-mode/ocpp:state/ocpp:channel-speed', namespaces=NAMESPACES)
add_value_from_tag(endpoint, 'type', component_type)
sample_types = {
ORM_KpiSampleType.BYTES_RECEIVED.value : XPATH_INTERFACE_COUNTER.format(endpoint['uuid'], 'in-octets' ),
ORM_KpiSampleType.BYTES_TRANSMITTED.value : XPATH_INTERFACE_COUNTER.format(endpoint['uuid'], 'out-octets'),
ORM_KpiSampleType.PACKETS_RECEIVED.value : XPATH_INTERFACE_COUNTER.format(endpoint['uuid'], 'in-pkts' ),
ORM_KpiSampleType.PACKETS_TRANSMITTED.value: XPATH_INTERFACE_COUNTER.format(endpoint['uuid'], 'out-pkts' ),
}
add_value_from_collection(endpoint, 'sample_types', sample_types)
if len(endpoint) == 0: continue
response.append(('endpoint[{:s}]'.format(endpoint['name']), endpoint))
response.append(('endpoint[{:s}]'.format(endpoint['uuid']), endpoint))
return response
import operator
from copy import deepcopy
from device.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum
from device.service.database.KpiSampleType import ORM_KpiSampleType
......@@ -22,32 +23,29 @@ DEVICE_EMU = {
}
PACKET_PORT_SAMPLE_TYPES = [
ORM_KpiSampleType.PACKETS_TRANSMITTED.value,
ORM_KpiSampleType.PACKETS_RECEIVED.value,
ORM_KpiSampleType.BYTES_TRANSMITTED.value,
ORM_KpiSampleType.BYTES_RECEIVED.value,
ORM_KpiSampleType.PACKETS_TRANSMITTED,
ORM_KpiSampleType.PACKETS_RECEIVED,
ORM_KpiSampleType.BYTES_TRANSMITTED,
ORM_KpiSampleType.BYTES_RECEIVED,
]
DEVICE_EMU_ENDPOINTS = [
('EP1', '10Gbps', PACKET_PORT_SAMPLE_TYPES),
('EP2', '10Gbps', PACKET_PORT_SAMPLE_TYPES),
('EP3', '10Gbps', PACKET_PORT_SAMPLE_TYPES),
('EP4', '10Gbps', PACKET_PORT_SAMPLE_TYPES),
]
ENDPOINT_UUIDS = ['EP1', 'EP2', 'EP3', 'EP4']
DEVICE_EMU_ENDPOINTS = []
for endpoint_uuid in ENDPOINT_UUIDS:
DEVICE_EMU_ENDPOINTS.append((endpoint_uuid, '10Gbps', PACKET_PORT_SAMPLE_TYPES))
RSRC_EP = '/endpoints/endpoint[{}]'
RSRC_SUBIF = RSRC_EP + '/subinterfaces/subinterface[{}]'
RSRC_ADDRIPV4 = RSRC_SUBIF + '/ipv4/address[{}]'
RSRC_EP = '/endpoints/endpoint[{:s}]'
RSRC_SUBIF = RSRC_EP + '/subinterfaces/subinterface[{:d}]'
RSRC_ADDRIPV4 = RSRC_SUBIF + '/ipv4/address[{:s}]'
DEVICE_EMU_ENDPOINTS_COOKED = []
for endpoint_uuid,endpoint_type,endpoint_sample_types in DEVICE_EMU_ENDPOINTS:
endpoint_resource_key = RSRC_EP.format(str(endpoint_uuid))
sample_types = {
ORM_KpiSampleType.PACKETS_TRANSMITTED.value: '{:s}/state/packets_transmitted'.format(endpoint_resource_key),
ORM_KpiSampleType.PACKETS_RECEIVED .value: '{:s}/state/packets_received' .format(endpoint_resource_key),
ORM_KpiSampleType.BYTES_TRANSMITTED .value: '{:s}/state/bytes_transmitted' .format(endpoint_resource_key),
ORM_KpiSampleType.BYTES_RECEIVED .value: '{:s}/state/bytes_received' .format(endpoint_resource_key),
}
sample_types = {}
for endpoint_sample_type in endpoint_sample_types:
sample_type_name = endpoint_sample_type.name.lower()
sample_types[endpoint_sample_type.value] = '{:s}/state/{:s}'.format(endpoint_resource_key, sample_type_name)
endpoint_resource_value = {'uuid': endpoint_uuid, 'type': endpoint_type, 'sample_types': sample_types}
DEVICE_EMU_ENDPOINTS_COOKED.append((endpoint_resource_key, endpoint_resource_value))
......@@ -55,31 +53,30 @@ DEVICE_EMU_CONNECT_RULES = [
config_rule_set('_connect/address', DEVICE_EMU_ADDRESS ),
config_rule_set('_connect/port', DEVICE_EMU_PORT ),
config_rule_set('_connect/settings', {'endpoints': [
{'uuid': endpoint_uuid, 'type': endpoint_type, 'sample_types': endpoint_sample_types}
{
'uuid': endpoint_uuid, 'type': endpoint_type,
'sample_types': list(map(operator.attrgetter('value'), endpoint_sample_types)),
}
for endpoint_uuid,endpoint_type,endpoint_sample_types in DEVICE_EMU_ENDPOINTS
]}),
]
DEVICE_EMU_CONFIG_ENDPOINTS = [
config_rule_set(RSRC_EP.format('EP1'), {'enabled' : True}),
config_rule_set(RSRC_EP.format('EP2'), {'enabled' : True}),
config_rule_set(RSRC_EP.format('EP3'), {'enabled' : True}),
config_rule_set(RSRC_EP.format('EP4'), {'enabled' : True}),
]
DEVICE_EMU_CONFIG_ADDRESSES = [
config_rule_set(RSRC_SUBIF .format('EP1', 0 ), {'index': 0}),
config_rule_set(RSRC_ADDRIPV4.format('EP1', 0, '10.1.0.1'), {'ip': '10.1.0.1', 'prefix_length': 24}),
config_rule_set(RSRC_SUBIF .format('EP2', 0 ), {'index': 0}),
config_rule_set(RSRC_ADDRIPV4.format('EP2', 0, '10.2.0.1'), {'ip': '10.2.0.1', 'prefix_length': 24}),
config_rule_set(RSRC_SUBIF .format('EP3', 0 ), {'index': 0}),
config_rule_set(RSRC_ADDRIPV4.format('EP3', 0, '10.3.0.1'), {'ip': '10.3.0.1', 'prefix_length': 24}),
config_rule_set(RSRC_SUBIF .format('EP4', 0 ), {'index': 0}),
config_rule_set(RSRC_ADDRIPV4.format('EP4', 0, '10.4.0.1'), {'ip': '10.4.0.1', 'prefix_length': 24}),
]
DEVICE_EMU_CONFIG_ENDPOINTS = []
for endpoint_uuid in ENDPOINT_UUIDS:
DEVICE_EMU_CONFIG_ENDPOINTS.append(config_rule_set(RSRC_EP.format(endpoint_uuid), {'enabled' : True}))
DEVICE_EMU_CONFIG_ADDRESSES = []
for endpoint_uuid in ENDPOINT_UUIDS:
endpoint_number = int(endpoint_uuid.replace('EP', ''))
subinterface_index = 0
subinterface_address = '10.{:d}.{:d}.1'.format(endpoint_number, subinterface_index)
subinterface_prefix_length = 24
DEVICE_EMU_CONFIG_ADDRESSES.extend([
config_rule_set(RSRC_SUBIF .format(endpoint_uuid, subinterface_index), {
'index': subinterface_index}),
config_rule_set(RSRC_ADDRIPV4.format(endpoint_uuid, subinterface_index, subinterface_address), {
'ip': subinterface_address, 'prefix_length': subinterface_prefix_length}),
])
DEVICE_EMU_RECONFIG_ADDRESSES = [
config_rule_delete(RSRC_SUBIF .format('EP2', 0 ), {}),
......@@ -89,23 +86,16 @@ DEVICE_EMU_RECONFIG_ADDRESSES = [
config_rule_set (RSRC_ADDRIPV4.format('EP2', 1, '10.2.1.1'), {'ip': '10.2.1.1', 'prefix_length': 24}),
]
DEVICE_EMU_DECONFIG_ADDRESSES = [
config_rule_delete(RSRC_SUBIF .format('EP1', 0 ), {}),
config_rule_delete(RSRC_ADDRIPV4.format('EP1', 0, '10.1.0.1'), {}),
config_rule_delete(RSRC_SUBIF .format('EP2', 1 ), {}),
config_rule_delete(RSRC_ADDRIPV4.format('EP2', 1, '10.2.1.1'), {}),
config_rule_delete(RSRC_SUBIF .format('EP3', 0 ), {}),
config_rule_delete(RSRC_ADDRIPV4.format('EP3', 0, '10.3.0.1'), {}),
config_rule_delete(RSRC_SUBIF .format('EP4', 0 ), {}),
config_rule_delete(RSRC_ADDRIPV4.format('EP4', 0, '10.4.0.1'), {}),
]
DEVICE_EMU_DECONFIG_ENDPOINTS = [
config_rule_delete(RSRC_EP.format('EP1'), {}),
config_rule_delete(RSRC_EP.format('EP2'), {}),
config_rule_delete(RSRC_EP.format('EP3'), {}),
config_rule_delete(RSRC_EP.format('EP4'), {}),
]
DEVICE_EMU_DECONFIG_ADDRESSES = []
for endpoint_uuid in ENDPOINT_UUIDS:
endpoint_number = int(endpoint_uuid.replace('EP', ''))
subinterface_index = 1 if endpoint_uuid == 'EP2' else 0
subinterface_address = '10.{:d}.{:d}.1'.format(endpoint_number, subinterface_index)
DEVICE_EMU_DECONFIG_ADDRESSES.extend([
config_rule_delete(RSRC_SUBIF .format(endpoint_uuid, subinterface_index), {}),
config_rule_delete(RSRC_ADDRIPV4.format(endpoint_uuid, subinterface_index, subinterface_address), {}),
])
DEVICE_EMU_DECONFIG_ENDPOINTS = []
for endpoint_uuid in ENDPOINT_UUIDS:
DEVICE_EMU_DECONFIG_ENDPOINTS.append(config_rule_delete(RSRC_EP.format(endpoint_uuid), {}))
......@@ -4,13 +4,14 @@ from .Tools import config_rule_set, config_rule_delete
# use "deepcopy" to prevent propagating forced changes during tests
DEVICE_OC_UUID = 'DEV2'
DEVICE_OC_TYPE = 'packet-router'
DEVICE_OC_ADDRESS = '127.0.0.1' # populate the Netconf Server IP address of the device to test
DEVICE_OC_PORT = '830' # populate the Netconf Server port of the device to test
DEVICE_OC_USERNAME = 'username' # populate the Netconf Server username of the device to test
DEVICE_OC_PASSWORD = 'password' # populate the Netconf Server password of the device to test
DEVICE_OC_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG]
DEVICE_OC_UUID = 'DEV2'
DEVICE_OC_TYPE = 'packet-router'
DEVICE_OC_ADDRESS = '127.0.0.1' # populate the Netconf Server IP address of the device to test
DEVICE_OC_PORT = '830' # populate the Netconf Server port of the device to test
DEVICE_OC_USERNAME = 'username' # populate the Netconf Server username of the device to test
DEVICE_OC_PASSWORD = 'password' # populate the Netconf Server password of the device to test
DEVICE_OC_TIMEOUT = 120
DEVICE_OC_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG]
DEVICE_OC_ID = {'device_uuid': {'uuid': DEVICE_OC_UUID}}
DEVICE_OC = {
......@@ -23,10 +24,13 @@ DEVICE_OC = {
}
DEVICE_OC_CONNECT_RULES = [
config_rule_set('_connect/address', DEVICE_OC_ADDRESS ),
config_rule_set('_connect/port', DEVICE_OC_PORT ),
config_rule_set('_connect/username', DEVICE_OC_USERNAME),
config_rule_set('_connect/password', DEVICE_OC_PASSWORD),
config_rule_set('_connect/address', DEVICE_OC_ADDRESS),
config_rule_set('_connect/port', DEVICE_OC_PORT ),
config_rule_set('_connect/settings', {
'username': DEVICE_OC_USERNAME,
'password': DEVICE_OC_PASSWORD,
'timeout' : DEVICE_OC_TIMEOUT,
}),
]
DEVICE_OC_CONFIG_RULES = [] # populate your configuration rules to test
......
......@@ -34,8 +34,8 @@ from monitoring.client.monitoring_client import MonitoringClient
from .CommonObjects import CONTEXT, TOPOLOGY
from .Device_Emulated import (
DEVICE_EMU, DEVICE_EMU_CONFIG_ADDRESSES, DEVICE_EMU_CONFIG_ENDPOINTS, DEVICE_EMU_CONNECT_RULES,
DEVICE_EMU_DECONFIG_ADDRESSES, DEVICE_EMU_DECONFIG_ENDPOINTS, DEVICE_EMU_ENDPOINTS_COOKED, DEVICE_EMU_ID,
DEVICE_EMU_RECONFIG_ADDRESSES, DEVICE_EMU_UUID)
DEVICE_EMU_DECONFIG_ADDRESSES, DEVICE_EMU_DECONFIG_ENDPOINTS, DEVICE_EMU_ENDPOINTS, DEVICE_EMU_ENDPOINTS_COOKED,
DEVICE_EMU_ID, DEVICE_EMU_RECONFIG_ADDRESSES, DEVICE_EMU_UUID)
try:
from .Device_OpenConfig_Infinera import(
DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID,
......@@ -316,28 +316,36 @@ def test_device_emulated_monitor(
SAMPLING_DURATION_SEC = 3.0
SAMPLING_INTERVAL_SEC = 0.5
NUM_SAMPLES_EXPECTED = SAMPLING_DURATION_SEC / SAMPLING_INTERVAL_SEC
ENDPOINT_UUID = 'EP2'
SAMPLE_TYPE = KpiSampleType.KPISAMPLETYPE_BYTES_RECEIVED
SAMPLE_TYPE_NAME = str(KpiSampleType.Name(SAMPLE_TYPE)).upper().replace('KPISAMPLETYPE_', '')
KPI_UUID = '{:s}-{:s}-{:s}-kpi_uuid'.format(DEVICE_EMU_UUID, ENDPOINT_UUID, str(SAMPLE_TYPE))
MONITORING_SETTINGS = {
'kpi_id' : {'kpi_id': {'uuid': KPI_UUID}},
'kpi_descriptor': {
'kpi_description': 'Metric {:s} for Endpoint {:s} in Device {:s}'.format(
SAMPLE_TYPE_NAME, ENDPOINT_UUID, DEVICE_EMU_UUID),
'kpi_sample_type': SAMPLE_TYPE,
'device_id': DEVICE_EMU_ID,
'endpoint_id': endpoint_id(DEVICE_EMU_ID, ENDPOINT_UUID),
},
'sampling_duration_s': SAMPLING_DURATION_SEC,
'sampling_interval_s': SAMPLING_INTERVAL_SEC,
}
MONITORING_SETTINGS_LIST = []
KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {}
for endpoint_uuid,_,sample_types in DEVICE_EMU_ENDPOINTS:
for sample_type in sample_types:
sample_type_id = sample_type.value
sample_type_name = str(KpiSampleType.Name(sample_type_id)).upper().replace('KPISAMPLETYPE_', '')
kpi_uuid = '{:s}-{:s}-{:s}-kpi_uuid'.format(DEVICE_EMU_UUID, endpoint_uuid, str(sample_type_id))
monitoring_settings = {
'kpi_id' : {'kpi_id': {'uuid': kpi_uuid}},
'kpi_descriptor': {
'kpi_description': 'Metric {:s} for Endpoint {:s} in Device {:s}'.format(
sample_type_name, endpoint_uuid, DEVICE_EMU_UUID),
'kpi_sample_type': sample_type_id,
'device_id': DEVICE_EMU_ID,
'endpoint_id': endpoint_id(DEVICE_EMU_ID, endpoint_uuid),
},
'sampling_duration_s': SAMPLING_DURATION_SEC,
'sampling_interval_s': SAMPLING_INTERVAL_SEC,
}
MONITORING_SETTINGS_LIST.append(monitoring_settings)
KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] = 0
NUM_SAMPLES_EXPECTED_PER_KPI = SAMPLING_DURATION_SEC / SAMPLING_INTERVAL_SEC
NUM_SAMPLES_EXPECTED = len(MONITORING_SETTINGS_LIST) * NUM_SAMPLES_EXPECTED_PER_KPI
# Start monitoring the device
t_start_monitoring = datetime.timestamp(datetime.utcnow())
device_client.MonitorDeviceKpi(MonitoringSettings(**MONITORING_SETTINGS))
for monitoring_settings in MONITORING_SETTINGS_LIST:
device_client.MonitorDeviceKpi(MonitoringSettings(**monitoring_settings))
# wait to receive the expected number of samples
# if takes more than 1.5 times the sampling duration, assume there is an error
......@@ -357,21 +365,28 @@ def test_device_emulated_monitor(
LOGGER.info('received_samples = {:s}'.format(str(received_samples)))
assert len(received_samples) == NUM_SAMPLES_EXPECTED
for received_sample in received_samples:
assert received_sample.kpi_id.kpi_id.uuid == KPI_UUID
kpi_uuid = received_sample.kpi_id.kpi_id.uuid
assert kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED
assert isinstance(received_sample.timestamp, str)
timestamp = float(received_sample.timestamp)
assert timestamp > t_start_monitoring
assert timestamp < t_end_monitoring
assert received_sample.kpi_value.HasField('floatVal')
assert isinstance(received_sample.kpi_value.floatVal, float)
KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] += 1
LOGGER.info('KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {:s}'.format(str(KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED)))
for kpi_uuid, num_samples_received in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.items():
assert num_samples_received == NUM_SAMPLES_EXPECTED_PER_KPI
# Unsubscribe monitoring
MONITORING_SETTINGS_UNSUBSCRIBE = {
'kpi_id' : {'kpi_id': {'uuid': KPI_UUID}},
'sampling_duration_s': -1, # negative value in sampling_duration_s or in sampling_interval_s means unsibscribe
'sampling_interval_s': -1, # kpi_id is mandatory to unsibscribe
}
device_client.MonitorDeviceKpi(MonitoringSettings(**MONITORING_SETTINGS_UNSUBSCRIBE))
for kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.keys():
MONITORING_SETTINGS_UNSUBSCRIBE = {
'kpi_id' : {'kpi_id': {'uuid': kpi_uuid}},
'sampling_duration_s': -1, # negative value in sampling_duration_s or in sampling_interval_s means unsibscribe
'sampling_interval_s': -1, # kpi_id is mandatory to unsibscribe
}
device_client.MonitorDeviceKpi(MonitoringSettings(**MONITORING_SETTINGS_UNSUBSCRIBE))
def test_device_emulated_deconfigure(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment