From 52de8bff1c858cc61c1c76e6eed328683832a76f Mon Sep 17 00:00:00 2001
From: Javi Moreno <francisco.moreno.external@atos.net>
Date: Thu, 15 Jul 2021 03:11:47 -0400
Subject: [PATCH] Monitoring - Fix dependencies issues to test it locally

---
 src/monitoring/README.md            |  68 ++++++++++
 src/monitoring/build.sh             |   7 ++
 src/monitoring/clean.sh             |   6 +
 src/monitoring/context_pb2.py       | 188 ++++++++++++++++++++++------
 src/monitoring/monitoring_client.py |  14 +--
 src/monitoring/monitoring_server.py |  12 +-
 src/monitoring/requirements.txt     |   5 +-
 src/monitoring/start.sh             |   5 +
 src/monitoring/tests/Dockerfile     |  28 +++++
 9 files changed, 280 insertions(+), 53 deletions(-)
 create mode 100644 src/monitoring/README.md
 create mode 100755 src/monitoring/build.sh
 create mode 100755 src/monitoring/clean.sh
 create mode 100755 src/monitoring/start.sh
 create mode 100644 src/monitoring/tests/Dockerfile

diff --git a/src/monitoring/README.md b/src/monitoring/README.md
new file mode 100644
index 000000000..8a79168d9
--- /dev/null
+++ b/src/monitoring/README.md
@@ -0,0 +1,68 @@
+# How to run locally the monitoring service (tested in Ubuntu 20.04)
+
+
+## Download the grpc health probe
+
+`
+GRPC_HEALTH_PROBE_VERSION=v0.2.0 
+`
+
+`
+wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64
+`
+
+`
+chmod +x /bin/grpc_health_probe
+`
+
+## Get packages
+
+`
+python3 -m pip install pip-tools
+`
+
+`
+python3 -m pip install -r requirements.txt
+`
+
+## Install prometheus client
+
+`
+pip3 install prometheus_client
+`
+
+## Execute server
+`
+cd monitoring
+`
+
+`
+python3 monitoring/monitoring_server.py
+`
+
+## Execute client
+`
+python3 monitoring_client.py
+`
+
+# How to create and execute the monitoring server in a docker container
+
+## Install docker
+`
+curl -fsSL https://get.docker.com -o get-docker.sh
+`
+sudo sh get-docker.sh
+`
+## Build service
+`
+cd src
+`
+
+`
+./build.sh
+`
+
+## Run service
+`
+./start.sh
+`
diff --git a/src/monitoring/build.sh b/src/monitoring/build.sh
new file mode 100755
index 000000000..41bf3f32c
--- /dev/null
+++ b/src/monitoring/build.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+echo "BUILD monitoring server"
+docker build -t "monitoring:dockerfile" -f Dockerfile .
+
+echo "BUILD monitoring client"
+docker build -t "monitoring_client:dockerfile" -f tests/Dockerfile .
diff --git a/src/monitoring/clean.sh b/src/monitoring/clean.sh
new file mode 100755
index 000000000..58667a9e6
--- /dev/null
+++ b/src/monitoring/clean.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+docker rm --force monitoring
+docker rm --force monitoring_client
+docker network remove teraflowbridge
+
diff --git a/src/monitoring/context_pb2.py b/src/monitoring/context_pb2.py
index 5930d483e..cb90ca043 100644
--- a/src/monitoring/context_pb2.py
+++ b/src/monitoring/context_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   package='context',
   syntax='proto3',
   serialized_options=None,
-  serialized_pb=_b('\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"T\n\x07\x43ontext\x12\x1f\n\x04topo\x18\x01 \x01(\x0b\x32\x11.context.Topology\x12(\n\x03\x63tl\x18\x02 \x01(\x0b\x32\x1b.context.TeraFlowController\"H\n\x08Topology\x12\x1f\n\x06\x64\x65vice\x18\x01 \x03(\x0b\x32\x0f.context.Device\x12\x1b\n\x04link\x18\x02 \x03(\x0b\x32\r.context.Link\"1\n\x04Link\x12)\n\x0c\x65ndpointList\x18\x01 \x03(\x0b\x32\x13.context.EndPointId\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"\xda\x01\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12>\n\x14\x64\x65vOperationalStatus\x18\x04 \x01(\x0e\x32 .context.DeviceOperationalStatus\x12\'\n\x0c\x65ndpointList\x18\x05 \x03(\x0b\x32\x11.context.EndPoint\"%\n\x0c\x44\x65viceConfig\x12\x15\n\rdevice_config\x18\x01 \x01(\t\"C\n\x08\x45ndPoint\x12$\n\x07port_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x11\n\tport_type\x18\x02 \x01(\t\"O\n\nEndPointId\x12\x1e\n\x07port_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\x12!\n\x06\x64\x65v_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\",\n\x08\x44\x65viceId\x12 \n\tdevice_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x12TeraFlowController\x12\x1d\n\x06\x63tl_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\x12\x11\n\tipaddress\x18\x02 \x01(\t\"L\n\x14\x41uthenticationResult\x12\x1d\n\x06\x63tl_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*4\n\x17\x44\x65viceOperationalStatus\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x32\x44\n\x0e\x43ontextService\x12\x32\n\x0bGetTopology\x12\x0e.context.Empty\x1a\x11.context.Topology\"\x00\x62\x06proto3')
+  serialized_pb=_b('\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"{\n\x07\x43ontext\x12%\n\tcontextId\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x1f\n\x04topo\x18\x02 \x01(\x0b\x32\x11.context.Topology\x12(\n\x03\x63tl\x18\x03 \x01(\x0b\x32\x1b.context.TeraFlowController\"/\n\tContextId\x12\"\n\x0b\x63ontextUuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"m\n\x08Topology\x12#\n\x06topoId\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\x12\x1f\n\x06\x64\x65vice\x18\x03 \x03(\x0b\x32\x0f.context.Device\x12\x1b\n\x04link\x18\x04 \x03(\x0b\x32\r.context.Link\"1\n\x04Link\x12)\n\x0c\x65ndpointList\x18\x01 \x03(\x0b\x32\x13.context.EndPointId\"R\n\nTopologyId\x12%\n\tcontextId\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x1d\n\x06topoId\x18\x02 \x01(\x0b\x32\r.context.Uuid\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"\xda\x01\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12>\n\x14\x64\x65vOperationalStatus\x18\x04 \x01(\x0e\x32 .context.DeviceOperationalStatus\x12\'\n\x0c\x65ndpointList\x18\x05 \x03(\x0b\x32\x11.context.EndPoint\"%\n\x0c\x44\x65viceConfig\x12\x15\n\rdevice_config\x18\x01 \x01(\t\"C\n\x08\x45ndPoint\x12$\n\x07port_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x11\n\tport_type\x18\x02 \x01(\t\"t\n\nEndPointId\x12#\n\x06topoId\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12!\n\x06\x64\x65v_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12\x1e\n\x07port_id\x18\x03 \x01(\x0b\x32\r.context.Uuid\",\n\x08\x44\x65viceId\x12 \n\tdevice_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"K\n\x12TeraFlowController\x12\"\n\x06\x63tl_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x11\n\tipaddress\x18\x02 \x01(\t\"Q\n\x14\x41uthenticationResult\x12\"\n\x06\x63tl_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*4\n\x17\x44\x65viceOperationalStatus\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x32\x44\n\x0e\x43ontextService\x12\x32\n\x0bGetTopology\x12\x0e.context.Empty\x1a\x11.context.Topology\"\x00\x62\x06proto3')
 )
 
 _DEVICEOPERATIONALSTATUS = _descriptor.EnumDescriptor(
@@ -40,8 +40,8 @@ _DEVICEOPERATIONALSTATUS = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=939,
-  serialized_end=991,
+  serialized_start=1195,
+  serialized_end=1247,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUS)
 
@@ -83,19 +83,26 @@ _CONTEXT = _descriptor.Descriptor(
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='topo', full_name='context.Context.topo', index=0,
+      name='contextId', full_name='context.Context.contextId', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='ctl', full_name='context.Context.ctl', index=1,
+      name='topo', full_name='context.Context.topo', index=1,
       number=2, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ctl', full_name='context.Context.ctl', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
@@ -109,7 +116,38 @@ _CONTEXT = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=35,
-  serialized_end=119,
+  serialized_end=158,
+)
+
+
+_CONTEXTID = _descriptor.Descriptor(
+  name='ContextId',
+  full_name='context.ContextId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contextUuid', full_name='context.ContextId.contextUuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=160,
+  serialized_end=207,
 )
 
 
@@ -121,15 +159,22 @@ _TOPOLOGY = _descriptor.Descriptor(
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='device', full_name='context.Topology.device', index=0,
-      number=1, type=11, cpp_type=10, label=3,
+      name='topoId', full_name='context.Topology.topoId', index=0,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='device', full_name='context.Topology.device', index=1,
+      number=3, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='link', full_name='context.Topology.link', index=1,
-      number=2, type=11, cpp_type=10, label=3,
+      name='link', full_name='context.Topology.link', index=2,
+      number=4, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
@@ -146,8 +191,8 @@ _TOPOLOGY = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=121,
-  serialized_end=193,
+  serialized_start=209,
+  serialized_end=318,
 )
 
 
@@ -177,8 +222,46 @@ _LINK = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=195,
-  serialized_end=244,
+  serialized_start=320,
+  serialized_end=369,
+)
+
+
+_TOPOLOGYID = _descriptor.Descriptor(
+  name='TopologyId',
+  full_name='context.TopologyId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contextId', full_name='context.TopologyId.contextId', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='topoId', full_name='context.TopologyId.topoId', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=371,
+  serialized_end=453,
 )
 
 
@@ -215,8 +298,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=246,
-  serialized_end=309,
+  serialized_start=455,
+  serialized_end=518,
 )
 
 
@@ -274,8 +357,8 @@ _DEVICE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=312,
-  serialized_end=530,
+  serialized_start=521,
+  serialized_end=739,
 )
 
 
@@ -305,8 +388,8 @@ _DEVICECONFIG = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=532,
-  serialized_end=569,
+  serialized_start=741,
+  serialized_end=778,
 )
 
 
@@ -343,8 +426,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=571,
-  serialized_end=638,
+  serialized_start=780,
+  serialized_end=847,
 )
 
 
@@ -356,7 +439,7 @@ _ENDPOINTID = _descriptor.Descriptor(
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='port_id', full_name='context.EndPointId.port_id', index=0,
+      name='topoId', full_name='context.EndPointId.topoId', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -369,6 +452,13 @@ _ENDPOINTID = _descriptor.Descriptor(
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='port_id', full_name='context.EndPointId.port_id', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
@@ -381,8 +471,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=640,
-  serialized_end=719,
+  serialized_start=849,
+  serialized_end=965,
 )
 
 
@@ -412,8 +502,8 @@ _DEVICEID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=721,
-  serialized_end=765,
+  serialized_start=967,
+  serialized_end=1011,
 )
 
 
@@ -443,8 +533,8 @@ _UUID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=767,
-  serialized_end=787,
+  serialized_start=1013,
+  serialized_end=1033,
 )
 
 
@@ -481,8 +571,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=789,
-  serialized_end=859,
+  serialized_start=1035,
+  serialized_end=1110,
 )
 
 
@@ -519,29 +609,37 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=861,
-  serialized_end=937,
+  serialized_start=1112,
+  serialized_end=1193,
 )
 
+_CONTEXT.fields_by_name['contextId'].message_type = _CONTEXTID
 _CONTEXT.fields_by_name['topo'].message_type = _TOPOLOGY
 _CONTEXT.fields_by_name['ctl'].message_type = _TERAFLOWCONTROLLER
+_CONTEXTID.fields_by_name['contextUuid'].message_type = _UUID
+_TOPOLOGY.fields_by_name['topoId'].message_type = _TOPOLOGYID
 _TOPOLOGY.fields_by_name['device'].message_type = _DEVICE
 _TOPOLOGY.fields_by_name['link'].message_type = _LINK
 _LINK.fields_by_name['endpointList'].message_type = _ENDPOINTID
+_TOPOLOGYID.fields_by_name['contextId'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['topoId'].message_type = _UUID
 _DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
 _DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
 _DEVICE.fields_by_name['devOperationalStatus'].enum_type = _DEVICEOPERATIONALSTATUS
 _DEVICE.fields_by_name['endpointList'].message_type = _ENDPOINT
 _ENDPOINT.fields_by_name['port_id'].message_type = _ENDPOINTID
-_ENDPOINTID.fields_by_name['port_id'].message_type = _UUID
+_ENDPOINTID.fields_by_name['topoId'].message_type = _TOPOLOGYID
 _ENDPOINTID.fields_by_name['dev_id'].message_type = _DEVICEID
+_ENDPOINTID.fields_by_name['port_id'].message_type = _UUID
 _DEVICEID.fields_by_name['device_id'].message_type = _UUID
-_TERAFLOWCONTROLLER.fields_by_name['ctl_id'].message_type = _UUID
-_AUTHENTICATIONRESULT.fields_by_name['ctl_id'].message_type = _UUID
+_TERAFLOWCONTROLLER.fields_by_name['ctl_id'].message_type = _CONTEXTID
+_AUTHENTICATIONRESULT.fields_by_name['ctl_id'].message_type = _CONTEXTID
 DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
 DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
+DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
 DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
 DESCRIPTOR.message_types_by_name['Link'] = _LINK
+DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
 DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT
 DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
 DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
@@ -568,6 +666,13 @@ Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,
   ))
 _sym_db.RegisterMessage(Context)
 
+ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), dict(
+  DESCRIPTOR = _CONTEXTID,
+  __module__ = 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextId)
+  ))
+_sym_db.RegisterMessage(ContextId)
+
 Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), dict(
   DESCRIPTOR = _TOPOLOGY,
   __module__ = 'context_pb2'
@@ -582,6 +687,13 @@ Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), dic
   ))
 _sym_db.RegisterMessage(Link)
 
+TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), dict(
+  DESCRIPTOR = _TOPOLOGYID,
+  __module__ = 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyId)
+  ))
+_sym_db.RegisterMessage(TopologyId)
+
 Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), dict(
   DESCRIPTOR = _CONSTRAINT,
   __module__ = 'context_pb2'
@@ -653,8 +765,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   file=DESCRIPTOR,
   index=0,
   serialized_options=None,
-  serialized_start=993,
-  serialized_end=1061,
+  serialized_start=1249,
+  serialized_end=1317,
   methods=[
   _descriptor.MethodDescriptor(
     name='GetTopology',
diff --git a/src/monitoring/monitoring_client.py b/src/monitoring/monitoring_client.py
index 955b512f1..db70e6e2a 100644
--- a/src/monitoring/monitoring_client.py
+++ b/src/monitoring/monitoring_client.py
@@ -1,9 +1,9 @@
 import sys
 import grpc
 
-import monitoring
+import monitoring_pb2 as monitoring
 import monitoring_pb2_grpc
-import context
+import context_pb2
 
 import json
 
@@ -16,7 +16,7 @@ class MonitoringClient:
     def __init__(self, server="monitoring", port="7070"):
         logger.info("init monitoringClient port " + port)
         self.channel=grpc.insecure_channel(server+':'+port)
-        self.server=usc_pb2_grpc.MonitoringServiceStub(self.channel)
+        self.server=monitoring_pb2_grpc.MonitoringServiceStub(self.channel)
 
     def IncludeKpi(self, request):
         logger.info("IncludeKpi: {}".format(request))
@@ -50,12 +50,12 @@ if __name__ == "__main__":
     else:
         port = "7070"
 
-
     # form request
     kpi = monitoring.Kpi()
-    kpi.kpi_id.kpi_id = "KPIID0000"
-    kpi.kpiDescription "KPI Desc"
-    
+    monitoring.KpiId.kpi_id = "KPIID0000"
+    kpi.kpiDescription = "KPI Desc"
+
+
     # make call to server
     client = MonitoringClient(port)
     response=client.IncludeKpi(kpi)
diff --git a/src/monitoring/monitoring_server.py b/src/monitoring/monitoring_server.py
index e7713e44d..66c85e2e6 100644
--- a/src/monitoring/monitoring_server.py
+++ b/src/monitoring/monitoring_server.py
@@ -19,8 +19,6 @@ from logger import getJSONLogger
 logger = getJSONLogger('monitoringservice-server')
 logger.setLevel('DEBUG')
 
-from prometheus_client import start_http_server, Summary
-
 import threading
 
 from prometheus_client import start_http_server, Summary
@@ -39,24 +37,24 @@ class monitoringService(monitoring_pb2_grpc.MonitoringServiceServicer):
         #KPI, returns empty
         logger.info("IncludeKpi")
         MONITORING_INCLUDEKPI_COUNTER.inc()
-        return 
+        return
 
 
     def MonitorKpi ( self, request, context):
         #KpiDevice returns (google.protobuf.Empty) {}
         logger.info("IncludeKpi")
-        return 
+        return
 
     def GetStream_kpi ( self, request, context):
         #KpiId ) returns (stream Kpi) {}
         logger.info("IncludeKpi")
-        return 
+        return
 
     @MONITORING_GETINSTANTKPI_REQUEST_TIME.time()
     def GetInstantKpi ( self, request, context):
         #KpiId ) returns ( Kpi) {}
         logger.info("IncludeKpi")
-        return   
+        return
 
 
 if __name__ == "__main__":
@@ -68,7 +66,7 @@ if __name__ == "__main__":
     serverGRPC = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) # ,interceptors=(tracer_interceptor,))
 
     # add class to gRPC server
-    service = monitoring_pb2_grpc.MonitoringService()
+    service = monitoring_pb2_grpc.MonitoringServiceServicer()
     monitoring_pb2_grpc.add_MonitoringServiceServicer_to_server(service, serverGRPC)
 
     health_servicer = health.HealthServicer(experimental_non_blocking=True,experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
diff --git a/src/monitoring/requirements.txt b/src/monitoring/requirements.txt
index 7b000b30e..66f5f281c 100644
--- a/src/monitoring/requirements.txt
+++ b/src/monitoring/requirements.txt
@@ -1,4 +1,7 @@
-#
+#raise _InactiveRpcError(state)
+grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
+	status = StatusCode.UNAVAILABLE
+	details = "DNS resolution failed for service: 7070:7070"
 # This file is autogenerated by pip-compile
 # To update, run:
 #
diff --git a/src/monitoring/start.sh b/src/monitoring/start.sh
new file mode 100755
index 000000000..dd12fc87c
--- /dev/null
+++ b/src/monitoring/start.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+docker network create -d bridge teraflowbridge
+
+docker run -d -p 7070:7070 --name monitoring --network=teraflowbridge monitoring:dockerfile
+docker run -d -p --name monitoring_client --network=teraflowbridge monitoring_client:dockerfile
diff --git a/src/monitoring/tests/Dockerfile b/src/monitoring/tests/Dockerfile
new file mode 100644
index 000000000..32a8af2f7
--- /dev/null
+++ b/src/monitoring/tests/Dockerfile
@@ -0,0 +1,28 @@
+FROM python:3-slim
+RUN apt-get update -qqy && \
+	apt-get -qqy install wget g++ && \
+	rm -rf /var/lib/apt/lists/*
+# show python logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# download the grpc health probe
+RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \
+    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
+    chmod +x /bin/grpc_health_probe
+
+# get packages
+WORKDIR /monitoring
+COPY monitoring/requirements.in requirements.in
+RUN python3 -m pip install pip-tools
+RUN pip-compile --output-file=requirements.txt requirements.in
+RUN python3 -m pip install -r requirements.txt
+
+# add files into working directory
+COPY /monitoring/. .
+COPY /common/logger.py .
+
+# set listen port
+
+ENTRYPOINT ["python", "/monitoring/monitoring_client.py"]
+
+
-- 
GitLab