diff --git a/.gitignore b/.gitignore
index aef881143cea5a4582ac54fb995381854e383534..7d70601f9fe2ed38d1b8f78d1b5ad8d3763d78e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -161,3 +161,5 @@ tfs_runtime_env_vars.sh
 delete_local_deployment.sh
 local_docker_deployment.sh
 local_k8s_deployment.sh
+/src/common/proto/.gitkeep
+/src/common/proto/__init__.py
diff --git a/src/monitoring/client/MonitoringClient.py b/src/monitoring/client/MonitoringClient.py
index f65072f19013b820312aa56b7f0062f9c95f712c..9b78d3d4f1cc724cca364320414d732a0058b55f 100644
--- a/src/monitoring/client/MonitoringClient.py
+++ b/src/monitoring/client/MonitoringClient.py
@@ -100,10 +100,10 @@ class MonitoringClient:
         return response
 
     @RETRY_DECORATOR
-    def SubscribeKpi(self, request : SubsDescriptor) -> Iterator[KpiList]:
-        LOGGER.debug('SubscribeKpi: {:s}'.format(grpc_message_to_json_string(request)))
-        response = self.stub.SubscribeKpi(request)
-        LOGGER.debug('SubscribeKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+    def SetKpiSubscription(self, request : SubsDescriptor) -> Iterator[KpiList]:
+        LOGGER.debug('SetKpiSubscription: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.SetKpiSubscription(request)
+        LOGGER.debug('SetKpiSubscription result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
diff --git a/src/monitoring/service/MonitoringServiceServicerImpl.py b/src/monitoring/service/MonitoringServiceServicerImpl.py
index df3b907415aabe0ed4c276ac6ac09582636ebe6b..ae6e9570c199a1b46426150d93389ed7ce62037e 100644
--- a/src/monitoring/service/MonitoringServiceServicerImpl.py
+++ b/src/monitoring/service/MonitoringServiceServicerImpl.py
@@ -104,6 +104,30 @@ class MonitoringServiceServicerImpl(MonitoringServiceServicer):
         except Exception as e:  # pragma: no cover
             LOGGER.exception('DeleteKpi exception')
 
+    def GetKpiDescriptor(self, request: KpiId, grpc_context: grpc.ServicerContext) -> KpiDescriptor:
+        LOGGER.info('getting Kpi by KpiID')
+        try:
+            kpi_db = self.sql_db.get_KPI(int(request.kpi_id.uuid))
+            # LOGGER.info('sql_db.get_KPIS={:s}'.format(str(self.sql_db.get_KPIS())))
+            # LOGGER.info('kpi_db={:s}'.format(str(kpi_db)))
+            if kpi_db is None: return None
+
+            kpiDescriptor = KpiDescriptor()
+
+            kpiDescriptor.kpi_description = kpi_db[1]
+            kpiDescriptor.kpi_sample_type = kpi_db[2]
+            kpiDescriptor.device_id.device_uuid.uuid = str(kpi_db[3])
+            kpiDescriptor.endpoint_id.endpoint_uuid.uuid = str(kpi_db[4])
+            kpiDescriptor.service_id.service_uuid.uuid = str(kpi_db[5])
+
+            return kpiDescriptor
+        except ServiceException as e:
+            LOGGER.exception('GetKpiDescriptor exception')
+            grpc_context.abort(e.code, e.details)
+
+        except Exception:  # pragma: no cover
+            LOGGER.exception('GetKpiDescriptor exception')
+
     def GetKpiDescriptorList ( self, request : Empty, grpc_context : grpc.ServicerContext) -> KpiDescriptorList:
 
         LOGGER.info('GetKpiDescriptorList')
@@ -116,34 +140,7 @@ class MonitoringServiceServicerImpl(MonitoringServiceServicer):
         except Exception as e:  # pragma: no cover
             LOGGER.exception('GetKpiDescriptorList exception')
 
-    # rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {}
-    def MonitorKpi ( self, request : MonitorKpiRequest, grpc_context : grpc.ServicerContext) -> Empty:
 
-        LOGGER.info('MonitorKpi')
-        try:
-            # Sets the request to send to the device service
-            monitor_device_request = MonitoringSettings()
-
-            kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context)
-
-            monitor_device_request.kpi_descriptor.CopyFrom(kpiDescriptor)
-            monitor_device_request.kpi_id.kpi_id.uuid  = request.kpi_id.kpi_id.uuid
-            monitor_device_request.sampling_duration_s = request.monitoring_window_s
-            monitor_device_request.sampling_interval_s = request.sampling_rate_s
-
-            device_client = DeviceClient()
-            device_client.MonitorDeviceKpi(monitor_device_request)
-
-        except ServiceException as e:
-            LOGGER.exception('MonitorKpi exception')
-            # CREATEKPI_COUNTER_FAILED.inc()
-            grpc_context.abort(e.code, e.details)
-        except Exception as e:  # pragma: no cover
-            LOGGER.exception('MonitorKpi exception')
-            grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
-            # CREATEKPI_COUNTER_FAILED.inc()
-
-        return Empty()
 
     # rpc IncludeKpi(IncludeKpiRequest)  returns(context.Empty)    {}
     def IncludeKpi(self, request : Kpi, grpc_context : grpc.ServicerContext) -> Empty:
@@ -178,55 +175,49 @@ class MonitoringServiceServicerImpl(MonitoringServiceServicer):
             # CREATEKPI_COUNTER_FAILED.inc()
         return Empty()
 
-    # def GetStreamKpi ( self, request, grpc_context : grpc.ServicerContext):
-    #
-    #     LOGGER.info('GetStreamKpi')
-    #     yield monitoring_pb2.Kpi()
-    #
-    # @MONITORING_GETINSTANTKPI_REQUEST_TIME.time()
-    # def GetInstantKpi ( self, request, grpc_context : grpc.ServicerContext):
-    #
-    #     LOGGER.info('GetInstantKpi')
-    #     return monitoring_pb2.Kpi()
-
+    # rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {}
+    def MonitorKpi ( self, request : MonitorKpiRequest, grpc_context : grpc.ServicerContext) -> Empty:
 
-    def GetKpiDescriptor(self, request : KpiId, grpc_context : grpc.ServicerContext) -> KpiDescriptor:
-        LOGGER.info('getting Kpi by KpiID')
+        LOGGER.info('MonitorKpi')
         try:
-            kpi_db = self.sql_db.get_KPI(int(request.kpi_id.uuid))
-            #LOGGER.info('sql_db.get_KPIS={:s}'.format(str(self.sql_db.get_KPIS())))
-            #LOGGER.info('kpi_db={:s}'.format(str(kpi_db)))
-            if kpi_db is None: return None
+            # Sets the request to send to the device service
+            monitor_device_request = MonitoringSettings()
 
-            kpiDescriptor = KpiDescriptor()
+            kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context)
+
+            monitor_device_request.kpi_descriptor.CopyFrom(kpiDescriptor)
+            monitor_device_request.kpi_id.kpi_id.uuid  = request.kpi_id.kpi_id.uuid
+            monitor_device_request.sampling_duration_s = request.monitoring_window_s
+            monitor_device_request.sampling_interval_s = request.sampling_rate_s
 
-            kpiDescriptor.kpi_description                   = kpi_db[1]
-            kpiDescriptor.kpi_sample_type                   = kpi_db[2]
-            kpiDescriptor.device_id.device_uuid.uuid        = str(kpi_db[3])
-            kpiDescriptor.endpoint_id.endpoint_uuid.uuid    = str(kpi_db[4])
-            kpiDescriptor.service_id.service_uuid.uuid      = str(kpi_db[5])
+            device_client = DeviceClient()
+            device_client.MonitorDeviceKpi(monitor_device_request)
 
-            return kpiDescriptor
         except ServiceException as e:
-            LOGGER.exception('GetKpiDescriptor exception')
+            LOGGER.exception('MonitorKpi exception')
+            # CREATEKPI_COUNTER_FAILED.inc()
             grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('MonitorKpi exception')
+            grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
+            # CREATEKPI_COUNTER_FAILED.inc()
+
+        return Empty()
 
-        except Exception:  # pragma: no cover
-            LOGGER.exception('GetKpiDescriptor exception')
 
     def QueryKpiData ( self, request : KpiQuery, grpc_context : grpc.ServicerContext) -> KpiList:
 
         LOGGER.info('QueryKpiData')
         try:
              # TBC
-            return KpiQuery()
+            return KpiList()
         except ServiceException as e:
             LOGGER.exception('QueryKpiData exception')
             grpc_context.abort(e.code, e.details)
         except Exception as e:  # pragma: no cover
             LOGGER.exception('QueryKpiData exception')
 
-    def SubscribeKpi ( self, request : SubsDescriptor, grpc_context : grpc.ServicerContext) -> KpiList:
+    def SetKpiSubscription ( self, request : SubsDescriptor, grpc_context : grpc.ServicerContext) -> KpiList:
 
         LOGGER.info('SubscribeKpi')
         try:
@@ -335,3 +326,14 @@ class MonitoringServiceServicerImpl(MonitoringServiceServicer):
             grpc_context.abort(e.code, e.details)
         except Exception as e:  # pragma: no cover
             LOGGER.exception('DeleteAlarm exception')
+
+    def GetStreamKpi ( self, request : KpiId, grpc_context : grpc.ServicerContext) -> Iterator[Kpi]:
+
+        LOGGER.info('GetStreamKpi')
+        yield Kpi()
+
+    @MONITORING_GETINSTANTKPI_REQUEST_TIME.time()
+    def GetInstantKpi ( self, request : KpiId, grpc_context : grpc.ServicerContext) -> KpiList:
+
+        LOGGER.info('GetInstantKpi')
+        return KpiList()
\ No newline at end of file
diff --git a/src/monitoring/tests/Messages.py b/src/monitoring/tests/Messages.py
index cf81ceed1e134240415ec1aabe8796cd4486f75f..450f6accc98a36bbe7a221eec5dd20d01f340f09 100644
--- a/src/monitoring/tests/Messages.py
+++ b/src/monitoring/tests/Messages.py
@@ -32,6 +32,24 @@ def create_kpi_request():
     _create_kpi_request.endpoint_id.endpoint_uuid.uuid = 'END1'     # pylint: disable=maybe-no-member
     return _create_kpi_request
 
+def create_kpi_request_b():
+    _create_kpi_request                                = monitoring_pb2.KpiDescriptor()
+    _create_kpi_request.kpi_description                = 'KPI Description Test'
+    _create_kpi_request.kpi_sample_type                = KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED
+    _create_kpi_request.device_id.device_uuid.uuid     = 'DEV2'     # pylint: disable=maybe-no-member
+    _create_kpi_request.service_id.service_uuid.uuid   = 'SERV2'    # pylint: disable=maybe-no-member
+    _create_kpi_request.endpoint_id.endpoint_uuid.uuid = 'END2'     # pylint: disable=maybe-no-member
+    return _create_kpi_request
+
+def create_kpi_request_c():
+    _create_kpi_request                                = monitoring_pb2.KpiDescriptor()
+    _create_kpi_request.kpi_description                = 'KPI Description Test'
+    _create_kpi_request.kpi_sample_type                = KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED
+    _create_kpi_request.device_id.device_uuid.uuid     = 'DEV3'     # pylint: disable=maybe-no-member
+    _create_kpi_request.service_id.service_uuid.uuid   = 'SERV3'    # pylint: disable=maybe-no-member
+    _create_kpi_request.endpoint_id.endpoint_uuid.uuid = 'END3'     # pylint: disable=maybe-no-member
+    return _create_kpi_request
+
 def monitor_kpi_request(kpi_uuid, monitoring_window_s, sampling_rate_s):
     _monitor_kpi_request                     = monitoring_pb2.MonitorKpiRequest()
     _monitor_kpi_request.kpi_id.kpi_id.uuid  = kpi_uuid   # pylint: disable=maybe-no-member
@@ -45,3 +63,28 @@ def include_kpi_request(kpi_id):
     _include_kpi_request.timestamp.timestamp    = timestamp_utcnow_to_float()
     _include_kpi_request.kpi_value.int32Val     = 500       # pylint: disable=maybe-no-member
     return _include_kpi_request
+
+def kpi_query():
+    _kpi_query = monitoring_pb2.KpiQuery()
+
+    return _kpi_query
+
+def subs_descriptor():
+    _subs_descriptor = monitoring_pb2.SubsDescriptor()
+
+    return _subs_descriptor
+
+def subs_id():
+    _subs_id = monitoring_pb2.SubsDescriptor()
+
+    return _subs_id
+
+def alarm_descriptor():
+    _alarm_descriptor = monitoring_pb2.AlarmDescriptor()
+
+    return _alarm_descriptor
+
+def alarm_id():
+    _alarm_id = monitoring_pb2.AlarmID()
+
+    return _alarm_id
\ No newline at end of file
diff --git a/src/monitoring/tests/test_unitary.py b/src/monitoring/tests/test_unitary.py
index 03d5e665b9f2bee509c0fe77699b72e690299a98..50d58c98d3c69576ca8e9c3568e51ea64d29e75b 100644
--- a/src/monitoring/tests/test_unitary.py
+++ b/src/monitoring/tests/test_unitary.py
@@ -15,6 +15,9 @@
 import copy, os, pytest
 from time import sleep
 from typing import Tuple
+
+from grpc._channel import _MultiThreadedRendezvous
+
 from common.Constants import ServiceNameEnum
 from common.Settings import (
     ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_service_port_grpc)
@@ -24,7 +27,8 @@ from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBack
 from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
 from common.message_broker.MessageBroker import MessageBroker
 from common.proto import monitoring_pb2
-from common.proto.monitoring_pb2 import KpiId, KpiDescriptor
+from common.proto.monitoring_pb2 import KpiId, KpiDescriptor, KpiList, SubsDescriptor, SubsIDList, AlarmID, \
+    AlarmDescriptor, AlarmIDList, Kpi
 
 from context.client.ContextClient import ContextClient
 from context.service.grpc_server.ContextService import ContextService
@@ -41,7 +45,8 @@ from common.proto.kpi_sample_types_pb2 import KpiSampleType
 from monitoring.service import SqliteTools, MetricsDBTools
 from monitoring.service.MonitoringService import MonitoringService
 from monitoring.service.EventTools import EventsDeviceCollector
-from monitoring.tests.Messages import create_kpi_request, include_kpi_request, monitor_kpi_request
+from monitoring.tests.Messages import create_kpi_request, include_kpi_request, monitor_kpi_request, \
+    create_kpi_request_b, create_kpi_request_c, kpi_query, subs_descriptor, subs_id, alarm_descriptor, alarm_id, kpi_id
 from monitoring.tests.Objects import DEVICE_DEV1, DEVICE_DEV1_CONNECT_RULES, DEVICE_DEV1_UUID
 
 from monitoring.service.MonitoringServiceServicerImpl import LOGGER
@@ -170,8 +175,38 @@ def test_set_kpi(monitoring_client): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_create_kpi requesting')
     response = monitoring_client.SetKpi(create_kpi_request())
     LOGGER.debug(str(response))
+    response = monitoring_client.SetKpi(create_kpi_request_b())
+    LOGGER.debug(str(response))
     assert isinstance(response, KpiId)
 
+
+# Test case that makes use of client fixture to test server's DeleteKpi method
+def test_delete_kpi(monitoring_client): # pylint: disable=redefined-outer-name
+    # make call to server
+    LOGGER.warning('delete_kpi requesting')
+    response = monitoring_client.SetKpi(create_kpi_request_b())
+    response = monitoring_client.DeleteKpi(response)
+    LOGGER.debug(str(response))
+    assert isinstance(response, Empty)
+
+# Test case that makes use of client fixture to test server's GetInstantKpi method
+def test_get_kpidescritor(monitoring_client): # pylint: disable=redefined-outer-name
+    LOGGER.warning('test_getkpidescritor_kpi begin')
+    response = monitoring_client.SetKpi(create_kpi_request_c())
+    # LOGGER.debug(str(response))
+    response = monitoring_client.GetKpiDescriptor(response)
+    # LOGGER.debug(str(response))
+    assert isinstance(response, KpiDescriptor)
+
+
+# Test case that makes use of client fixture to test server's IncludeKpi method
+def test_include_kpi(monitoring_client): # pylint: disable=redefined-outer-name
+    # make call to server
+    LOGGER.warning('test_include_kpi requesting')
+    kpi_id = monitoring_client.SetKpi(create_kpi_request_c())
+    response = monitoring_client.IncludeKpi(include_kpi_request(kpi_id))
+    assert isinstance(response, Empty)
+
 # Test case that makes use of client fixture to test server's MonitorKpi method
 def test_monitor_kpi(
         context_client : ContextClient,                 # pylint: disable=redefined-outer-name
@@ -207,13 +242,76 @@ def test_monitor_kpi(
     LOGGER.debug(str(response))
     assert isinstance(response, Empty)
 
+# Test case that makes use of client fixture to test server's QueryKpiData method
+def test_query_kpi_data(monitoring_client): # pylint: disable=redefined-outer-name
+    LOGGER.warning('test_query_kpi_data')
+    response = monitoring_client.QueryKpiData(kpi_query())
+    LOGGER.debug(str(response))
+    assert isinstance(response, KpiList)
+
+# Test case that makes use of client fixture to test server's SetKpiSubscription method
+def test_set_kpi_subscription(monitoring_client): # pylint: disable=redefined-outer-name
+    LOGGER.warning('test_set_kpi_subscription')
+    response = monitoring_client.SetKpiSubscription(subs_descriptor())
+    LOGGER.debug(type(response))
+    assert isinstance(response, _MultiThreadedRendezvous)
+
+# Test case that makes use of client fixture to test server's GetSubsDescriptor method
+def test_get_subs_descriptor(monitoring_client):
+    LOGGER.warning('test_get_subs_descriptor')
+    response = monitoring_client.GetSubsDescriptor(subs_id())
+    LOGGER.debug(type(response))
+    assert isinstance(response, SubsDescriptor)
+
+# Test case that makes use of client fixture to test server's GetSubscriptions method
+def test_get_subscriptions(monitoring_client):
+    LOGGER.warning('test_get_subscriptions')
+    response = monitoring_client.GetSubscriptions(Empty())
+    LOGGER.debug(type(response))
+    assert isinstance(response, SubsIDList)
+
+# Test case that makes use of client fixture to test server's DeleteSubscription method
+def test_delete_subscription(monitoring_client):
+    LOGGER.warning('test_delete_subscription')
+    response = monitoring_client.DeleteSubscription(subs_id())
+    LOGGER.debug(type(response))
+    assert isinstance(response, Empty)
 
-# Test case that makes use of client fixture to test server's IncludeKpi method
-def test_include_kpi(monitoring_client): # pylint: disable=redefined-outer-name
-    # make call to server
-    LOGGER.warning('test_include_kpi requesting')
-    kpi_id = monitoring_client.SetKpi(create_kpi_request())
-    response = monitoring_client.IncludeKpi(include_kpi_request(kpi_id))
+# Test case that makes use of client fixture to test server's SetKpiAlarm method
+def test_set_kpi_alarm(monitoring_client):
+    LOGGER.warning('test_set_kpi_alarm')
+    response = monitoring_client.SetKpiAlarm(alarm_descriptor())
+    LOGGER.debug(type(response))
+    assert isinstance(response, AlarmID)
+
+# Test case that makes use of client fixture to test server's GetAlarms method
+def test_get_alarms(monitoring_client):
+    LOGGER.warning('test_get_alarms')
+    response = monitoring_client.GetAlarms(Empty())
+    LOGGER.debug(type(response))
+    assert isinstance(response, AlarmIDList)
+
+
+# Test case that makes use of client fixture to test server's GetAlarmDescriptor method
+def test_get_alarm_descriptor(monitoring_client):
+    LOGGER.warning('test_get_alarm_descriptor')
+    response = monitoring_client.GetAlarmDescriptor(alarm_id())
+    LOGGER.debug(type(response))
+    assert isinstance(response, AlarmDescriptor)
+
+# Test case that makes use of client fixture to test server's GetAlarmResponseStream method
+def test_get_alarm_response_stream(monitoring_client):
+    LOGGER.warning('test_get_alarm_descriptor')
+    response = monitoring_client.GetAlarmResponseStream(alarm_descriptor())
+    LOGGER.debug(type(response))
+    assert isinstance(response, _MultiThreadedRendezvous)
+
+
+# Test case that makes use of client fixture to test server's DeleteAlarm method
+def test_delete_alarm(monitoring_client):
+    LOGGER.warning('test_delete_alarm')
+    response = monitoring_client.DeleteAlarm(alarm_id())
+    LOGGER.debug(type(response))
     assert isinstance(response, Empty)
 
 # Test case that makes use of client fixture to test server's GetStreamKpi method
@@ -221,23 +319,15 @@ def test_get_stream_kpi(monitoring_client): # pylint: disable=redefined-outer-na
     LOGGER.warning('test_getstream_kpi begin')
     response = monitoring_client.GetStreamKpi(monitoring_pb2.Kpi())
     LOGGER.debug(str(response))
-    #assert isinstance(response, Kpi)
+    assert isinstance(response, _MultiThreadedRendezvous)
 
 # Test case that makes use of client fixture to test server's GetInstantKpi method
-# def test_get_instant_kpi(monitoring_client): # pylint: disable=redefined-outer-name
-#     LOGGER.warning('test_getinstant_kpi begin')
-#     response = monitoring_client.GetInstantKpi(kpi_id())
-#     LOGGER.debug(str(response))
-#     # assert isinstance(response, Kpi)
+def test_get_instant_kpi(monitoring_client): # pylint: disable=redefined-outer-name
+    LOGGER.warning('test_getinstant_kpi begin')
+    response = monitoring_client.GetInstantKpi(kpi_id())
+    LOGGER.debug(str(response))
+    assert isinstance(response, KpiList)
 
-# Test case that makes use of client fixture to test server's GetInstantKpi method
-def test_get_kpidescritor_kpi(monitoring_client): # pylint: disable=redefined-outer-name
-    LOGGER.warning('test_getkpidescritor_kpi begin')
-    response = monitoring_client.SetKpi(create_kpi_request())
-    # LOGGER.debug(str(response))
-    response = monitoring_client.GetKpiDescriptor(response)
-    # LOGGER.debug(str(response))
-    assert isinstance(response, KpiDescriptor)
 
 def test_sqlitedb_tools_insert_kpi(sql_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_sqlitedb_tools_insert_kpi begin')