CORD-2754 Add restart command line option

Change-Id: I1c88e71a44d1f2777c550fcfeb32afd6e365321a
diff --git a/__init__.py b/__init__.py
index e69de29..1a13cdf 100644
--- a/__init__.py
+++ b/__init__.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017 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.
+#
diff --git a/grpc_client/__init__.py b/grpc_client/__init__.py
index e69de29..1a13cdf 100644
--- a/grpc_client/__init__.py
+++ b/grpc_client/__init__.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017 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.
+#
diff --git a/grpc_client/grpc_client.py b/grpc_client/grpc_client.py
index 62814ef..730887c 100644
--- a/grpc_client/grpc_client.py
+++ b/grpc_client/grpc_client.py
@@ -51,12 +51,13 @@
     RETRY_BACKOFF = [0.05, 0.1, 0.2, 0.5, 1, 2, 5]
 
     def __init__(self, consul_endpoint, work_dir, endpoint='localhost:50055',
-                 reconnect_callback=None, credentials=None):
+                 reconnect_callback=None, credentials=None, restart_on_disconnect=False):
         self.consul_endpoint = consul_endpoint
         self.endpoint = endpoint
         self.work_dir = work_dir
         self.reconnect_callback = reconnect_callback
         self.credentials = credentials
+        self.restart_on_disconnect = restart_on_disconnect
 
         self.plugin_dir = os.path.abspath(os.path.join(
             os.path.dirname(__file__), '../protoc_plugins'))
@@ -66,6 +67,7 @@
         self.retries = 0
         self.shutting_down = False
         self.connected = False
+        self.was_connected = False
 
     def start(self):
         log.debug('starting')
@@ -85,6 +87,14 @@
         self.reconnect_callback = reconnect_callback
         return self
 
+    def connectivity_callback(self, connectivity):
+        if (self.was_connected) and (connectivity in [connectivity.TRANSIENT_FAILURE, connectivity.FATAL_FAILURE, connectivity.SHUTDOWN]):
+            log.info("connectivity lost -- restarting")
+            os.execv(sys.executable, ['python'] + sys.argv)
+
+        if (connectivity == connectivity.READY):
+            self.was_connected = True
+
     @inlineCallbacks
     def connect(self):
         """
@@ -108,6 +118,9 @@
                 log.info('insecurely connecting', endpoint=_endpoint)
                 self.channel = grpc.insecure_channel(_endpoint)
 
+            if self.restart_on_disconnect:
+                self.channel.subscribe(self.connectivity_callback)
+
             swagger_from = self._retrieve_schema()
             self._compile_proto_files(swagger_from)
             self._clear_backoff()
diff --git a/main.py b/main.py
index a06e15d..2d06e53 100755
--- a/main.py
+++ b/main.py
@@ -197,6 +197,12 @@
                         default=defs['cert'],
                         help=_help)
 
+    _help = ('Restart chameleon if the gRPC connection is disconnected.')
+    parser.add_argument('-r', '--restart',
+                        dest='restart',
+                        action='store_true',
+                        default=False,
+                        help=_help)
 
     args = parser.parse_args()
 
@@ -264,7 +270,7 @@
             self.log.info('starting-internal-components')
             args = self.args
             self.grpc_client = yield \
-                GrpcClient(args.consul, args.work_dir, args.grpc_endpoint)
+                GrpcClient(args.consul, args.work_dir, args.grpc_endpoint, restart_on_disconnect=args.restart)
 
             if args.enable_tls == "False":
                 self.log.info('tls-disabled-through-configuration')
diff --git a/protoc_plugins/__init__.py b/protoc_plugins/__init__.py
index e69de29..1a13cdf 100644
--- a/protoc_plugins/__init__.py
+++ b/protoc_plugins/__init__.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017 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.
+#
diff --git a/protos/__init__.py b/protos/__init__.py
index e69de29..1a13cdf 100644
--- a/protos/__init__.py
+++ b/protos/__init__.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017 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.
+#
diff --git a/protos/third_party/google/__init__.py b/protos/third_party/google/__init__.py
index e69de29..1a13cdf 100644
--- a/protos/third_party/google/__init__.py
+++ b/protos/third_party/google/__init__.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017 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.
+#
diff --git a/utils/__init__.py b/utils/__init__.py
index e69de29..1a13cdf 100644
--- a/utils/__init__.py
+++ b/utils/__init__.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017 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.
+#
diff --git a/web_server/__init__.py b/web_server/__init__.py
index e69de29..1a13cdf 100644
--- a/web_server/__init__.py
+++ b/web_server/__init__.py
@@ -0,0 +1,15 @@
+
+# Copyright 2017 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.
+#