Chameleon rest-grpc gateway fetching and compiling
diff --git a/.gitignore b/.gitignore
index ada7197..9805cec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,10 +30,8 @@
 *.swp
 
 # Protobuf output files
-#voltha/core/protos/*.desc
-#voltha/core/protos/*_pb2.py
-#third_party/googleapis/**/*.desc
-#third_party/googleapis/**/*_pb2.py
+#voltha/**/*.desc
+#voltha/**/*_pb2.py
 
 # Editors
 *.bak
diff --git a/Dockerfile.chameleon b/Dockerfile.chameleon
index a916134..ea3e53a 100644
--- a/Dockerfile.chameleon
+++ b/Dockerfile.chameleon
@@ -21,6 +21,18 @@
 MAINTAINER Ali Al-Shabibi <ali.al-shabibi@onlab.us>
 MAINTAINER Nathan Knuth   <nathan.knuth@tibitcom.com>
 
+# Install protoc version 3.0.0; this is not yet the supported
+# version on xenial, so we need to "backport" it
+RUN apt-get install -y zlib1g-dev wget && \
+    wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/libprotoc10_3.0.0-7_amd64.deb && \
+    wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/libprotobuf-lite10_3.0.0-7_amd64.deb && \
+    wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/libprotobuf-dev_3.0.0-7_amd64.deb && \
+    wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/libprotobuf10_3.0.0-7_amd64.deb && \
+    wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/protobuf-compiler_3.0.0-7_amd64.deb && \
+    dpkg -i *.deb && \
+    protoc --version && \
+    rm -f *.deb
+
 # Bundle app source
 COPY chameleon /chameleon
 
diff --git a/Makefile b/Makefile
index 51c15f0..fea9f5e 100644
--- a/Makefile
+++ b/Makefile
@@ -67,12 +67,13 @@
 	@echo "fetch        : Pre-fetch artifacts for subsequent local builds"
 	@echo "flake8       : Run specifically flake8 tests"
 	@echo "help         : Print this help"
+	@echo "protos       : Compile all grpc/protobuf files"
 	@echo "rebuild-venv : Rebuild local Python virtualenv from scratch"
 	@echo "venv         : Build local Python virtualenv if did not exist yet"
 	@echo "utest        : Run all unit tests"
 	@echo
 
-build: utest build-protos docker-base
+build: utest protos docker-base
 	docker build -t cord/voltha -f Dockerfile.voltha .
 	docker build -t cord/chameleon -f Dockerfile.chameleon .
 
@@ -82,11 +83,12 @@
 	docker build -t cord/voltha-base -f Dockerfile.base .
 	touch .docker-base-built
 
-build-protos:
-	make -C voltha/core/protos
+protos:
+	make -C voltha/protos
+	make -C chameleon/protos
 
 install-protoc:
-	make -C voltha/core/protos install-protoc
+	make -C voltha/protos install-protoc
 
 clean:
 	find voltha -name '*.pyc' | xargs rm -f
diff --git a/voltha/core/protos/__init__.py b/chameleon/grpc_client/__init__.py
similarity index 100%
copy from voltha/core/protos/__init__.py
copy to chameleon/grpc_client/__init__.py
diff --git a/chameleon/grpc_client/grpc_client.py b/chameleon/grpc_client/grpc_client.py
new file mode 100644
index 0000000..2ce8d7c
--- /dev/null
+++ b/chameleon/grpc_client/grpc_client.py
@@ -0,0 +1,154 @@
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+gRPC client meant to connect to a gRPC server endpoint,
+and query the end-point's schema by calling
+SchemaService.Schema(NullMessage) and all of its
+semantics are derived from the recovered schema.
+"""
+import os
+
+import grpc
+import sys
+from consul import Consul
+from random import randint
+from structlog import get_logger
+from zlib import decompress
+
+from chameleon.protos.schema_pb2 import NullMessage, Schema, SchemaServiceStub
+
+log = get_logger()
+
+
+class GrpcClient(object):
+
+    def __init__(self, consul_endpoint, endpoint='localhost:50055'):
+        self.consul_endpoint = consul_endpoint
+        self.endpoint = endpoint
+        self.work_dir = '/tmp/chameleon'
+
+        self.channel = None
+        self.schema = None
+
+        self.shutting_down = False
+
+    def run(self):
+        self.connect()
+        return self
+
+    def shutdown(self):
+        if self.shutting_down:
+            return
+        self.shutting_down = True
+        pass
+
+    def connect(self):
+        """(re-)connect to end-point"""
+        if self.shutting_down:
+            return
+
+        try:
+            if self.endpoint.startswith('@'):
+                _endpoint = self.get_endpoint_from_consul(self.endpoint[1:])
+            else:
+                _endpoint = self.endpoint
+
+            log.info('connecting', endpoint=_endpoint)
+            self.channel = grpc.insecure_channel(_endpoint)
+
+            self._retrieve_schema()
+            self._compile_proto_files()
+
+        except Exception, e:
+            log.exception('cannot-connect', endpoint=_endpoint)
+
+    def get_endpoint_from_consul(self, service_name):
+        """Look up an appropriate grpc endpoint (host, port) from
+           consul, under the service name specified by service-name
+        """
+        host = self.consul_endpoint.split(':')[0].strip()
+        port = int(self.consul_endpoint.split(':')[1].strip())
+
+        consul = Consul(host=host, port=port)
+        _, services = consul.catalog.service(service_name)
+
+        if len(services) == 0:
+            raise Exception('Cannot find service %s in consul' % service_name)
+
+        # pick a random entry
+        # TODO should we prefer local IP addresses? Probably.
+
+        service = services[randint(0, len(services) - 1)]
+        endpoint = '{}:{}'.format(service['ServiceAddress'],
+                                  service['ServicePort'])
+        return endpoint
+
+    def _retrieve_schema(self):
+        """Retrieve schema from gRPC end-point"""
+        assert isinstance(self.channel, grpc.Channel)
+        stub = SchemaServiceStub(self.channel)
+        schema = stub.GetSchema(NullMessage())
+
+        os.system('mkdir -p %s' % self.work_dir)
+        os.system('rm -fr /tmp/%s/*' %
+                  self.work_dir.replace('/tmp/', ''))  # safer
+
+        for fname in schema.protos:
+            content = schema.protos[fname]
+            log.debug('saving-proto',
+                      fname=fname, dir=self.work_dir, length=len(content))
+            with open(os.path.join(self.work_dir, fname), 'w') as f:
+                f.write(content)
+
+        for fname in schema.descriptors:
+            content = decompress(schema.descriptors[fname])
+            log.debug('saving-descriptor',
+                      fname=fname, dir=self.work_dir, length=len(content))
+            with open(os.path.join(self.work_dir, fname), 'wb') as f:
+                f.write(content)
+
+    def _compile_proto_files(self):
+
+        google_api_dir = os.path.abspath(os.path.join(
+            os.path.dirname(__file__),
+            '../protos/third_party'
+        ))
+
+        for fname in [f for f in os.listdir(self.work_dir)
+                      if f.endswith('.proto')]:
+            log.info('compiling', file=fname)
+
+            cmd = (
+                'cd %s && '
+                'python -m grpc.tools.protoc '
+                '-I. '
+                '-I%s '
+                '--python_out=. '
+                '--grpc_python_out=. '
+                '%s' % (self.work_dir, google_api_dir, fname)
+            )
+            os.system(cmd)
+
+        # test-load each _pb2 file to see all is right
+        if self.work_dir not in sys.path:
+            sys.path.insert(0, self.work_dir)
+
+        for fname in [f for f in os.listdir(self.work_dir)
+                      if f.endswith('_pb2.py')]:
+            modname = fname[:-len('.py')]
+            log.debug('test-import', modname=modname)
+            _ = __import__(modname)
diff --git a/chameleon/main.py b/chameleon/main.py
index dbbca2f..e75de77 100755
--- a/chameleon/main.py
+++ b/chameleon/main.py
@@ -26,10 +26,12 @@
 
 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 sys.path.append(base_dir)
+sys.path.append(os.path.join(base_dir, '/chameleon/protos/third_party'))
 
 from chameleon.structlog_setup import setup_logging
 from chameleon.nethelpers import get_my_primary_local_ipv4
 from chameleon.dockerhelpers import get_my_containers_name
+from chameleon.grpc_client.grpc_client import GrpcClient
 
 
 defs = dict(
@@ -82,6 +84,18 @@
                         default=defs['fluentd'],
                         help=_help)
 
+    _help = ('gRPC end-point to connect to. It can either be a direct'
+             'definition in the form of <hostname>:<port>, or it can be an'
+             'indirect definition in the form of @<service-name> where'
+             '<service-name> is the name of the grpc service as registered'
+             'in consul (example: @voltha-grpc). (default: %s'
+             % defs['grpc_endpoint'])
+    parser.add_argument('-G', '--grpc-endpoint',
+                        dest='grpc_endpoint',
+                        action='store',
+                        default=defs['grpc_endpoint'],
+                        help=_help)
+
     _help = ('<hostname> or <ip> at which Chameleon is reachable from inside'
              'the cluster (default: %s)' % defs['internal_host_address'])
     parser.add_argument('-H', '--internal-host-address',
@@ -196,7 +210,9 @@
     def startup_components(self):
         self.log.info('starting-internal-components')
 
-        # TODO init client
+        self.grpc_client = \
+            GrpcClient(self.args.consul, self.args.grpc_endpoint).run()
+
         # TODO init server
 
         self.log.info('started-internal-services')
diff --git a/chameleon/protos/Makefile b/chameleon/protos/Makefile
new file mode 100644
index 0000000..9222ab1
--- /dev/null
+++ b/chameleon/protos/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Makefile to build all protobuf and gRPC related artifacts
+
+ifeq ($(VOLTHA_BASE)_set,_set)
+  $(error To get started, please source the env.sh file from Voltha top level directory)
+endif
+
+default: build
+
+PROTO_FILES := $(wildcard *.proto)
+PROTO_PB2_FILES := $(foreach f,$(PROTO_FILES),$(subst .proto,_pb2.py,$(f)))
+PROTO_DESC_FILES := $(foreach f,$(PROTO_FILES),$(subst .proto,.desc,$(f)))
+
+PROTOC_PREFIX := /usr/local
+PROTOC_LIBDIR := $(PROTOC_PREFIX)/lib
+
+build: $(PROTO_PB2_FILES)
+
+%_pb2.py: %.proto Makefile
+	@echo "Building protocol buffer artifacts from $<"
+	env LD_LIBRARY_PATH=$(PROTOC_LIBDIR) python -m grpc.tools.protoc \
+	    -I. \
+	    --python_out=. \
+	    --grpc_python_out=. \
+	    $<
+
+clean:
+	rm -f $(PROTO_PB2_FILES) $(PROTO_DESC_FILES)
+
diff --git a/voltha/core/protos/__init__.py b/chameleon/protos/__init__.py
similarity index 100%
copy from voltha/core/protos/__init__.py
copy to chameleon/protos/__init__.py
diff --git a/chameleon/protos/schema.proto b/chameleon/protos/schema.proto
new file mode 100644
index 0000000..530d74a
--- /dev/null
+++ b/chameleon/protos/schema.proto
@@ -0,0 +1,25 @@
+syntax = "proto3";
+
+package schema;
+
+// Proto file and compiled descriptor for this interface
+message Schema {
+
+  // file name -> proto file content
+  map<string, string> protos = 1;
+
+  // file name -> gzip compressed protobuf of descriptor
+  map<string, bytes> descriptors = 2;
+
+}
+
+// Empty message
+message NullMessage {}
+
+// Schema services
+service SchemaService {
+
+  // Return active grpc schemas
+  rpc GetSchema(NullMessage) returns (Schema) {}
+
+}
diff --git a/voltha/core/protos/third_party/__init__.py b/chameleon/protos/third_party/__init__.py
similarity index 100%
copy from voltha/core/protos/third_party/__init__.py
copy to chameleon/protos/third_party/__init__.py
diff --git a/voltha/core/protos/third_party/google/LICENSE b/chameleon/protos/third_party/google/LICENSE
similarity index 100%
copy from voltha/core/protos/third_party/google/LICENSE
copy to chameleon/protos/third_party/google/LICENSE
diff --git a/voltha/core/protos/third_party/google/__init__.py b/chameleon/protos/third_party/google/__init__.py
similarity index 100%
copy from voltha/core/protos/third_party/google/__init__.py
copy to chameleon/protos/third_party/google/__init__.py
diff --git a/voltha/core/protos/third_party/google/api/__init__.py b/chameleon/protos/third_party/google/api/__init__.py
similarity index 100%
copy from voltha/core/protos/third_party/google/api/__init__.py
copy to chameleon/protos/third_party/google/api/__init__.py
diff --git a/voltha/core/protos/third_party/google/api/annotations_pb2.py b/chameleon/protos/third_party/google/api/annotations_pb2.py
similarity index 100%
copy from voltha/core/protos/third_party/google/api/annotations_pb2.py
copy to chameleon/protos/third_party/google/api/annotations_pb2.py
diff --git a/voltha/core/protos/third_party/google/api/http_pb2.py b/chameleon/protos/third_party/google/api/http_pb2.py
similarity index 100%
copy from voltha/core/protos/third_party/google/api/http_pb2.py
copy to chameleon/protos/third_party/google/api/http_pb2.py
diff --git a/env.sh b/env.sh
index bd4f04c..84f9359 100644
--- a/env.sh
+++ b/env.sh
@@ -13,7 +13,7 @@
 . $VENVDIR/bin/activate
 
 # add top-level voltha dir to pythonpath
-export PYTHONPATH=$PYTHONPATH:$VOLTHA_BASE/voltha:$VOLTHA_BASE/voltha/core/protos/third_party
+export PYTHONPATH=$PYTHONPATH:$VOLTHA_BASE/voltha:$VOLTHA_BASE/voltha/protos/third_party
 
 # assign DOCKER_HOST_IP to be the main ip address of this host
 export DOCKER_HOST_IP=$(python voltha/nethelpers.py)
diff --git a/voltha/main.py b/voltha/main.py
index a3badea..ef03797 100755
--- a/voltha/main.py
+++ b/voltha/main.py
@@ -26,7 +26,7 @@
 
 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 sys.path.append(base_dir)
-sys.path.append(os.path.join(base_dir, '/voltha/core/protos/third_party'))
+sys.path.append(os.path.join(base_dir, '/voltha/protos/third_party'))
 
 from voltha.coordinator import Coordinator
 from voltha.dockerhelpers import get_my_containers_name
diff --git a/voltha/northbound/grpc/grpc_client.py b/voltha/northbound/grpc/grpc_client.py
index 60b0b6b..a9d2d55 100644
--- a/voltha/northbound/grpc/grpc_client.py
+++ b/voltha/northbound/grpc/grpc_client.py
@@ -18,7 +18,8 @@
 
 import grpc
 
-from voltha.core.protos import voltha_pb2
+from voltha.protos import schema_pb2
+from voltha.protos import voltha_pb2
 
 
 def run():
@@ -26,8 +27,8 @@
     channel = grpc.insecure_channel('localhost:50055')
 
     # Test fetch the schema
-    stub = voltha_pb2.SchemaServiceStub(channel)
-    res = stub.GetSchema(voltha_pb2.NullMessage())
+    stub = schema_pb2.SchemaServiceStub(channel)
+    res = stub.GetSchema(schema_pb2.NullMessage())
     print '\nSchema:\n'
     for key in res.protos:
         print '%s %s file begins %s\n' % (30 * '~', key, (35 - len(key)) * '~')
diff --git a/voltha/northbound/grpc/grpc_introspect.py b/voltha/northbound/grpc/grpc_introspect.py
index 9a30077..e2f24ca 100755
--- a/voltha/northbound/grpc/grpc_introspect.py
+++ b/voltha/northbound/grpc/grpc_introspect.py
@@ -160,7 +160,7 @@
 
     # try loading voltha descriptor and turn it into JSON data as a preparation
     # for generating JSON Schema / swagger file (to be done later)
-    from voltha.core.protos import voltha_pb2
+    from voltha.protos import voltha_pb2
     desc_dir = os.path.dirname(inspect.getfile(voltha_pb2))
     desc_file = os.path.join(desc_dir, 'voltha.desc')
     with open(desc_file, 'rb') as f:
diff --git a/voltha/northbound/grpc/grpc_server.py b/voltha/northbound/grpc/grpc_server.py
index 5b1d4ca..da824ea 100644
--- a/voltha/northbound/grpc/grpc_server.py
+++ b/voltha/northbound/grpc/grpc_server.py
@@ -15,6 +15,7 @@
 #
 
 """gRPC server endpoint"""
+import os
 import uuid
 from os.path import abspath, basename, dirname, join, walk
 import grpc
@@ -22,16 +23,16 @@
 from structlog import get_logger
 import zlib
 
-from voltha.core.protos import voltha_pb2
+from voltha.protos import voltha_pb2, schema_pb2
 
 log = get_logger()
 
 
-class SchemaService(voltha_pb2.SchemaServiceServicer):
+class SchemaService(schema_pb2.SchemaServiceServicer):
 
     def __init__(self):
         proto_map, descriptor_map = self._load_schema()
-        self.schema = voltha_pb2.Schema(
+        self.schema = schema_pb2.Schema(
             protos=proto_map,
             descriptors=descriptor_map
         )
@@ -40,13 +41,13 @@
         """Pre-load schema file so that we can serve it up (file sizes
            are small enough to do so
         """
-        proto_dir = abspath(join(dirname(__file__), '../../core/protos'))
+        proto_dir = abspath(join(dirname(__file__), '../../protos'))
 
         def find_files(dir, suffix):
-            proto_files = []
-            visitor = lambda _, d, fnames: proto_files.extend(
-                [join(d, fn) for fn in fnames if fn.endswith(suffix)])
-            walk(dir, visitor, None)
+            proto_files = [
+                join(dir, fname) for fname in os.listdir(dir)
+                if fname.endswith(suffix)
+            ]
             return proto_files
 
         proto_map = {}
@@ -135,12 +136,13 @@
         self.thread_pool = futures.ThreadPoolExecutor(max_workers=10)
         self.server = grpc.server(self.thread_pool)
 
+        schema_pb2.add_SchemaServiceServicer_to_server(
+            SchemaService(), self.server)
+
         voltha_pb2.add_HealthServiceServicer_to_server(
             HealthService(self.thread_pool), self.server)
         voltha_pb2.add_ExampleServiceServicer_to_server(
             ExampleService(self.thread_pool), self.server)
-        voltha_pb2.add_SchemaServiceServicer_to_server(
-            SchemaService(), self.server)
 
         self.server.add_insecure_port('[::]:%s' % self.port)
 
diff --git a/voltha/core/protos/Makefile b/voltha/protos/Makefile
similarity index 100%
rename from voltha/core/protos/Makefile
rename to voltha/protos/Makefile
diff --git a/voltha/core/protos/__init__.py b/voltha/protos/__init__.py
similarity index 100%
rename from voltha/core/protos/__init__.py
rename to voltha/protos/__init__.py
diff --git a/voltha/core/protos/voltha.desc b/voltha/protos/schema.desc
similarity index 90%
copy from voltha/core/protos/voltha.desc
copy to voltha/protos/schema.desc
index 035cafb..578b0e0 100644
--- a/voltha/core/protos/voltha.desc
+++ b/voltha/protos/schema.desc
Binary files differ
diff --git a/voltha/protos/schema.proto b/voltha/protos/schema.proto
new file mode 100644
index 0000000..8f9b643
--- /dev/null
+++ b/voltha/protos/schema.proto
@@ -0,0 +1,30 @@
+syntax = "proto3";
+
+package schema;
+
+import "google/api/annotations.proto";
+
+// Proto file and compiled descriptor for this interface
+message Schema {
+
+  // file name -> proto file content
+  map<string, string> protos = 1;
+
+  // file name -> gzip compressed protobuf of descriptor
+  map<string, bytes> descriptors = 2;
+
+}
+
+// Empty message
+message NullMessage {}
+
+// Schema services
+service SchemaService {
+
+  // Return active grpc schemas
+  rpc GetSchema(NullMessage) returns (Schema) {
+    option (google.api.http) = {
+      get: "/schema"
+    };
+  }
+}
diff --git a/voltha/protos/schema_pb2.py b/voltha/protos/schema_pb2.py
new file mode 100644
index 0000000..f8c5e46
--- /dev/null
+++ b/voltha/protos/schema_pb2.py
@@ -0,0 +1,302 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: schema.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='schema.proto',
+  package='schema',
+  syntax='proto3',
+  serialized_pb=_b('\n\x0cschema.proto\x12\x06schema\x1a\x1cgoogle/api/annotations.proto\"\xcd\x01\n\x06Schema\x12*\n\x06protos\x18\x01 \x03(\x0b\x32\x1a.schema.Schema.ProtosEntry\x12\x34\n\x0b\x64\x65scriptors\x18\x02 \x03(\x0b\x32\x1f.schema.Schema.DescriptorsEntry\x1a-\n\x0bProtosEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x32\n\x10\x44\x65scriptorsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"\r\n\x0bNullMessage2R\n\rSchemaService\x12\x41\n\tGetSchema\x12\x13.schema.NullMessage\x1a\x0e.schema.Schema\"\x0f\x82\xd3\xe4\x93\x02\t\x12\x07/schemab\x06proto3')
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_SCHEMA_PROTOSENTRY = _descriptor.Descriptor(
+  name='ProtosEntry',
+  full_name='schema.Schema.ProtosEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='schema.Schema.ProtosEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='schema.Schema.ProtosEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=163,
+  serialized_end=208,
+)
+
+_SCHEMA_DESCRIPTORSENTRY = _descriptor.Descriptor(
+  name='DescriptorsEntry',
+  full_name='schema.Schema.DescriptorsEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='schema.Schema.DescriptorsEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='schema.Schema.DescriptorsEntry.value', index=1,
+      number=2, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=210,
+  serialized_end=260,
+)
+
+_SCHEMA = _descriptor.Descriptor(
+  name='Schema',
+  full_name='schema.Schema',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='protos', full_name='schema.Schema.protos', index=0,
+      number=1, 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,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='descriptors', full_name='schema.Schema.descriptors', index=1,
+      number=2, 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,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_SCHEMA_PROTOSENTRY, _SCHEMA_DESCRIPTORSENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=55,
+  serialized_end=260,
+)
+
+
+_NULLMESSAGE = _descriptor.Descriptor(
+  name='NullMessage',
+  full_name='schema.NullMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=262,
+  serialized_end=275,
+)
+
+_SCHEMA_PROTOSENTRY.containing_type = _SCHEMA
+_SCHEMA_DESCRIPTORSENTRY.containing_type = _SCHEMA
+_SCHEMA.fields_by_name['protos'].message_type = _SCHEMA_PROTOSENTRY
+_SCHEMA.fields_by_name['descriptors'].message_type = _SCHEMA_DESCRIPTORSENTRY
+DESCRIPTOR.message_types_by_name['Schema'] = _SCHEMA
+DESCRIPTOR.message_types_by_name['NullMessage'] = _NULLMESSAGE
+
+Schema = _reflection.GeneratedProtocolMessageType('Schema', (_message.Message,), dict(
+
+  ProtosEntry = _reflection.GeneratedProtocolMessageType('ProtosEntry', (_message.Message,), dict(
+    DESCRIPTOR = _SCHEMA_PROTOSENTRY,
+    __module__ = 'schema_pb2'
+    # @@protoc_insertion_point(class_scope:schema.Schema.ProtosEntry)
+    ))
+  ,
+
+  DescriptorsEntry = _reflection.GeneratedProtocolMessageType('DescriptorsEntry', (_message.Message,), dict(
+    DESCRIPTOR = _SCHEMA_DESCRIPTORSENTRY,
+    __module__ = 'schema_pb2'
+    # @@protoc_insertion_point(class_scope:schema.Schema.DescriptorsEntry)
+    ))
+  ,
+  DESCRIPTOR = _SCHEMA,
+  __module__ = 'schema_pb2'
+  # @@protoc_insertion_point(class_scope:schema.Schema)
+  ))
+_sym_db.RegisterMessage(Schema)
+_sym_db.RegisterMessage(Schema.ProtosEntry)
+_sym_db.RegisterMessage(Schema.DescriptorsEntry)
+
+NullMessage = _reflection.GeneratedProtocolMessageType('NullMessage', (_message.Message,), dict(
+  DESCRIPTOR = _NULLMESSAGE,
+  __module__ = 'schema_pb2'
+  # @@protoc_insertion_point(class_scope:schema.NullMessage)
+  ))
+_sym_db.RegisterMessage(NullMessage)
+
+
+_SCHEMA_PROTOSENTRY.has_options = True
+_SCHEMA_PROTOSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_SCHEMA_DESCRIPTORSENTRY.has_options = True
+_SCHEMA_DESCRIPTORSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+import grpc
+from grpc.beta import implementations as beta_implementations
+from grpc.beta import interfaces as beta_interfaces
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import utilities as face_utilities
+
+
+class SchemaServiceStub(object):
+  """Schema services
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.GetSchema = channel.unary_unary(
+        '/schema.SchemaService/GetSchema',
+        request_serializer=NullMessage.SerializeToString,
+        response_deserializer=Schema.FromString,
+        )
+
+
+class SchemaServiceServicer(object):
+  """Schema services
+  """
+
+  def GetSchema(self, request, context):
+    """Return active grpc schemas
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_SchemaServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'GetSchema': grpc.unary_unary_rpc_method_handler(
+          servicer.GetSchema,
+          request_deserializer=NullMessage.FromString,
+          response_serializer=Schema.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'schema.SchemaService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
+
+
+class BetaSchemaServiceServicer(object):
+  """Schema services
+  """
+  def GetSchema(self, request, context):
+    """Return active grpc schemas
+    """
+    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+class BetaSchemaServiceStub(object):
+  """Schema services
+  """
+  def GetSchema(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+    """Return active grpc schemas
+    """
+    raise NotImplementedError()
+  GetSchema.future = None
+
+
+def beta_create_SchemaService_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+  request_deserializers = {
+    ('schema.SchemaService', 'GetSchema'): NullMessage.FromString,
+  }
+  response_serializers = {
+    ('schema.SchemaService', 'GetSchema'): Schema.SerializeToString,
+  }
+  method_implementations = {
+    ('schema.SchemaService', 'GetSchema'): face_utilities.unary_unary_inline(servicer.GetSchema),
+  }
+  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+  return beta_implementations.server(method_implementations, options=server_options)
+
+
+def beta_create_SchemaService_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+  request_serializers = {
+    ('schema.SchemaService', 'GetSchema'): NullMessage.SerializeToString,
+  }
+  response_deserializers = {
+    ('schema.SchemaService', 'GetSchema'): Schema.FromString,
+  }
+  cardinalities = {
+    'GetSchema': cardinality.Cardinality.UNARY_UNARY,
+  }
+  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+  return beta_implementations.dynamic_stub(channel, 'schema.SchemaService', cardinalities, options=stub_options)
+# @@protoc_insertion_point(module_scope)
diff --git a/voltha/core/protos/third_party/__init__.py b/voltha/protos/third_party/__init__.py
similarity index 100%
rename from voltha/core/protos/third_party/__init__.py
rename to voltha/protos/third_party/__init__.py
diff --git a/voltha/core/protos/third_party/google/LICENSE b/voltha/protos/third_party/google/LICENSE
similarity index 100%
rename from voltha/core/protos/third_party/google/LICENSE
rename to voltha/protos/third_party/google/LICENSE
diff --git a/voltha/core/protos/third_party/google/__init__.py b/voltha/protos/third_party/google/__init__.py
similarity index 100%
rename from voltha/core/protos/third_party/google/__init__.py
rename to voltha/protos/third_party/google/__init__.py
diff --git a/voltha/core/protos/third_party/google/api/__init__.py b/voltha/protos/third_party/google/api/__init__.py
similarity index 100%
rename from voltha/core/protos/third_party/google/api/__init__.py
rename to voltha/protos/third_party/google/api/__init__.py
diff --git a/voltha/core/protos/third_party/google/api/annotations.desc b/voltha/protos/third_party/google/api/annotations.desc
similarity index 100%
rename from voltha/core/protos/third_party/google/api/annotations.desc
rename to voltha/protos/third_party/google/api/annotations.desc
Binary files differ
diff --git a/voltha/core/protos/third_party/google/api/annotations.proto b/voltha/protos/third_party/google/api/annotations.proto
similarity index 100%
rename from voltha/core/protos/third_party/google/api/annotations.proto
rename to voltha/protos/third_party/google/api/annotations.proto
diff --git a/voltha/core/protos/third_party/google/api/annotations_pb2.py b/voltha/protos/third_party/google/api/annotations_pb2.py
similarity index 100%
rename from voltha/core/protos/third_party/google/api/annotations_pb2.py
rename to voltha/protos/third_party/google/api/annotations_pb2.py
diff --git a/voltha/core/protos/third_party/google/api/http.desc b/voltha/protos/third_party/google/api/http.desc
similarity index 100%
rename from voltha/core/protos/third_party/google/api/http.desc
rename to voltha/protos/third_party/google/api/http.desc
Binary files differ
diff --git a/voltha/core/protos/third_party/google/api/http.proto b/voltha/protos/third_party/google/api/http.proto
similarity index 100%
rename from voltha/core/protos/third_party/google/api/http.proto
rename to voltha/protos/third_party/google/api/http.proto
diff --git a/voltha/core/protos/third_party/google/api/http_pb2.py b/voltha/protos/third_party/google/api/http_pb2.py
similarity index 100%
rename from voltha/core/protos/third_party/google/api/http_pb2.py
rename to voltha/protos/third_party/google/api/http_pb2.py
diff --git a/voltha/core/protos/voltha.desc b/voltha/protos/voltha.desc
similarity index 93%
rename from voltha/core/protos/voltha.desc
rename to voltha/protos/voltha.desc
index 035cafb..2a42de8 100644
--- a/voltha/core/protos/voltha.desc
+++ b/voltha/protos/voltha.desc
Binary files differ
diff --git a/voltha/core/protos/voltha.proto b/voltha/protos/voltha.proto
similarity index 84%
rename from voltha/core/protos/voltha.proto
rename to voltha/protos/voltha.proto
index 9ce135a..87b6dda 100644
--- a/voltha/core/protos/voltha.proto
+++ b/voltha/protos/voltha.proto
@@ -8,17 +8,6 @@
 option java_outer_classname = "VolthaProtos";
 option csharp_namespace = "Opencord.Voltha.Voltha";
 
-// Proto file and compiled descriptor for this interface
-message Schema {
-
-  // file name -> proto file content
-  map<string, string> protos = 1;
-
-  // file name -> gzip compressed protobuf of descriptor
-  map<string, bytes> descriptors = 2;
-
-}
-
 // Empty message
 message NullMessage {}
 
@@ -37,17 +26,6 @@
 
 }
 
-// Schema services
-service SchemaService {
-
-  // Return active grpc schemas
-  rpc GetSchema(NullMessage) returns (Schema) {
-    option (google.api.http) = {
-      get: "/schema"
-    };
-  }
-}
-
 // Health related services
 service HealthService {
 
diff --git a/voltha/core/protos/voltha_pb2.py b/voltha/protos/voltha_pb2.py
similarity index 67%
rename from voltha/core/protos/voltha_pb2.py
rename to voltha/protos/voltha_pb2.py
index e82df67..65ae82f 100644
--- a/voltha/core/protos/voltha_pb2.py
+++ b/voltha/protos/voltha_pb2.py
@@ -20,7 +20,7 @@
   name='voltha.proto',
   package='voltha',
   syntax='proto3',
-  serialized_pb=_b('\n\x0cvoltha.proto\x12\x06voltha\x1a\x1cgoogle/api/annotations.proto\"\xcd\x01\n\x06Schema\x12*\n\x06protos\x18\x01 \x03(\x0b\x32\x1a.voltha.Schema.ProtosEntry\x12\x34\n\x0b\x64\x65scriptors\x18\x02 \x03(\x0b\x32\x1f.voltha.Schema.DescriptorsEntry\x1a-\n\x0bProtosEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x32\n\x10\x44\x65scriptorsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"\r\n\x0bNullMessage\"v\n\x0cHealthStatus\x12/\n\x05state\x18\x01 \x01(\x0e\x32 .voltha.HealthStatus.HealthState\"5\n\x0bHealthState\x12\x0b\n\x07HEALTHY\x10\x00\x12\x0e\n\nOVERLOADED\x10\x01\x12\t\n\x05\x44YING\x10\x02\"q\n\x07\x41\x64\x64ress\x12\n\n\x02id\x18\x07 \x01(\t\x12\x0e\n\x06street\x18\x01 \x01(\t\x12\x0f\n\x07street2\x18\x02 \x01(\t\x12\x0f\n\x07street3\x18\x03 \x01(\t\x12\x0c\n\x04\x63ity\x18\x04 \x01(\t\x12\r\n\x05state\x18\x05 \x01(\t\x12\x0b\n\x03zip\x18\x06 \x01(\r\"/\n\tAddresses\x12\"\n\taddresses\x18\x01 \x03(\x0b\x32\x0f.voltha.Address\"\x9f\x01\n\x0bMoreComplex\x12$\n\x06health\x18\x01 \x01(\x0b\x32\x14.voltha.HealthStatus\x12\x13\n\x0b\x66oo_counter\x18\x02 \x01(\x05\x12\x0c\n\x04name\x18\x03 \x01(\t\x12%\n\x08\x63hildren\x18\x04 \x03(\x0b\x32\x13.voltha.MoreComplex\x12 \n\x07\x61\x64\x64ress\x18\x05 \x01(\x0b\x32\x0f.voltha.Address\"\x10\n\x02ID\x12\n\n\x02id\x18\x01 \x01(\t2R\n\rSchemaService\x12\x41\n\tGetSchema\x12\x13.voltha.NullMessage\x1a\x0e.voltha.Schema\"\x0f\x82\xd3\xe4\x93\x02\t\x12\x07/schema2^\n\rHealthService\x12M\n\x0fGetHealthStatus\x12\x13.voltha.NullMessage\x1a\x14.voltha.HealthStatus\"\x0f\x82\xd3\xe4\x93\x02\t\x12\x07/health2\xb6\x02\n\x0e\x45xampleService\x12K\n\rListAddresses\x12\x13.voltha.NullMessage\x1a\x11.voltha.Addresses\"\x12\x82\xd3\xe4\x93\x02\x0c\x12\n/addresses\x12\x42\n\nGetAddress\x12\n.voltha.ID\x1a\x0f.voltha.Address\"\x17\x82\xd3\xe4\x93\x02\x11\x12\x0f/addresses/{id}\x12H\n\rCreateAddress\x12\x0f.voltha.Address\x1a\x0f.voltha.Address\"\x15\x82\xd3\xe4\x93\x02\x0f\"\n/addresses:\x01*\x12I\n\rDeleteAddress\x12\n.voltha.ID\x1a\x13.voltha.NullMessage\"\x17\x82\xd3\xe4\x93\x02\x11*\x0f/addresses/{id}B<\n\x13org.opencord.volthaB\x0cVolthaProtos\xaa\x02\x16Opencord.Voltha.Volthab\x06proto3')
+  serialized_pb=_b('\n\x0cvoltha.proto\x12\x06voltha\x1a\x1cgoogle/api/annotations.proto\"\r\n\x0bNullMessage\"v\n\x0cHealthStatus\x12/\n\x05state\x18\x01 \x01(\x0e\x32 .voltha.HealthStatus.HealthState\"5\n\x0bHealthState\x12\x0b\n\x07HEALTHY\x10\x00\x12\x0e\n\nOVERLOADED\x10\x01\x12\t\n\x05\x44YING\x10\x02\"q\n\x07\x41\x64\x64ress\x12\n\n\x02id\x18\x07 \x01(\t\x12\x0e\n\x06street\x18\x01 \x01(\t\x12\x0f\n\x07street2\x18\x02 \x01(\t\x12\x0f\n\x07street3\x18\x03 \x01(\t\x12\x0c\n\x04\x63ity\x18\x04 \x01(\t\x12\r\n\x05state\x18\x05 \x01(\t\x12\x0b\n\x03zip\x18\x06 \x01(\r\"/\n\tAddresses\x12\"\n\taddresses\x18\x01 \x03(\x0b\x32\x0f.voltha.Address\"\x9f\x01\n\x0bMoreComplex\x12$\n\x06health\x18\x01 \x01(\x0b\x32\x14.voltha.HealthStatus\x12\x13\n\x0b\x66oo_counter\x18\x02 \x01(\x05\x12\x0c\n\x04name\x18\x03 \x01(\t\x12%\n\x08\x63hildren\x18\x04 \x03(\x0b\x32\x13.voltha.MoreComplex\x12 \n\x07\x61\x64\x64ress\x18\x05 \x01(\x0b\x32\x0f.voltha.Address\"\x10\n\x02ID\x12\n\n\x02id\x18\x01 \x01(\t2^\n\rHealthService\x12M\n\x0fGetHealthStatus\x12\x13.voltha.NullMessage\x1a\x14.voltha.HealthStatus\"\x0f\x82\xd3\xe4\x93\x02\t\x12\x07/health2\xb6\x02\n\x0e\x45xampleService\x12K\n\rListAddresses\x12\x13.voltha.NullMessage\x1a\x11.voltha.Addresses\"\x12\x82\xd3\xe4\x93\x02\x0c\x12\n/addresses\x12\x42\n\nGetAddress\x12\n.voltha.ID\x1a\x0f.voltha.Address\"\x17\x82\xd3\xe4\x93\x02\x11\x12\x0f/addresses/{id}\x12H\n\rCreateAddress\x12\x0f.voltha.Address\x1a\x0f.voltha.Address\"\x15\x82\xd3\xe4\x93\x02\x0f\"\n/addresses:\x01*\x12I\n\rDeleteAddress\x12\n.voltha.ID\x1a\x13.voltha.NullMessage\"\x17\x82\xd3\xe4\x93\x02\x11*\x0f/addresses/{id}B<\n\x13org.opencord.volthaB\x0cVolthaProtos\xaa\x02\x16Opencord.Voltha.Volthab\x06proto3')
   ,
   dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,])
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -48,124 +48,12 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=342,
-  serialized_end=395,
+  serialized_start=134,
+  serialized_end=187,
 )
 _sym_db.RegisterEnumDescriptor(_HEALTHSTATUS_HEALTHSTATE)
 
 
-_SCHEMA_PROTOSENTRY = _descriptor.Descriptor(
-  name='ProtosEntry',
-  full_name='voltha.Schema.ProtosEntry',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='key', full_name='voltha.Schema.ProtosEntry.key', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=_b("").decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='value', full_name='voltha.Schema.ProtosEntry.value', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=_b("").decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
-  is_extendable=False,
-  syntax='proto3',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=163,
-  serialized_end=208,
-)
-
-_SCHEMA_DESCRIPTORSENTRY = _descriptor.Descriptor(
-  name='DescriptorsEntry',
-  full_name='voltha.Schema.DescriptorsEntry',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='key', full_name='voltha.Schema.DescriptorsEntry.key', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=_b("").decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='value', full_name='voltha.Schema.DescriptorsEntry.value', index=1,
-      number=2, type=12, cpp_type=9, label=1,
-      has_default_value=False, default_value=_b(""),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
-  is_extendable=False,
-  syntax='proto3',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=210,
-  serialized_end=260,
-)
-
-_SCHEMA = _descriptor.Descriptor(
-  name='Schema',
-  full_name='voltha.Schema',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='protos', full_name='voltha.Schema.protos', index=0,
-      number=1, 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,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='descriptors', full_name='voltha.Schema.descriptors', index=1,
-      number=2, 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,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[_SCHEMA_PROTOSENTRY, _SCHEMA_DESCRIPTORSENTRY, ],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  syntax='proto3',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=55,
-  serialized_end=260,
-)
-
-
 _NULLMESSAGE = _descriptor.Descriptor(
   name='NullMessage',
   full_name='voltha.NullMessage',
@@ -185,8 +73,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=262,
-  serialized_end=275,
+  serialized_start=54,
+  serialized_end=67,
 )
 
 
@@ -217,8 +105,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=277,
-  serialized_end=395,
+  serialized_start=69,
+  serialized_end=187,
 )
 
 
@@ -290,8 +178,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=397,
-  serialized_end=510,
+  serialized_start=189,
+  serialized_end=302,
 )
 
 
@@ -321,8 +209,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=512,
-  serialized_end=559,
+  serialized_start=304,
+  serialized_end=351,
 )
 
 
@@ -380,8 +268,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=562,
-  serialized_end=721,
+  serialized_start=354,
+  serialized_end=513,
 )
 
 
@@ -411,21 +299,16 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=723,
-  serialized_end=739,
+  serialized_start=515,
+  serialized_end=531,
 )
 
-_SCHEMA_PROTOSENTRY.containing_type = _SCHEMA
-_SCHEMA_DESCRIPTORSENTRY.containing_type = _SCHEMA
-_SCHEMA.fields_by_name['protos'].message_type = _SCHEMA_PROTOSENTRY
-_SCHEMA.fields_by_name['descriptors'].message_type = _SCHEMA_DESCRIPTORSENTRY
 _HEALTHSTATUS.fields_by_name['state'].enum_type = _HEALTHSTATUS_HEALTHSTATE
 _HEALTHSTATUS_HEALTHSTATE.containing_type = _HEALTHSTATUS
 _ADDRESSES.fields_by_name['addresses'].message_type = _ADDRESS
 _MORECOMPLEX.fields_by_name['health'].message_type = _HEALTHSTATUS
 _MORECOMPLEX.fields_by_name['children'].message_type = _MORECOMPLEX
 _MORECOMPLEX.fields_by_name['address'].message_type = _ADDRESS
-DESCRIPTOR.message_types_by_name['Schema'] = _SCHEMA
 DESCRIPTOR.message_types_by_name['NullMessage'] = _NULLMESSAGE
 DESCRIPTOR.message_types_by_name['HealthStatus'] = _HEALTHSTATUS
 DESCRIPTOR.message_types_by_name['Address'] = _ADDRESS
@@ -433,29 +316,6 @@
 DESCRIPTOR.message_types_by_name['MoreComplex'] = _MORECOMPLEX
 DESCRIPTOR.message_types_by_name['ID'] = _ID
 
-Schema = _reflection.GeneratedProtocolMessageType('Schema', (_message.Message,), dict(
-
-  ProtosEntry = _reflection.GeneratedProtocolMessageType('ProtosEntry', (_message.Message,), dict(
-    DESCRIPTOR = _SCHEMA_PROTOSENTRY,
-    __module__ = 'voltha_pb2'
-    # @@protoc_insertion_point(class_scope:voltha.Schema.ProtosEntry)
-    ))
-  ,
-
-  DescriptorsEntry = _reflection.GeneratedProtocolMessageType('DescriptorsEntry', (_message.Message,), dict(
-    DESCRIPTOR = _SCHEMA_DESCRIPTORSENTRY,
-    __module__ = 'voltha_pb2'
-    # @@protoc_insertion_point(class_scope:voltha.Schema.DescriptorsEntry)
-    ))
-  ,
-  DESCRIPTOR = _SCHEMA,
-  __module__ = 'voltha_pb2'
-  # @@protoc_insertion_point(class_scope:voltha.Schema)
-  ))
-_sym_db.RegisterMessage(Schema)
-_sym_db.RegisterMessage(Schema.ProtosEntry)
-_sym_db.RegisterMessage(Schema.DescriptorsEntry)
-
 NullMessage = _reflection.GeneratedProtocolMessageType('NullMessage', (_message.Message,), dict(
   DESCRIPTOR = _NULLMESSAGE,
   __module__ = 'voltha_pb2'
@@ -501,10 +361,6 @@
 
 DESCRIPTOR.has_options = True
 DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023org.opencord.volthaB\014VolthaProtos\252\002\026Opencord.Voltha.Voltha'))
-_SCHEMA_PROTOSENTRY.has_options = True
-_SCHEMA_PROTOSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
-_SCHEMA_DESCRIPTORSENTRY.has_options = True
-_SCHEMA_DESCRIPTORSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
 import grpc
 from grpc.beta import implementations as beta_implementations
 from grpc.beta import interfaces as beta_interfaces
@@ -512,95 +368,6 @@
 from grpc.framework.interfaces.face import utilities as face_utilities
 
 
-class SchemaServiceStub(object):
-  """Schema services
-  """
-
-  def __init__(self, channel):
-    """Constructor.
-
-    Args:
-      channel: A grpc.Channel.
-    """
-    self.GetSchema = channel.unary_unary(
-        '/voltha.SchemaService/GetSchema',
-        request_serializer=NullMessage.SerializeToString,
-        response_deserializer=Schema.FromString,
-        )
-
-
-class SchemaServiceServicer(object):
-  """Schema services
-  """
-
-  def GetSchema(self, request, context):
-    """Return active grpc schemas
-    """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-
-def add_SchemaServiceServicer_to_server(servicer, server):
-  rpc_method_handlers = {
-      'GetSchema': grpc.unary_unary_rpc_method_handler(
-          servicer.GetSchema,
-          request_deserializer=NullMessage.FromString,
-          response_serializer=Schema.SerializeToString,
-      ),
-  }
-  generic_handler = grpc.method_handlers_generic_handler(
-      'voltha.SchemaService', rpc_method_handlers)
-  server.add_generic_rpc_handlers((generic_handler,))
-
-
-class BetaSchemaServiceServicer(object):
-  """Schema services
-  """
-  def GetSchema(self, request, context):
-    """Return active grpc schemas
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-
-
-class BetaSchemaServiceStub(object):
-  """Schema services
-  """
-  def GetSchema(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
-    """Return active grpc schemas
-    """
-    raise NotImplementedError()
-  GetSchema.future = None
-
-
-def beta_create_SchemaService_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
-  request_deserializers = {
-    ('voltha.SchemaService', 'GetSchema'): NullMessage.FromString,
-  }
-  response_serializers = {
-    ('voltha.SchemaService', 'GetSchema'): Schema.SerializeToString,
-  }
-  method_implementations = {
-    ('voltha.SchemaService', 'GetSchema'): face_utilities.unary_unary_inline(servicer.GetSchema),
-  }
-  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
-  return beta_implementations.server(method_implementations, options=server_options)
-
-
-def beta_create_SchemaService_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
-  request_serializers = {
-    ('voltha.SchemaService', 'GetSchema'): NullMessage.SerializeToString,
-  }
-  response_deserializers = {
-    ('voltha.SchemaService', 'GetSchema'): Schema.FromString,
-  }
-  cardinalities = {
-    'GetSchema': cardinality.Cardinality.UNARY_UNARY,
-  }
-  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
-  return beta_implementations.dynamic_stub(channel, 'voltha.SchemaService', cardinalities, options=stub_options)
-
-
 class HealthServiceStub(object):
   """Health related services
   """