adding "isAvaliable" method for services

This commit is contained in:
Adolfo Gómez García 2022-01-13 13:32:36 +01:00
parent 8018c7bed7
commit 1667c8b4a8
11 changed files with 85 additions and 9 deletions

View File

@ -2,8 +2,7 @@
""" """
Url patterns for UDS project (Django) Url patterns for UDS project (Django)
""" """
from django.conf.urls import include from django.urls import include, path
from django.urls import path
# Uncomment the next two lines to enable the admin: # Uncomment the next two lines to enable the admin:

View File

@ -248,6 +248,7 @@ class Service(Module):
Returns if this service is reachable (that is, we can operate with it). This is used, for example, to check Returns if this service is reachable (that is, we can operate with it). This is used, for example, to check
if a service is "operable" before removing an user service (that is, pass from "waiting for remove" to "removing") if a service is "operable" before removing an user service (that is, pass from "waiting for remove" to "removing")
By default, this method returns True. By default, this method returns True.
Ideally, availability should be cached for a while, so that we don't have to check it every time.
""" """
return True return True

View File

@ -48,7 +48,10 @@ class Cache:
hits = 0 hits = 0
misses = 0 misses = 0
# Some aliases
DEFAULT_VALIDITY = 60 DEFAULT_VALIDITY = 60
SHORT_VALIDITY = 5
LONG_VALIDITY = 3600
_owner: str _owner: str
_bowner: bytes _bowner: bytes
@ -98,6 +101,12 @@ class Cache:
# logger.debug('Cache inaccesible: %s:%s', skey, e) # logger.debug('Cache inaccesible: %s:%s', skey, e)
return defValue return defValue
def __getitem__(self, key: typing.Union[str, bytes]) -> typing.Any:
"""
Returns the cached value for the given key using the [] operator
"""
return self.get(key)
def remove(self, skey: typing.Union[str, bytes]) -> bool: def remove(self, skey: typing.Union[str, bytes]) -> bool:
""" """
Removes an stored cached item Removes an stored cached item
@ -112,6 +121,12 @@ class Cache:
logger.debug('key not found') logger.debug('key not found')
return False return False
def __delitem__(self, key: typing.Union[str, bytes]) -> None:
"""
Removes an stored cached item using the [] operator
"""
self.remove(key)
def clean(self) -> None: def clean(self) -> None:
Cache.delete(self._owner) Cache.delete(self._owner)
@ -148,6 +163,12 @@ class Cache:
except transaction.TransactionManagementError: except transaction.TransactionManagementError:
logger.debug('Transaction in course, cannot store value') logger.debug('Transaction in course, cannot store value')
def __setitem__(self, key: typing.Union[str, bytes], value: typing.Any) -> None:
"""
Stores a value in the cache using the [] operator with default validity
"""
self.put(key, value)
def refresh(self, skey: typing.Union[str, bytes]) -> None: def refresh(self, skey: typing.Union[str, bytes]) -> None:
# logger.debug('Refreshing key "%s" for cache "%s"' % (skey, self._owner,)) # logger.debug('Refreshing key "%s" for cache "%s"' % (skey, self._owner,))
try: try:

View File

@ -36,6 +36,7 @@ import inspect
import typing import typing
from uds.core.util.html import checkBrowser from uds.core.util.html import checkBrowser
from uds.core.util.cache import Cache
from uds.web.util import errors from uds.web.util import errors
@ -115,7 +116,7 @@ def ensureConected(func: typing.Callable[..., RT]) -> typing.Callable[..., RT]:
# Decorator that tries to get from cache before executing # Decorator that tries to get from cache before executing
def allowCache( def allowCache(
cachePrefix: str, cachePrefix: str,
cacheTimeout: int, cacheTimeout: typing.Union[typing.Callable[[], int], int] = Cache.DEFAULT_VALIDITY,
cachingArgs: typing.Optional[ cachingArgs: typing.Optional[
typing.Union[typing.List[int], typing.Tuple[int], int] typing.Union[typing.List[int], typing.Tuple[int], int]
] = None, ] = None,
@ -131,6 +132,8 @@ def allowCache(
:param cacheTimeout: The cache timeout in seconds :param cacheTimeout: The cache timeout in seconds
:param cachingArgs: The caching args. Can be a single integer or a list. :param cachingArgs: The caching args. Can be a single integer or a list.
First arg (self) is 0, so normally cachingArgs are 1, or [1,2,..] First arg (self) is 0, so normally cachingArgs are 1, or [1,2,..]
:param cachingKWArgs: The caching kwargs. Can be a single string or a list.
:param cachingKeyFnc: A function that receives the args and kwargs and returns the key
""" """
keyFnc = cachingKeyFnc or (lambda x: '') keyFnc = cachingKeyFnc or (lambda x: '')
@ -169,12 +172,17 @@ def allowCache(
if 'force' in kwargs: if 'force' in kwargs:
# Remove force key # Remove force key
del kwargs['force'] del kwargs['force']
# ic cacheTimeout is a function, call it
timeout = cacheTimeout
if callable(timeout):
timeout = timeout()
if args[0].cache: # Not in cache and object can cache it if args[0].cache: # Not in cache and object can cache it
data = fnc(*args, **kwargs) data = fnc(*args, **kwargs)
try: try:
# Maybe returned data is not serializable. In that case, cache will fail but no harm is done with this # Maybe returned data is not serializable. In that case, cache will fail but no harm is done with this
args[0].cache.put(cacheKey, data, cacheTimeout) args[0].cache.put(cacheKey, data, timeout)
except Exception as e: except Exception as e:
logger.debug( logger.debug(
'Data for %s is not serializable on call to %s, not cached. %s (%s)', 'Data for %s is not serializable on call to %s, not cached. %s (%s)',

View File

@ -39,6 +39,8 @@ from django.utils.translation import gettext_noop as _
from uds.core.services import ServiceProvider from uds.core.services import ServiceProvider
from uds.core.ui import gui from uds.core.ui import gui
from uds.core.util import validators from uds.core.util import validators
from uds.core.util.decorators import allowCache
from uds.core.util.cache import Cache
from .service import OGService from .service import OGService
from . import og from . import og
@ -283,3 +285,10 @@ class OGProvider(ServiceProvider):
def status(self, machineId: str) -> typing.Any: def status(self, machineId: str) -> typing.Any:
return self.api.status(machineId) return self.api.status(machineId)
@allowCache('reachable', Cache.SHORT_VALIDITY)
def isAvailable(self) -> bool:
"""
Check if aws provider is reachable
"""
return self.testConnection()[0]

View File

@ -213,3 +213,6 @@ class OGService(Service):
def isRemovableIfUnavailable(self): def isRemovableIfUnavailable(self):
return self.startIfUnavailable.isTrue() return self.startIfUnavailable.isTrue()
def isAvailable(self) -> bool:
return self.parent().isAvailable()

View File

@ -37,9 +37,11 @@ from django.utils.translation import gettext_noop as _
from uds.core.services import ServiceProvider from uds.core.services import ServiceProvider
from uds.core.ui import gui from uds.core.ui import gui
from uds.core.util import validators from uds.core.util import validators
from uds.core.util.cache import Cache
from uds.core.util.decorators import allowCache
from .service import LiveService
from . import on from . import on
from .service import LiveService
# Not imported at runtime, just for type checking # Not imported at runtime, just for type checking
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
@ -334,3 +336,10 @@ class OpenNebulaProvider(ServiceProvider): # pylint: disable=too-many-public-me
@staticmethod @staticmethod
def test(env: 'Environment', data: 'Module.ValuesType') -> typing.List[typing.Any]: def test(env: 'Environment', data: 'Module.ValuesType') -> typing.List[typing.Any]:
return OpenNebulaProvider(env, data).testConnection() return OpenNebulaProvider(env, data).testConnection()
@allowCache('reachable', Cache.SHORT_VALIDITY)
def isAvailable(self) -> bool:
"""
Check if aws provider is reachable
"""
return self.testConnection()[0]

View File

@ -320,3 +320,6 @@ class LiveService(Service):
self, machineId: str, username: str, password: str, domain: str self, machineId: str, username: str, password: str, domain: str
) -> typing.Dict[str, typing.Any]: ) -> typing.Dict[str, typing.Any]:
return self.parent().desktopLogin(machineId, username, password, domain) return self.parent().desktopLogin(machineId, username, password, domain)
def isAvailable(self) -> bool:
return self.parent().isAvailable()

View File

@ -30,16 +30,18 @@
""" """
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com .. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
""" """
import typing
import logging import logging
import typing
from django.utils.translation import gettext_noop as _ from django.utils.translation import gettext_noop as _
from uds.core.services import ServiceProvider from uds.core.services import ServiceProvider
from uds.core.ui import gui from uds.core.ui import gui
from uds.core.util import validators from uds.core.util import validators
from uds.core.util.cache import Cache
from uds.core.util.decorators import allowCache
from .service import LiveService
from . import openstack from . import openstack
from .service import LiveService
# Not imported at runtime, just for type checking # Not imported at runtime, just for type checking
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
@ -290,3 +292,11 @@ class OpenStackProvider(ServiceProvider):
""" """
return OpenStackProvider(env, data).testConnection() return OpenStackProvider(env, data).testConnection()
@allowCache('reachable', Cache.SHORT_VALIDITY)
def isAvailable(self) -> bool:
"""
Check if aws provider is reachable
"""
return self.testConnection()[0]

View File

@ -39,10 +39,11 @@ from django.utils.translation import gettext_noop as _
from uds.core.services import ServiceProvider from uds.core.services import ServiceProvider
from uds.core.ui import gui from uds.core.ui import gui
from uds.core.util import validators from uds.core.util import validators
from uds.core.util.cache import Cache
from uds.core.util.decorators import allowCache
from .service import LiveService
from . import openstack from . import openstack
from .service import LiveService
# Not imported at runtime, just for type checking # Not imported at runtime, just for type checking
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
@ -274,3 +275,12 @@ class ProviderLegacy(ServiceProvider):
""" """
return ProviderLegacy(env, data).testConnection() return ProviderLegacy(env, data).testConnection()
@allowCache('reachable', Cache.SHORT_VALIDITY)
def isAvailable(self) -> bool:
"""
Check if aws provider is reachable
"""
return self.testConnection()[0]

View File

@ -440,3 +440,6 @@ class LiveService(Service):
Returns the length of numbers part Returns the length of numbers part
""" """
return int(self.lenName.value) return int(self.lenName.value)
def isAvailable(self) -> bool:
return self.parent().isAvailable()