CORD-2868 GetLoadStatus returns present if app is present

Change-Id: Iebf76609530a13d60a5a587d9a2cb328afda682a
diff --git a/xos/coreapi/dynamicbuild.py b/xos/coreapi/dynamicbuild.py
index a41fc89..96e4d39 100644
--- a/xos/coreapi/dynamicbuild.py
+++ b/xos/coreapi/dynamicbuild.py
@@ -54,6 +54,9 @@
             self.pre_validate_file(item)
 
     def get_manifests(self):
+        if not os.path.exists(self.manifest_dir):
+            return []
+
         manifests=[]
         for fn in os.listdir(self.manifest_dir):
             if fn.endswith(".json"):
diff --git a/xos/coreapi/grpc_server.py b/xos/coreapi/grpc_server.py
index 3ae2bf1..1450756 100644
--- a/xos/coreapi/grpc_server.py
+++ b/xos/coreapi/grpc_server.py
@@ -101,6 +101,7 @@
         self.thread_pool = futures.ThreadPoolExecutor(max_workers=1)
         self.server = grpc.server(self.thread_pool)
         self.django_initialized = False
+        self.django_apps = []
 
         server_key = open(SERVER_KEY,"r").read()
         server_cert = open(SERVER_CERT,"r").read()
@@ -114,10 +115,15 @@
         self.services = []
 
     def init_django(self):
-        import django
-        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-        django.setup()
-        self.django_initialized = True
+        try:
+            import django
+            os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
+            django.setup()
+            from django.apps import apps
+            self.django_apps = apps
+            self.django_initialized = True
+        except:
+            log.exception("Failed to initialize django")
 
     def register_core(self):
         from xos_grpc_api import XosService
@@ -144,14 +150,16 @@
                       schema_pb2_grpc.add_SchemaServiceServicer_to_server,
                       SchemaService(self.thread_pool))
 
+        dynamic_load_service = DynamicLoadService(self.thread_pool, self)
         self.register("dynamicload",
                       dynamicload_pb2_grpc.add_dynamicloadServicer_to_server,
-                      DynamicLoadService(self.thread_pool, self))
+                      dynamic_load_service)
 
         if (self.model_status == 0):
             self.init_django()
 
         if (self.django_initialized):
+            dynamic_load_service.set_django_apps(self.django_apps)
             self.register_core()
             self.register_utility()
             self.register_modeldefs()
diff --git a/xos/coreapi/protos/dynamicload.proto b/xos/coreapi/protos/dynamicload.proto
index 7827adb..14dcf87 100644
--- a/xos/coreapi/protos/dynamicload.proto
+++ b/xos/coreapi/protos/dynamicload.proto
@@ -70,7 +70,6 @@
   rpc GetLoadStatus(google.protobuf.Empty) returns (LoadStatusReply) {
         option (google.api.http) = {
             get: "/xosapi/v1/dynamicload/load_status"
-            body: "*"
         };
   }
 };
diff --git a/xos/coreapi/xos_dynamicload_api.py b/xos/coreapi/xos_dynamicload_api.py
index 53ad93e..cadfaa6 100644
--- a/xos/coreapi/xos_dynamicload_api.py
+++ b/xos/coreapi/xos_dynamicload_api.py
@@ -32,10 +32,18 @@
     def __init__(self, thread_pool, server):
         self.thread_pool = thread_pool
         self.server = server
+        self.django_apps = None
 
     def stop(self):
         pass
 
+    def set_django_apps(self, django_apps):
+        """ Allows the creator of DynamicLoadService to pass in a pointer to django's app list once django has been
+            installed. This is optional. We don't import django.apps directly, as DynamicLoadService must be able
+            to run even if django is broken due to modeling issues.
+        """
+        self.django_apps = django_apps
+
     def LoadModels(self, request, context):
         try:
             builder = DynamicBuilder()
@@ -69,6 +77,11 @@
             raise e
 
     def GetLoadStatus(self, request, context):
+        django_apps_by_name = {}
+        if self.django_apps:
+            for app in self.django_apps.get_app_configs():
+                django_apps_by_name[app.name] = app
+
         try:
             builder = DynamicBuilder()
             manifests = builder.get_manifests()
@@ -82,6 +95,12 @@
                 item.version = manifest["version"]
                 item.state = manifest.get("state", "unspecified")
 
+                if item.state == "load":
+                    django_app = django_apps_by_name.get("services." + item.name)
+                    if django_app:
+                        item.state = "present"
+                        # TODO: Might be useful to return a list of models as well
+
             return response
         except Exception, e:
             import traceback; traceback.print_exc()