Add initial gRPC server
diff --git a/.gitignore b/.gitignore
index 5fdec72..11d18ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,8 @@
 # Protobuf output files
 voltha/core/protos/*.desc
 voltha/core/protos/*_pb2.py
+third_party/googleapis/**/*.desc
+third_party/googleapis/**/*_pb2.py
 
 # Editors
 *.bak
diff --git a/env.sh b/env.sh
index 8f3a07c..c24eb91 100644
--- a/env.sh
+++ b/env.sh
@@ -12,6 +12,9 @@
 fi
 . $VENVDIR/bin/activate
 
+# add top-level voltha dir to pythonpath
+export PYTHONPATH=$PYTHONPATH:$VOLTHA_BASE/voltha
+
 # assign DOCKER_HOST_IP to be the main ip address of this host
 export DOCKER_HOST_IP=$(python voltha/nethelpers.py)
 
diff --git a/requirements.txt b/requirements.txt
index 9580168..5f9796f 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,9 @@
 decorator>=3.4.0
 docker-py
 fluent-logger>=0.4.3
+grpc>=0.3
+grpcio>=1.0.0
+grpcio-tools>=1.0.0
 hash_ring>=1.3.1
 hexdump>=3.3
 klein>=15.3.1
diff --git a/third_party/googleapis/google/__init__.py b/third_party/googleapis/google/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/googleapis/google/__init__.py
diff --git a/third_party/googleapis/google/api/__init__.py b/third_party/googleapis/google/api/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/googleapis/google/api/__init__.py
diff --git a/voltha/core/__init__.py b/voltha/core/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/voltha/core/__init__.py
diff --git a/voltha/core/protos/Makefile b/voltha/core/protos/Makefile
index 5466e37..5452be7 100644
--- a/voltha/core/protos/Makefile
+++ b/voltha/core/protos/Makefile
@@ -22,7 +22,7 @@
 
 default: build
 
-PROTO_FILES := $(wildcard *.proto)
+PROTO_FILES := $(wildcard *.proto) $(wildcard google/api/*proto)
 PROTO_PB2_FILES := $(foreach f,$(PROTO_FILES),$(subst .proto,_pb2.py,$(f)))
 PROTO_DESC_FILES := $(foreach f,$(PROTO_FILES),$(subst .proto,.desc,$(f)))
 
@@ -42,7 +42,7 @@
 
 %_pb2.py: %.proto Makefile
 	@echo "Building protocol buffer artifacts from $<"
-	env LD_LIBRARY_PATH=$(PROTOC_LIBDIR) $(PROTOC) -I. -I$(VOLTHA_BASE)/third_party/googleapis --python_out=. --descriptor_set_out=$(basename $<).desc --include_source_info $<
+	env LD_LIBRARY_PATH=$(PROTOC_LIBDIR) python -m grpc.tools.protoc -I. -I$(VOLTHA_BASE)/third_party/googleapis --python_out=. --grpc_python_out=. --descriptor_set_out=$(basename $<).desc --include_source_info $<
 
 clean:
 	rm -f $(PROTO_PB2_FILES) $(PROTO_DESC_FILES)
diff --git a/voltha/core/protos/__init__.py b/voltha/core/protos/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/voltha/core/protos/__init__.py
diff --git a/voltha/core/protos/google2 b/voltha/core/protos/google2
new file mode 120000
index 0000000..689c27a
--- /dev/null
+++ b/voltha/core/protos/google2
@@ -0,0 +1 @@
+../../../third_party/googleapis/google
\ No newline at end of file
diff --git a/voltha/main.py b/voltha/main.py
index 20ef726..160eb76 100755
--- a/voltha/main.py
+++ b/voltha/main.py
@@ -20,15 +20,16 @@
 import argparse
 import os
 import time
+
 import yaml
 from twisted.internet.defer import inlineCallbacks
 
-from structlog_setup import setup_logging
-from coordinator import Coordinator
-from northbound.rest.health_check import init_rest_service
-from nethelpers import get_my_primary_interface, get_my_primary_local_ipv4
-from dockerhelpers import get_my_containers_name
-
+from voltha.coordinator import Coordinator
+from voltha.dockerhelpers import get_my_containers_name
+from voltha.nethelpers import get_my_primary_interface, get_my_primary_local_ipv4
+from voltha.northbound.grpc.grpc_server import VolthaGrpcServer
+from voltha.northbound.rest.health_check import init_rest_service
+from voltha.structlog_setup import setup_logging
 
 defs = dict(
     consul=os.environ.get('CONSUL', 'localhost:8500'),
@@ -192,6 +193,7 @@
 
         # components
         self.coordinator = None
+        self.grpc_server = None
 
         if not args.no_banner:
             print_banner(self.log)
@@ -213,13 +215,19 @@
             instance_id=self.args.instance_id,
             consul=self.args.consul)
         init_rest_service(self.args.rest_port)
+
+        self.grpc_server = VolthaGrpcServer().run()
+
         self.log.info('started-internal-services')
 
     @inlineCallbacks
     def shutdown_components(self):
         """Execute before the reactor is shut down"""
         self.log.info('exiting-on-keyboard-interrupt')
-        yield self.coordinator.shutdown()
+        if self.coordinator is not None:
+            yield self.coordinator.shutdown()
+        if self.grpc_server is not None:
+            yield self.grpc_server.shutdown()
 
     def start_reactor(self):
         from twisted.internet import reactor
diff --git a/voltha/northbound/grpc/__init__.py b/voltha/northbound/grpc/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/voltha/northbound/grpc/__init__.py
diff --git a/voltha/northbound/grpc/grpc_client.py b/voltha/northbound/grpc/grpc_client.py
new file mode 100644
index 0000000..3700da5
--- /dev/null
+++ b/voltha/northbound/grpc/grpc_client.py
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+"""Temp client code to test grpc server"""
+
+import grpc
+
+from voltha.northbound.grpc import pb2_loader
+from voltha.core.protos import voltha_pb2
+
+
+def run():
+    channel = grpc.insecure_channel('localhost:50055')
+    stub = voltha_pb2.HealthServiceStub(channel)
+    response = stub.GetHealthStatus(voltha_pb2.NullMessage())
+    print 'Health state:', response.state
+
+if __name__ == '__main__':
+    run()
diff --git a/voltha/northbound/grpc/grpc_server.py b/voltha/northbound/grpc/grpc_server.py
new file mode 100644
index 0000000..7e737ae
--- /dev/null
+++ b/voltha/northbound/grpc/grpc_server.py
@@ -0,0 +1,77 @@
+#
+# 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 server endpoint"""
+import grpc
+from concurrent import futures
+from structlog import get_logger
+
+from voltha.northbound.grpc import pb2_loader
+from voltha.core.protos import voltha_pb2
+
+log = get_logger()
+
+
+class HealthService(voltha_pb2.HealthServiceServicer):
+
+    def __init__(self, thread_pool):
+        self.thread_pool = thread_pool
+
+    def GetHealthStatus(self, request, context):
+        """Return current health status of a Voltha instance
+        """
+        log.info('get-health-status', request=request)
+        hs = voltha_pb2.HealthStatus()
+        hs.state = voltha_pb2.HealthStatus.HEALTHY
+        return hs
+
+
+class VolthaGrpcServer(object):
+
+    def __init__(self, port=50055):
+        self.port = port
+        log.info('init-grpc-server', port=self.port)
+        self.thread_pool = futures.ThreadPoolExecutor(max_workers=10)
+        self.server = grpc.server(self.thread_pool)
+
+        voltha_pb2.add_HealthServiceServicer_to_server(
+            HealthService(self.thread_pool), self.server)
+
+        self.server.add_insecure_port('[::]:%s' % self.port)
+
+    def run(self):
+        log.info('starting-grpc-server')
+        self.server.start()
+        return self
+
+    def shutdown(self, grace=0):
+        self.server.stop(grace)
+
+
+# This is to allow runninf the GRPC server in stand-alone mode
+if __name__ == '__main__':
+
+    server = VolthaGrpcServer().run()
+
+    import time
+    _ONE_DAY_IN_SECONDS = 60 * 60 * 24
+    try:
+        while 1:
+            time.sleep(_ONE_DAY_IN_SECONDS)
+    except KeyboardInterrupt:
+        server.shutdown()
+
+
diff --git a/voltha/northbound/grpc/pb2_loader.py b/voltha/northbound/grpc/pb2_loader.py
new file mode 100644
index 0000000..920ebab
--- /dev/null
+++ b/voltha/northbound/grpc/pb2_loader.py
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+"""Assist in loading *_pb2.py protobuf files"""
+
+import sys
+
+
+#~~~~~~~~~~~~~~~~~~~~ begin import hach ~~~~~~~~~~~~~~~~~~~~~~~~~
+# Import hack to allow loading the google.api local files
+# without shadowing the google.protoc dependency. We needed
+# to do this because the grpc-generated pb2 files use
+# "from google.api import ..." directive and we cannot alter
+# the path.
+class ModuleProxy(object):
+    def __getattr__(self, key):
+        if key == 'http_pb2':
+            return http_pb2
+        elif key == 'annotations_pb2':
+            return annotations_pb2
+        else:
+            return None
+sys.modules['google.api'] = ModuleProxy()
+from voltha.core.protos.google2.api import http_pb2
+from voltha.core.protos.google2.api import annotations_pb2
+#~~~~~~~~~~~~~~~~~~~~  end import hach  ~~~~~~~~~~~~~~~~~~~~~~~~~
+