ckanext-d4science_theme/ckanext/d4science_theme/d4sdiscovery/d4s_namespaces_controller.py

131 lines
4.9 KiB
Python

import logging
import time
from d4s_cache_controller import D4S_Cache_Controller
from icproxycontroller import D4S_IS_DiscoveryCatalogueNamespaces
from threading import Event, Thread
CATEGORY = 'category'
NOCATEOGORY = 'nocategory'
log = logging.getLogger(__name__)
cancel_future_calls = None
# Refreshing time for namespaces cache in secs.
NAMESPACES_CACHE_REFRESHING_TIME = 60 * 60
# Funtion to call repeatedly another function
def call_repeatedly(interval, func, *args):
log.info("call_repeatedly called on func '{}' with interval {} sec".format(func.func_name, interval))
stopped = Event()
def loop():
while not stopped.wait(interval): # the first call is in `interval` secs
func(*args)
th = Thread(name='daemon_caching_namespaces', target=loop)
th.setDaemon(True)
th.start()
return stopped.set
def reload_namespaces_from_IS(urlICProxy, resourceID, gcubeToken):
log.info("_reload_namespaces_from_IS called")
try:
discovery_ctg_namespaces = D4S_IS_DiscoveryCatalogueNamespaces(urlICProxy, resourceID, gcubeToken)
namespaces_list_of_dict = discovery_ctg_namespaces.getNamespacesDictFromResource()
if namespaces_list_of_dict is not None and len(namespaces_list_of_dict) > 0:
log.debug("namespaces read from IS are: %s" % namespaces_list_of_dict)
D4S_Cache_Controller().write_namespaces(namespaces_list_of_dict)
else:
log.info("namespaces list read from IS is empty. Skipping caching update")
except Exception as e:
print("Error occurred on reading namespaces from IS and refilling the cache!")
print(e)
# Created by Francesco Mangiacrapa
# francesco.mangiacrapa@isti.cnr.it
# ISTI-CNR Pisa (ITALY)
# D4S_IS_DiscoveryCatalogueNamespacesController is used to discovery namespaces for Catalogue Categories (implemented as a Singleton)
# @param: urlICProxy is the URI of IC proxy rest-full service provided by IS
# @param: resourceID is the resource ID of the Generic Resource: "Namespaces Catalogue Categories"
# @param: gcubeToken the gcube token used to contact the IC proxy
class D4S_Namespaces_Controller():
__instance = None
@staticmethod
def getInstance():
""" Static access method. """
if D4S_Namespaces_Controller.__instance is None:
D4S_Namespaces_Controller()
return D4S_Namespaces_Controller.__instance
def __init__(self):
""" Virtually private constructor. """
log.debug("__init__ D4S_Namespaces_Controller")
if D4S_Namespaces_Controller.__instance is not None:
raise Exception("This class is a singleton!")
else:
D4S_Namespaces_Controller.__instance = self
self._d4s_cache_controller = D4S_Cache_Controller()
self._urlICProxy = None
self._resourceID = None
self._gcubeToken = None
def load_namespaces(self, urlICProxy, resourceID, gcubeToken):
log.debug("readNamespaces called")
self._urlICProxy = urlICProxy
self._resourceID = resourceID
self._gcubeToken = gcubeToken
return self._check_namespaces()
def _read_namespaces(self):
return self._d4s_cache_controller.read_namespaces()
def _check_namespaces(self):
log.debug("_check_namespaces called")
if self._d4s_cache_controller is None:
self._d4s_cache_controller = D4S_Cache_Controller()
namespace_list = self._read_namespaces()
# when the Cache is empty
if namespace_list is None or not namespace_list:
# reading namespaces from IS and filling the DB
log.info("The Cache is empty. Reading the namespace from IS and filling the Cache")
reload_namespaces_from_IS(self._urlICProxy, self._resourceID, self._gcubeToken)
# reloading the namespaces from the cache
namespace_list = self._read_namespaces()
# starting Thread daemon for refreshing the namespaces Cache
global cancel_future_calls
if cancel_future_calls is None:
cancel_future_calls = call_repeatedly(NAMESPACES_CACHE_REFRESHING_TIME, reload_namespaces_from_IS,
self._urlICProxy,
self._resourceID,
self._gcubeToken)
return namespace_list
def get_dict_ctg_namespaces(self):
log.debug("get_dict_ctg_namespaces called")
namespace_list_of_dict = self._check_namespaces()
return self.convert_namespaces_to_d4s_namespacedict(namespace_list_of_dict)
# Private method
@staticmethod
def convert_namespaces_to_d4s_namespacedict(namespace_list_of_dict):
log.debug("convert_namespaces_to_d4s_namespacedict called on %s" % namespace_list_of_dict)
return D4S_IS_DiscoveryCatalogueNamespaces.to_namespaces_dict_index_for_id(namespace_list_of_dict)