This commit consists of:
1) Improved error handling
2) Return correct XML message for unimplemented rpcs
3) Clean up

Change-Id: Ia59d203840efc2e238a50d4f05e56f854cca9fc7
diff --git a/netconf/nc_rpc/base/get.py b/netconf/nc_rpc/base/get.py
index d953b17..b2bb9fe 100644
--- a/netconf/nc_rpc/base/get.py
+++ b/netconf/nc_rpc/base/get.py
@@ -40,8 +40,8 @@
         if not rpc:
             log.info('unsupported-request', request=self.request)
             self.rpc_response.is_error = True
-            self.rpc_response.node = ncerror.BadMsg(self.request)
-            return
+            self.rpc_response.node = ncerror.NotImpl(self.request_xml)
+            returnValue(self.rpc_response)
 
         # Invoke voltha via the grpc client
         res_dict = yield self.grpc_client.invoke_voltha_api(rpc)
@@ -66,18 +66,18 @@
             try:
                 if self.request['command'] != 'get':
                     self.rpc_response.is_error = True
-                    self.rpc_response.node = ncerror.BadMsg('No GET in get '
-                                                            'request')
+                    self.rpc_response.node = ncerror.BadMsg(self.request_xml)
+                    return
 
                 if self.request.has_key('filter'):
                     if not self.request.has_key('class'):
                         self.rpc_response.is_error = True
-                        self.rpc_response.node = ncerror.BadMsg(
-                            'Missing filter sub-element')
+                        self.rpc_response.node = ncerror.NotImpl(self.request_xml)
+                    return
 
             except Exception as e:
                 self.rpc_response.is_error = True
-                self.rpc_response.node = ncerror.BadMsg(self.request)
+                self.rpc_response.node = ncerror.ServerException(self.request_xml)
                 return
 
     def get_voltha_rpc(self, request):
@@ -92,6 +92,11 @@
                         'subclass']:
                         return rpc['rpc']
 
+            # If the request has a subclass and is not in the list of
+            # supported rpc then return None
+            if request.has_key('subclass'):
+                return None
+
             # If we are here then no subclass exists.  Just return the rpc
             # associated with theNone subclass
             for rpc in rpcs:
@@ -128,9 +133,9 @@
             {'subclass': 'device_groups',
              'rpc': 'VolthaLocalService-ListDeviceGroups'
              },
-        ],
-        'VolthaInstances': [
-            {'subclass': None,
-             'rpc': 'VolthaGlobalService-ListVolthaInstances'
-             }],
+        ]
+        # 'VolthaInstances': [
+        #     {'subclass': None,
+        #      'rpc': 'VolthaGlobalService-ListVolthaInstances'
+        #      }],
     }
diff --git a/netconf/nc_rpc/ext/get_schema.py b/netconf/nc_rpc/ext/get_schema.py
index ec473d3..569a3b0 100644
--- a/netconf/nc_rpc/ext/get_schema.py
+++ b/netconf/nc_rpc/ext/get_schema.py
@@ -19,7 +19,8 @@
 from netconf.nc_rpc.rpc import Rpc
 import netconf.nc_common.error as ncerror
 from netconf.constants import Constants as C
-from netconf.nc_common.utils import qmap, ns
+from netconf.nc_common.utils import qmap
+from twisted.internet.defer import inlineCallbacks, returnValue
 
 log = structlog.get_logger()
 
@@ -31,26 +32,28 @@
         self.parse_schema_request(request_xml)
         self._validate_parameters()
 
+    @inlineCallbacks
     def execute(self):
         if self.rpc_response.is_error:
-            return(self.rpc_response)
+            returnValue(self.rpc_response)
 
         log.info('get-schema-request', session=self.session.session_id,
                  request=self.request)
 
         # Get the yang schema content
         # TODO: Use version as well
-        content = self.capabilities.get_schema_content(self.request['identifier'])
+        content = yield self.capabilities.get_schema_content(self.request[
+                                                            'identifier'])
         if not content:
             self.rpc_response.is_error = True
-            self.rpc_response.node = ncerror.BadMsg('Server Error')
-            return
+            self.rpc_response.node = ncerror.BadMsg(self.request_xml)
+            returnValue(self.rpc_response)
 
-        self.rpc_response.node = self.create_xml_response(content)
+        self.rpc_response.node = yield self.create_xml_response(content)
 
         self.rpc_response.is_error = False
 
-        return(self.rpc_response)
+        returnValue(self.rpc_response)
 
     def _validate_parameters(self):
         log.info('validate-parameters', session=self.session.session_id)
@@ -62,16 +65,14 @@
                         not self.request.has_key('format') or \
                         not self.request.has_key('version'):
                     self.rpc_response.is_error = True
-                    self.rpc_response.node = ncerror.BadMsg('Improperly '
-                                                            'formatted get '
-                                                            'schemas request')
+                    self.rpc_response.node = ncerror.BadMsg(self.request_xml)
                     return
 
                 if self.request.has_key('filter'):
                     if not self.request.has_key('class'):
                         self.rpc_response.is_error = True
                         self.rpc_response.node = ncerror.BadMsg(
-                            'Missing filter sub-element')
+                            self.request_xml)
                         return
 
                 # Verify that the requested schema exists
@@ -79,8 +80,7 @@
                                                              'identifier']) \
                         or self.request['format'] != 'yang' :
                     self.rpc_response.is_error = True
-                    self.rpc_response.node = ncerror.BadMsg(
-                        'Unsupported request')
+                    self.rpc_response.node = ncerror.BadMsg(self.request_xml)
                     return
 
             except Exception as e:
diff --git a/netconf/nc_rpc/ext/get_schemas.py b/netconf/nc_rpc/ext/get_schemas.py
index 7ec4555..cc09ebb 100644
--- a/netconf/nc_rpc/ext/get_schemas.py
+++ b/netconf/nc_rpc/ext/get_schemas.py
@@ -18,6 +18,8 @@
 import structlog
 from netconf.nc_rpc.rpc import Rpc
 import netconf.nc_common.error as ncerror
+from twisted.internet.defer import inlineCallbacks, returnValue
+
 
 log = structlog.get_logger()
 
@@ -28,9 +30,10 @@
         self._validate_parameters()
         self.capabilities = capabilities
 
+    @inlineCallbacks
     def execute(self):
         if self.rpc_response.is_error:
-            return(self.rpc_response)
+            returnValue(self.rpc_response)
 
         log.info('get-schemas-request', session=self.session.session_id,
                  request=self.request)
@@ -55,12 +58,12 @@
             node.text = dict['location']
 
         # Build the yang response
-        self.rpc_response.node = self.rpc_response.build_xml_response(
+        self.rpc_response.node = yield self.rpc_response.build_xml_response(
             self.request, top)
 
         self.rpc_response.is_error = False
 
-        return(self.rpc_response)
+        returnValue(self.rpc_response)
 
 
     def _validate_parameters(self):
@@ -70,15 +73,14 @@
             try:
                 if self.request['command'] != 'get-schemas':
                     self.rpc_response.is_error = True
-                    self.rpc_response.node = ncerror.BadMsg('Improperly '
-                                                            'formatted get '
-                                                            'schemas request')
+                    self.rpc_response.node = ncerror.BadMsg(self.request_xml)
+                    return
 
                 if self.request.has_key('filter'):
                     if not self.request.has_key('class'):
                         self.rpc_response.is_error = True
-                        self.rpc_response.node = ncerror.BadMsg(
-                            'Missing filter sub-element')
+                        self.rpc_response.node = ncerror.BadMsg(self.request_xml)
+                        return
 
             except Exception as e:
                 self.rpc_response.is_error = True
diff --git a/netconf/nc_rpc/rpc_factory.py b/netconf/nc_rpc/rpc_factory.py
index 3d0d678..f314dbe 100644
--- a/netconf/nc_rpc/rpc_factory.py
+++ b/netconf/nc_rpc/rpc_factory.py
@@ -42,13 +42,7 @@
     instance = None
 
     def __init__(self):
-        self.rpc_map = {}
-        # TODO:  This will be loaded after the yang modules have been
-        # generated from proto files
-        self.register_rpc('{urn:opencord:params:xml:ns:voltha:ietf-voltha}',
-                          'VolthaGlobalService', 'GetVoltha', GetVoltha)
-        self.register_rpc('{urn:opencord:params:xml:ns:voltha:ietf-voltha}',
-                          'any', 'any', GetVoltha)
+        pass
 
     def _get_key(self, namespace, service, name):
         return ''.join([namespace, service, name])
@@ -60,8 +54,8 @@
 
 
     # Parse a request (node is an ElementTree) and return a dictionary
-    # TODO:  This parser is specific to a GET request.  Need to be it more
-    # generic
+    # TODO:  This parser is specific for a GET/GET SCHEMAS request.  Need to be
+    #  it more generic
     def parse_xml_request(self, node):
         request = {}
         if not len(node):
@@ -99,15 +93,6 @@
 
         return request
 
-    def register_rpc(self, namespace, service, name, klass):
-        key = self._get_key(namespace, service, name)
-        if key not in self.rpc_map.keys():
-            self.rpc_map[key] = klass
-
-    def get_handler(self, namespace, service, name):
-        key = self._get_key(namespace, service, name)
-        if key in self.rpc_map.keys():
-            return self.rpc_map[key]
 
     def get_rpc_handler(self, rpc_node, msg, grpc_channel, session,
                         capabilities):
@@ -135,9 +120,13 @@
 
             log.error("rpc-not-implemented", rpc=request['command'])
 
-        except Exception as e:
+        except ncerror.BadMsg as err:
+            log.info('ncerror.BadMsg')
             raise ncerror.BadMsg(rpc_node)
 
+        except Exception as e:
+            raise ncerror.ServerException(rpc_node, exception=e)
+
     rpc_class_handlers = {
         'getvoltha': GetVoltha,
         'get-config': GetConfig,
diff --git a/netconf/nc_rpc/rpc_response.py b/netconf/nc_rpc/rpc_response.py
index 150631b..a544598 100644
--- a/netconf/nc_rpc/rpc_response.py
+++ b/netconf/nc_rpc/rpc_response.py
@@ -41,6 +41,9 @@
             voltha_xml_string = voltha_xml_string[len('<yang>'):]
             if voltha_xml_string.endswith('</yang>'):
                 voltha_xml_string = voltha_xml_string[:-len('</yang>')]
+        # Empty response
+        elif voltha_xml_string.startswith('<yang/>'):
+            voltha_xml_string=''
 
         # Create the xml body as
         if request.has_key('subclass'):
@@ -151,6 +154,7 @@
         # special case the xml contain a list type
         if len(elms) == 1:
             item = elms[0]
+            #TODO: Address the case where the content is a list of list
             if item.get('type') == 'list':
                 item.tag = 'ignore'
                 self.add_node(self.process_element(item), top)