scripts/gestion/trigger/host.py

132 lines
4.2 KiB
Python

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
#
# Basic trigger host, will be imported from any other
# Contains a TriggerFactory, which records the host functions
# decorated with @record.
# Contains a trigger which calls good functions from factory.
#
# Author : Pierre-Elliott Bécue <becue@crans.org>
# License : GPLv3
# Date : 28/04/2014
"""This module provides host functions for trigger, such as the TriggerFactory which
stores parsers and services metadata.
"""
import collections
import functools
import gestion.config.trigger as trigger_config
from gestion.trigger.producer import EventProducer
# Clogger
import cranslib.clogger as clogger
LOGGER = clogger.CLogger("trigger", "host.py/ack", trigger_config.log_level, trigger_config.debug)
PRODUCER = EventProducer("trigger.civet")
class TriggerFactory(object):
"""Factory containing which function is part of the trigger set
"""
_services = {}
_parsers = collections.defaultdict(list)
@classmethod
def register_service(cls, key, value):
"""Stores the appropriate service in the factory"""
cls._services[key] = value
@classmethod
def get_service(cls, key):
"""Retrieves the appropriate service"""
return cls._services.get(key, None)
@classmethod
def get_services(cls):
"""Retrieves the list of all services"""
return cls._services.values()
@classmethod
def register_parser(cls, keys, parser):
"""Stores the attributes to watch and the function"""
for key in keys:
cls._parsers[key].append(parser)
@classmethod
def get_parser(cls, keyword):
"""Restitutes the parser using keywords"""
return cls._parsers[keyword]
def record_service(ack=True):
"""Records in the triggerfactory the function
The function provided are services to regen
"""
def enhance_func(func):
"""Creates an enhanced function which tests if ack is True and
creates an ack if it's the case."""
@functools.wraps(func)
def enhanced_func(*args, **kwargs):
"""Dummy"""
# The first arg is ob_id, execpt if kwargs.
if args:
__ob_id = args[0]
else:
__ob_id = kwargs['ob_id']
# The function does not return.
func(*args, **kwargs)
LOGGER.debug("[%r] Ran %r on (%r, %r)", __ob_id, func.func_name, args, kwargs,)
if ack:
# We send directly with routing key trigger.ack on the way.
# Thus, ack service does not need any parser.
routing_key = "ack"
body = (__ob_id, func.func_name)
LOGGER.debug("[%r] Ack %r.", __ob_id, body)
PRODUCER.send_message("trigger.%s" % (routing_key,), body)
TriggerFactory.register_service(func.func_name, enhanced_func)
return enhanced_func
return enhance_func
def trigger_service(what):
"""Calls the appropriate service"""
return TriggerFactory.get_service(what)
def record_parser(*args):
"""Stores the function in TriggerFactory, using args as
keys for the dict"""
def find_parser(func):
"""Adds the chaining_pos at the end of the return of functions."""
@functools.wraps(func)
def enhanced_func(*args, **kwargs):
"""dummy"""
__ob_id = args[0]
ret = func(*args, **kwargs)
LOGGER.debug("[%r] In record_parser.find_parser, ran %r(%r, %r). Got %r.", __ob_id, func.func_name, args, kwargs, ret)
if ret is not None:
ret = [elem for elem in ret] + [getattr(func, "chaining_pos", 0)]
LOGGER.debug("[%r] In record_parser.find_parser, for %r got chaining_pos %r", __ob_id, func.func_name, ret[-1])
return ret
TriggerFactory.register_parser(args, enhanced_func)
return enhanced_func
return find_parser
def chaining(pos):
"""Allows chaining of operations, by adding a position marker
on the function."""
def add_pos(func):
"""Adds the chaining_pos variable to func"""
LOGGER.debug("%r chaining pos : %r", func.func_name, pos)
setattr(func, "chaining_pos", pos)
return func
return add_pos