Commit ebe9fff8 authored by Gianluca Marotta's avatar Gianluca Marotta
Browse files

CT-205 Added transaction_id decorator

parent 3eeec585
Loading
Loading
Loading
Loading
Loading
+36 −47
Original line number Diff line number Diff line
import sys
import os

import tango
from .cspcommons import CmdExecState
from ska.base.control_model import AdminMode,ObsState
import functools
import json
from ska.log_transactions import transaction
from ska.base.control_model import AdminMode,ObsState
from .cspcommons import CmdExecState

def transaction_id(func):
    """
    This decorator add a transaction id to the input of the decorated method. 
    The input of the decorated method is a json string.
    
    """
    @functools.wraps(func)
    def wrap(*args, **kwargs):
        
        # Argument of the decorated method can be either positional or named. 
        # Following code manage both cases.
        # A named argument occurs when applied to "do" method of SKA Base Command Classes.
        # argument must be single.
        # note that args[0] is the "self" object of the class of the decorated method.
        if kwargs:
            keys=list(kwargs.keys())
            argin = kwargs[keys[0]]    
        elif len(args)>1:
            argin = args[1]
        else:
            raise Exception('No argument are passed to the transaction ID decorator')
        parameters =json.loads(argin)
        obj = args[0]

        #note: obj.name is the Command Class Name.
        with transaction(obj.name, parameters,logger=obj.logger) as transaction_id:    

            parameters['transaction_id'] = transaction_id

        argin = json.dumps(parameters)
        return func(obj,argin)
    return wrap

class AdminModeCheck(object):
    """
@@ -47,50 +80,6 @@ class AdminModeCheck(object):
            return f(*args, **kwargs)
        return admin_mode_check


VALID_OBS_STATE = {'reset': [ObsState.ABORTED],
                   'configscan': [ObsState.IDLE, ObsState.READY],
                   'scan': [ObsState.READY],
                   'endscan': [ObsState.SCANNING],
                   'gotoidle': [ObsState.READY, ObsState.IDLE],
                   'addresources': [ObsState.IDLE],
                   'removeresources': [ObsState.IDLE]
                   }


class ObsStateCheck(object):
    """
    Class designed to be a decorator for the CspMaster methods.
    It checks the obsMode attribute value
    """

    def __init__(self, args=False, kwargs=False):
        self._args = args
        self._kwargs = kwargs

    def __call__(self, f):
        @functools.wraps(f)
        def obs_state_check(*args, **kwargs):
            # get the  device instance
            dev_instance = args[0]
            cmd_type = self._args

            dev_instance.logger.info("device obs_state: {}".format(dev_instance._obs_state))
            # Check the obsState attribute value: valid values for the command to
            # execute are defined by VALID_OBS_STATE dictionary
            if dev_instance._obs_state not in VALID_OBS_STATE[cmd_type]:
                msg_args = (f.__name__, ObsState(dev_instance._obs_state).name)
                err_msg = ("{} command can't be issued when the"
                           " obsState is {} ".format(*msg_args))

                tango.Except.throw_exception("Command not executable",
                                             err_msg,
                                             "ObsStateCheck decorator",
                                             tango.ErrSeverity.ERR)
            return f(*args, **kwargs)
        return obs_state_check


class CmdInputArgsCheck(object):
    """
    Class designed to be a decorator for the CspMaster methods.