Add ListAdapters to global handler RPCs

Change-Id: I54e53f284abbccae369905cae6cf1070b5136300
diff --git a/tests/itests/voltha/test_dispatcher.py b/tests/itests/voltha/test_dispatcher.py
index 71f6c8a..293f6f1 100644
--- a/tests/itests/voltha/test_dispatcher.py
+++ b/tests/itests/voltha/test_dispatcher.py
@@ -153,6 +153,14 @@
                '\nEnsure port forwarding is set on ponmgnt ...')
 
         # Test 1:
+        # A. Get the list of adapters using a global stub
+        # B. Get the list of adapters using a local stub
+        # C. Verify that the two lists are the same
+        adapters_g = self._get_adapters_grpc(self.ponsim_voltha_stub_global)
+        adapters_l =  self._get_adapters_grpc(self.empty_voltha_stub_local)
+        assert adapters_g == adapters_l
+
+        # Test 2:
         # A. Provision a pomsim olt using the ponsim_voltha_stub
         # B. Enable the posim olt using the simulated_voltha_stub
         # C. Wait for onu discovery using the empty_voltha_stub
@@ -164,7 +172,7 @@
         self._wait_for_onu_discovery_grpc(self.empty_voltha_stub_global,
                                           ponsim_olt.id,
                                           count=4)
-        # Test 2:
+        # Test 3:
         # A. Provision a simulated olt using the simulated_voltha_stub
         # B. Enable the simulated olt using the ponsim_voltha_stub
         # C. Wait for onu discovery using the empty_voltha_stub
@@ -175,7 +183,7 @@
         self._wait_for_onu_discovery_grpc(self.empty_voltha_stub_global,
                                           simulated_olt.id, count=4)
 
-        # Test 3:
+        # Test 4:
         # Verify that we have at least 8 devices created using the global
         # REST and also via direct grpc in the empty stub
         devices_via_rest = self._list_devices_rest(8)['items']
@@ -183,7 +191,7 @@
             self.empty_voltha_stub_global)
         assert len(devices_via_rest) == len(devices_via_global_grpc)
 
-        # Test 4:
+        # Test 5:
         # A. Create 2 Alarms filters using REST
         # B. Ensure it is present across all instances
         # C. Ensure when requesting the alarm filters we do not get
@@ -200,7 +208,7 @@
         filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_global)
         assert global_filters == MessageToDict(filter)
 
-        # Test 5:
+        # Test 6:
         # A. Delete an alarm filter
         # B. Ensure that filter is deleted from all instances
         self._remove_device_filter_rest(alarm_filter1['id'])
@@ -216,7 +224,7 @@
         filter = self._get_alarm_filters_grpc(self.empty_voltha_stub_global)
         assert global_filters == MessageToDict(filter)
 
-        # Test 6:
+        # Test 7:
         # A. Simulate EAPOL install on ponsim instance using grpc
         # B. Validate the flows using global REST
         # C. Retrieve the flows from global grpc using empty voltha instance
@@ -226,7 +234,7 @@
         res = self._get_olt_flows_grpc(self.empty_voltha_stub_global,
                                        ponsim_logical_device_id)
 
-        # TODO:  More tests to be added as new features are added 
+        # TODO:  More tests to be added as new features are added
 
 
     def _get_grpc_address(self, voltha_instance):
@@ -371,6 +379,10 @@
         res = stub.ListDevices(Empty())
         return res.items
 
+    def _get_adapters_grpc(self, stub):
+        res = stub.ListAdapters(Empty())
+        return res.items
+
     def _find_onus_grpc(self, stub, olt_id):
         devices = self._get_devices_grpc(stub)
         return [
diff --git a/voltha/core/global_handler.py b/voltha/core/global_handler.py
index ab02cf0..f681816 100644
--- a/voltha/core/global_handler.py
+++ b/voltha/core/global_handler.py
@@ -237,6 +237,17 @@
 
     @twisted_async
     @inlineCallbacks
+    def ListAdapters(self, request, context):
+        log.info('grpc-request', request=request)
+        response = yield self.dispatcher.dispatch('ListAdapters',
+                                                  Empty(),
+                                                  context,
+                                                  broadcast=True)
+        log.info('grpc-response', response=response)
+        returnValue(response)
+
+    @twisted_async
+    @inlineCallbacks
     def GetDevice(self, request, context):
         log.info('grpc-request', request=request)
         response = yield self.dispatcher.dispatch('GetDevice',
diff --git a/voltha/protos/voltha.proto b/voltha/protos/voltha.proto
index b015f47..ee8c9bd 100644
--- a/voltha/protos/voltha.proto
+++ b/voltha/protos/voltha.proto
@@ -187,6 +187,15 @@
         };
     }
 
+    // List all active adapters (plugins) in the Voltha cluster
+    rpc ListAdapters(google.protobuf.Empty) returns(Adapters) {
+        option (google.api.http) = {
+            get: "/api/v1/adapters"
+        };
+        option (voltha.yang_xml_tag).xml_tag = 'adapters';
+    }
+
+
     // List all logical devices managed by the Voltha cluster
     rpc ListLogicalDevices(google.protobuf.Empty) returns(LogicalDevices) {
         option (google.api.http) = {