[SEBA-497]

Change to using alpine-grpc-base
Fix issue with nested exceptions causing an error in structlog
Reformat and python3 fixes, v3.5 mock support
Record execution times in the loader

Change-Id: I6d7923818d57012fca32ce44668820de422206d6
diff --git a/src/grpc_client/models_accessor.py b/src/grpc_client/models_accessor.py
index 2c96c48..445918a 100644
--- a/src/grpc_client/models_accessor.py
+++ b/src/grpc_client/models_accessor.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,11 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from xosconfig import Config
-from multistructlog import create_logger
-log = create_logger(Config().get('logging'))
+from __future__ import absolute_import
 
-from resources import RESOURCES
+from multistructlog import create_logger
+from xosconfig import Config
+
+from .resources import RESOURCES
+
+log = create_logger(Config().get("logging"))
+
+
+class GRPCModelsException(Exception):
+    """
+    Differentiates between exceptions created by GRPCModelsAccessor and other exceptions
+    """
+    pass
+
 
 class GRPCModelsAccessor:
     """
@@ -31,24 +41,31 @@
         """
 
         # NOTE: we need to import this later as it's generated by main.py
-        from KEYS import TOSCA_KEYS
+        from .KEYS import TOSCA_KEYS
 
         # get the key for this model
         try:
             filter_keys = TOSCA_KEYS[class_name]
-        except KeyError, e:
-            raise Exception("[XOS-TOSCA] Model %s doesn't have a tosca_key specified" % (class_name))
+        except KeyError:
+            raise GRPCModelsException(
+                "[XOS-TOSCA] Model %s doesn't have a tosca_key specified" % (class_name)
+            )
 
         if len(filter_keys) == 0:
-            raise Exception("[XOS-TOSCA] Model %s doesn't have a tosca_key specified" % (class_name))
+            raise GRPCModelsException(
+                "[XOS-TOSCA] Model %s doesn't have a tosca_key specified" % (class_name)
+            )
 
         filter = {}
         for k in filter_keys:
             if isinstance(k, str):
                 try:
                     filter[k] = data[k]
-                except KeyError, e:
-                    raise Exception("[XOS-TOSCA] Model %s doesn't have a property for the specified tosca_key (%s)" % (class_name, e))
+                except KeyError as e:
+                    raise GRPCModelsException(
+                        "[XOS-TOSCA] Model %s doesn't have a property for the specified tosca_key (%s)"
+                        % (class_name, e)
+                    )
             elif isinstance(k, list):
                 # one of they keys in this list has to be set
                 one_of_key = None
@@ -57,15 +74,23 @@
                         one_of_key = i
                         one_of_key_val = data[i]
                 if not one_of_key:
-                    raise Exception("[XOS-TOSCA] Model %s doesn't have a property for the specified tosca_key_one_of (%s)" % (class_name, k))
+                    raise GRPCModelsException(
+                        "[XOS-TOSCA] Model %s doesn't have a property for the specified tosca_key_one_of (%s)"
+                        % (class_name, k)
+                    )
                 else:
                     filter[one_of_key] = one_of_key_val
 
         key = "%s~%s" % (username, password)
-        if not key in RESOURCES:
-            raise Exception("[XOS-TOSCA] User '%s' does not have ready resources" % username)
+        if key not in RESOURCES:
+            raise GRPCModelsException(
+                "[XOS-TOSCA] User '%s' does not have ready resources" % username
+            )
         if class_name not in RESOURCES[key]:
-            raise Exception('[XOS-TOSCA] The model you are trying to create (class: %s, properties, %s) is not know by xos-core' % (class_name, str(filter)))
+            raise GRPCModelsException(
+                "[XOS-TOSCA] The model you are trying to create (class: %s, properties, %s) is not know by xos-core"
+                % (class_name, str(filter))
+            )
 
         cls = RESOURCES[key][class_name]
 
@@ -73,15 +98,27 @@
 
         if len(models) == 1:
             model = models[0]
-            log.info("[XOS-Tosca] Model of class %s and properties %s already exist, retrieving instance..." % (class_name, str(filter)), model=model)
+            log.info(
+                "[XOS-TOSCA] Model of class %s and properties %s already exist, retrieving instance..."
+                % (class_name, str(filter)),
+                model=model,
+            )
         elif len(models) == 0:
 
-            if 'must-exist' in data and data['must-exist']:
-                raise Exception("[XOS-TOSCA] Model of class %s and properties %s has property 'must-exist' but cannot be found" % (class_name, str(filter)))
+            if "must-exist" in data and data["must-exist"]:
+                raise GRPCModelsException(
+                    "[XOS-TOSCA] Model of class %s and properties %s has property 'must-exist' but cannot be found"
+                    % (class_name, str(filter))
+                )
 
             model = cls.objects.new()
-            log.info("[XOS-Tosca] Model (%s) is new, creating new instance..." % str(filter))
+            log.info(
+                "[XOS-TOSCA] Model (%s) is new, creating new instance..." % str(filter)
+            )
         else:
-            raise Exception("[XOS-Tosca] Model of class %s and properties %s has multiple instances, I can't handle it" % (class_name, str(filter)))
+            raise GRPCModelsException(
+                "[XOS-TOSCA] Model of class %s and properties %s has multiple instances, I can't handle it"
+                % (class_name, str(filter))
+            )
 
-        return model
\ No newline at end of file
+        return model