Refactor the AAI cache for multicloud plugin 81/75081/1
authorBin Yang <bin.yang@windriver.com>
Tue, 25 Dec 2018 10:42:52 +0000 (10:42 +0000)
committerBin Yang <bin.yang@windriver.com>
Wed, 26 Dec 2018 03:14:25 +0000 (03:14 +0000)
Fix the cache issue of cloud region which result in failure of
cloud region registration

Change-Id: Id13a40124efb92bd818686e069c9335ecd0d07c1
Issue-ID: MULTICLOUD-431
Signed-off-by: Bin Yang <bin.yang@windriver.com>
share/common/msapi/extsys.py
share/common/utils/aai_cache.py [new file with mode: 0644]
share/common/utils/restcall.py

index 9b65072..88118aa 100644 (file)
@@ -12,7 +12,6 @@
 import json
 import logging
 import re
-from django.core.cache import cache
 
 from common.exceptions import VimDriverNewtonException
 from common.utils import restcall
@@ -22,13 +21,6 @@ logger = logging.getLogger(__name__)
 
 
 def get_vim_by_id(vim_id):
-
-    # try to load from cache
-    cachedviminfostr = cache.get("VIMINFOCACHE_"+vim_id)
-    if cachedviminfostr:
-        viminfo = json.loads(cachedviminfostr)
-        return viminfo
-
     cloud_owner,cloud_region_id = decode_vim_id(vim_id)
 
     if cloud_owner and cloud_region_id:
@@ -81,8 +73,6 @@ def get_vim_by_id(vim_id):
             viminfo['openstack_region_id'] = tmp_viminfo.get("cloud-epa-caps") \
                 if tmp_viminfo.get("cloud-epa-caps") else cloud_region_id
 
-            # cache the viminfo for 24 hour
-            cache.set("VIMINFOCACHE_"+vim_id, json.dumps(viminfo), 3600*24)
             return viminfo
     return None
 
diff --git a/share/common/utils/aai_cache.py b/share/common/utils/aai_cache.py
new file mode 100644 (file)
index 0000000..53298bb
--- /dev/null
@@ -0,0 +1,53 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import json
+import logging
+from django.core.cache import cache
+
+logger = logging.getLogger(__name__)
+
+# note: memcached key length should be < 250, the value < 1MB
+
+def flush_cache_by_url(resource_url):
+    try:
+        cache.delete("AAI_" + resource_url)
+    except:
+        pass # silently drop any exception
+
+
+def get_cache_by_url(resource_url):
+    try:
+        if (filter_cache_by_url(resource_url)):
+            value = cache.get("AAI_" + resource_url)
+            return json.loads(value) if value else None
+        else:
+            return None
+    except:
+        return None
+
+
+def set_cache_by_url(resource_url, resource_in_json):
+    try:
+        # filter out unmanaged AAI resource
+        if filter_cache_by_url(resource_url):
+            # cache the resource for 24 hours
+            logger.debug("Cache the resource: "+ resource_url)
+            cache.set("AAI_" + resource_url, json.dumps(resource_in_json), 3600 * 24)
+    except:
+        pass
+
+def filter_cache_by_url(resource_url):
+    # hardcoded filter: cloud region only
+    if resource_url.find(r"cloud-infrastructure/cloud-regions/cloud-region") > 0:
+        return True
+    else:
+        return False
\ No newline at end of file
index ec3abb3..eb4cb00 100644 (file)
@@ -25,6 +25,8 @@ import uuid
 from rest_framework import status
 from django.conf import settings
 
+from common.utils import aai_cache
+
 rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
 HTTP_200_OK, HTTP_201_CREATED = '200', '201'
 HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED = '204', '202'
@@ -124,7 +126,7 @@ def req_to_vim(base_url, resource, method, extra_headers='', content=''):
                     resource, method, extra_headers, content)
 
 
-def req_to_aai(resource, method, content='', appid=settings.MULTICLOUD_APP_ID):
+def req_to_aai(resource, method, content='', appid=settings.MULTICLOUD_APP_ID, nocache=False):
     tmp_trasaction_id = '9003' #str(uuid.uuid1())
     headers = {
         'X-FromAppId': appid,
@@ -133,8 +135,22 @@ def req_to_aai(resource, method, content='', appid=settings.MULTICLOUD_APP_ID):
         'accept': 'application/json'
     }
 
-    return _call_req(settings.AAI_BASE_URL, settings.AAI_USERNAME, settings.AAI_PASSWORD, rest_no_auth,
-                    resource, method, content=json.dumps(content), extra_headers=headers)
+    # hook to flush cache
+    if method.upper() in ["PUT", "POST", "PATCH", "DELETE"]:
+        aai_cache.flush_cache_by_url(resource)
+    elif method.upper in ["GET"] and not nocache:
+        content = aai_cache.get_cache_by_url(resource)
+        if content:
+            return content
+
+    ret, resp_body, resp_status = _call_req(
+        settings.AAI_BASE_URL, settings.AAI_USERNAME, settings.AAI_PASSWORD, rest_no_auth,
+        resource, method, content=json.dumps(content), extra_headers=headers)
+
+    if method.upper() in ["GET"] and ret == 0 and not nocache:
+        aai_cache.set_cache_by_url(resource, [ret, resp_body, resp_status])
+
+    return [ret, resp_body, resp_status]
 
 
 def _combine_url(base_url, resource):