本文整理汇总了Python中st2common.transport.reactor.TriggerDispatcher.dispatch方法的典型用法代码示例。如果您正苦于以下问题:Python TriggerDispatcher.dispatch方法的具体用法?Python TriggerDispatcher.dispatch怎么用?Python TriggerDispatcher.dispatch使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类st2common.transport.reactor.TriggerDispatcher
的用法示例。
在下文中一共展示了TriggerDispatcher.dispatch方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: _inject_instances
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
def _inject_instances(trigger, rate_per_trigger, duration, payload=None, max_throughput=False):
payload = payload or {}
start = date_utils.get_datetime_utc_now()
elapsed = 0.0
count = 0
dispatcher = TriggerDispatcher()
while elapsed < duration:
# print('Dispatching trigger %s at time %s', trigger, date_utils.get_datetime_utc_now())
dispatcher.dispatch(trigger, payload)
if rate_per_trigger:
# NOTE: We decrease sleep delay for 56% to take into account overhead / delay because
# of the call to dispatchet.dispatch method.
delta = random.expovariate(rate_per_trigger)
eventlet.sleep(delta * 0.56)
elapsed = (date_utils.get_datetime_utc_now() - start).seconds
count += 1
actual_rate = int(count / elapsed)
print('%s: Emitted %d triggers in %d seconds (actual rate=%s triggers / second)' %
(trigger, count, elapsed, actual_rate))
# NOTE: Due to the overhead of dispatcher.dispatch call, we allow for 10% of deviation from
# requested rate before warning
if rate_per_trigger and (actual_rate < (rate_per_trigger * 0.9)):
print('')
print('Warning, requested rate was %s triggers / second, but only achieved %s '
'triggers / second' % (rate_per_trigger, actual_rate))
print('Too increase the throuput you will likely need to run multiple instances of '
'this script in parallel.')
示例2: SensorService
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class SensorService(object):
"""
Instance of this class is passed to the sensor instance and exposes "public"
methods which can be called by the sensor.
"""
def __init__(self, sensor_wrapper):
self._sensor_wrapper = sensor_wrapper
self._logger = self._sensor_wrapper._logger
self._dispatcher = TriggerDispatcher(self._logger)
def get_logger(self, name):
"""
Retrieve an instance of a logger to be used by the sensor class.
"""
logger_name = '%s.%s' % (self._sensor_wrapper._logger.name, name)
logger = logging.getLogger(logger_name)
logger.propagate = True
return logger
def dispatch(self, trigger, payload=None):
"""
Method which dispatches the trigger.
:param trigger: Full name / reference of the trigger.
:type trigger: ``str``
:param payload: Trigger payload.
:type payload: ``dict``
"""
self._dispatcher.dispatch(trigger, payload=payload)
示例3: Inquirer
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class Inquirer(ActionRunner):
"""This runner implements the ability to ask for more input during a workflow
"""
def __init__(self, runner_id):
super(Inquirer, self).__init__(runner_id=runner_id)
self.trigger_dispatcher = TriggerDispatcher(LOG)
def pre_run(self):
super(Inquirer, self).pre_run()
# TODO :This is awful, but the way "runner_parameters" and other variables get
# assigned on the runner instance is even worse. Those arguments should
# be passed to the constructor.
self.schema = self.runner_parameters.get(RUNNER_SCHEMA, DEFAULT_SCHEMA)
self.roles_param = self.runner_parameters.get(RUNNER_ROLES, [])
self.users_param = self.runner_parameters.get(RUNNER_USERS, [])
self.route = self.runner_parameters.get(RUNNER_ROUTE, "")
self.ttl = self.runner_parameters.get(RUNNER_TTL, 1440)
def run(self, action_parameters):
liveaction_db = action_utils.get_liveaction_by_id(self.liveaction_id)
exc = ActionExecution.get(liveaction__id=str(liveaction_db.id))
# Assemble and dispatch trigger
trigger_ref = ResourceReference.to_string_reference(
pack=INQUIRY_TRIGGER['pack'],
name=INQUIRY_TRIGGER['name']
)
trigger_payload = {
"id": str(exc.id),
"route": self.route
}
self.trigger_dispatcher.dispatch(trigger_ref, trigger_payload)
# We only want to request a pause if this has a parent
if liveaction_db.context.get("parent"):
# Get the root liveaction and request that it pauses
root_liveaction = action_service.get_root_liveaction(liveaction_db)
action_service.request_pause(
root_liveaction,
self.context.get('user', None)
)
result = {
"schema": self.schema,
"roles": self.roles_param,
"users": self.users_param,
"route": self.route,
"ttl": self.ttl
}
return (LIVEACTION_STATUS_PENDING, result, None)
示例4: _inject_instances
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
def _inject_instances(trigger, rate_per_trigger, duration, payload={}):
start = date_utils.get_datetime_utc_now()
elapsed = 0.0
count = 0
dispatcher = TriggerDispatcher()
while elapsed < duration:
# print('Dispatching trigger %s at time %s', trigger, date_utils.get_datetime_utc_now())
dispatcher.dispatch(trigger, payload)
delta = random.expovariate(rate_per_trigger)
eventlet.sleep(delta)
elapsed = (date_utils.get_datetime_utc_now() - start).seconds / 60.0
count += 1
print("%s: Emitted %d triggers in %d seconds" % (trigger, count, elapsed))
示例5: TriggerInstanceResendController
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class TriggerInstanceResendController(TriggerInstanceControllerMixin, resource.ResourceController):
supported_filters = {}
def __init__(self, *args, **kwargs):
super(TriggerInstanceResendController, self).__init__(*args, **kwargs)
self.trigger_dispatcher = TriggerDispatcher(LOG)
class TriggerInstancePayload(object):
def __init__(self, payload=None):
self.payload = payload or {}
def validate(self):
if self.payload:
assert isinstance(self.payload, dict)
return True
def post(self, trigger_instance_id):
"""
Re-send the provided trigger instance optionally specifying override parameters.
Handles requests:
POST /triggerinstance/<id>/re_emit
POST /triggerinstance/<id>/re_send
"""
# Note: We only really need parameters here
existing_trigger_instance = self._get_one_by_id(id=trigger_instance_id,
permission_type=None,
requester_user=None)
new_payload = copy.deepcopy(existing_trigger_instance.payload)
new_payload['__context'] = {
'original_id': trigger_instance_id
}
try:
self.trigger_dispatcher.dispatch(existing_trigger_instance.trigger,
new_payload)
return {
'message': 'Trigger instance %s succesfully re-sent.' % trigger_instance_id,
'payload': new_payload
}
except Exception as e:
abort(http_client.INTERNAL_SERVER_ERROR, six.text_type(e))
示例6: WebhooksController
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class WebhooksController(RestController):
def __init__(self, *args, **kwargs):
super(WebhooksController, self).__init__(*args, **kwargs)
self._hooks = {}
self._base_url = '/webhooks/'
self._trigger_types = WEBHOOK_TRIGGER_TYPES.keys()
self._trigger_dispatcher = TriggerDispatcher(LOG)
queue_suffix = self.__class__.__name__
self._trigger_watcher = TriggerWatcher(create_handler=self._handle_create_trigger,
update_handler=self._handle_update_trigger,
delete_handler=self._handle_delete_trigger,
trigger_types=self._trigger_types,
queue_suffix=queue_suffix,
exclusive=True)
self._trigger_watcher.start()
self._register_webhook_trigger_types()
@jsexpose()
def get_all(self):
# Return only the hooks known by this controller.
return [trigger for trigger in six.itervalues(self._hooks)]
@jsexpose()
def get_one(self, name):
hook = self._hooks.get(name, None)
if not hook:
abort(http_client.NOT_FOUND)
return
return hook
@request_user_has_webhook_permission(permission_type=PermissionType.WEBHOOK_SEND)
@jsexpose(arg_types=[str], status_code=http_client.ACCEPTED)
def post(self, *args, **kwargs):
hook = '/'.join(args) # TODO: There must be a better way to do this.
# Note: For backward compatibility reasons we default to application/json if content
# type is not explicitly provided
content_type = pecan.request.headers.get('Content-Type', 'application/json')
body = pecan.request.body
try:
body = self._parse_request_body(content_type=content_type, body=body)
except Exception as e:
self._log_request('Failed to parse request body: %s.' % (str(e)), pecan.request)
msg = 'Failed to parse request body "%s": %s' % (body, str(e))
return pecan.abort(http_client.BAD_REQUEST, msg)
headers = self._get_headers_as_dict(pecan.request.headers)
# If webhook contains a trace-tag use that else create create a unique trace-tag.
trace_context = self._create_trace_context(trace_tag=headers.pop(TRACE_TAG_HEADER, None),
hook=hook)
if hook == 'st2' or hook == 'st2/':
return self._handle_st2_webhook(body, trace_context=trace_context)
if not self._is_valid_hook(hook):
self._log_request('Invalid hook.', pecan.request)
msg = 'Webhook %s not registered with st2' % hook
return pecan.abort(http_client.NOT_FOUND, msg)
trigger = self._get_trigger_for_hook(hook)
payload = {}
payload['headers'] = headers
payload['body'] = body
self._trigger_dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
return body
def _parse_request_body(self, content_type, body):
if content_type == 'application/json':
self._log_request('Parsing request body as JSON', request=pecan.request)
body = json.loads(body)
elif content_type in ['application/x-www-form-urlencoded', 'multipart/form-data']:
self._log_request('Parsing request body as form encoded data', request=pecan.request)
body = urlparse.parse_qs(body)
else:
raise ValueError('Unsupported Content-Type: "%s"' % (content_type))
return body
def _handle_st2_webhook(self, body, trace_context):
trigger = body.get('trigger', None)
payload = body.get('payload', None)
if not trigger:
msg = 'Trigger not specified.'
return pecan.abort(http_client.BAD_REQUEST, msg)
self._trigger_dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
return body
def _is_valid_hook(self, hook):
# TODO: Validate hook payload with payload_schema.
return hook in self._hooks
def _get_trigger_for_hook(self, hook):
return self._hooks[hook]
#.........这里部分代码省略.........
示例7: SensorService
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class SensorService(object):
"""
Instance of this class is passed to the sensor instance and exposes "public"
methods which can be called by the sensor.
"""
def __init__(self, sensor_wrapper):
self._sensor_wrapper = sensor_wrapper
self._logger = self._sensor_wrapper._logger
self._dispatcher = TriggerDispatcher(self._logger)
self._datastore_service = DatastoreService(logger=self._logger,
pack_name=self._sensor_wrapper._pack,
class_name=self._sensor_wrapper._class_name,
api_username='sensor_service')
self._client = None
def get_logger(self, name):
"""
Retrieve an instance of a logger to be used by the sensor class.
"""
logger_name = '%s.%s' % (self._sensor_wrapper._logger.name, name)
logger = logging.getLogger(logger_name)
logger.propagate = True
return logger
def dispatch(self, trigger, payload=None, trace_tag=None):
"""
Method which dispatches the trigger.
:param trigger: Full name / reference of the trigger.
:type trigger: ``str``
:param payload: Trigger payload.
:type payload: ``dict``
:param trace_tag: Tracer to track the triggerinstance.
:type trace_tags: ``str``
"""
# empty strings
trace_context = TraceContext(trace_tag=trace_tag) if trace_tag else None
self.dispatch_with_context(trigger, payload=payload, trace_context=trace_context)
def dispatch_with_context(self, trigger, payload=None, trace_context=None):
"""
Method which dispatches the trigger.
:param trigger: Full name / reference of the trigger.
:type trigger: ``str``
:param payload: Trigger payload.
:type payload: ``dict``
:param trace_context: Trace context to associate with Trigger.
:type trace_context: ``st2common.api.models.api.trace.TraceContext``
"""
self._dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
##################################
# Methods for datastore management
##################################
def list_values(self, local=True, prefix=None):
return self._datastore_service.list_values(local, prefix)
def get_value(self, name, local=True):
return self._datastore_service.get_value(name, local)
def set_value(self, name, value, ttl=None, local=True):
return self._datastore_service.set_value(name, value, ttl, local)
def delete_value(self, name, local=True):
return self._datastore_service.delete_value(name, local)
示例8: SensorService
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class SensorService(object):
"""
Instance of this class is passed to the sensor instance and exposes "public"
methods which can be called by the sensor.
"""
def __init__(self, sensor_wrapper):
self._sensor_wrapper = sensor_wrapper
self._logger = self._sensor_wrapper._logger
self._dispatcher = TriggerDispatcher(self._logger)
self._datastore_service = SensorDatastoreService(
logger=self._logger,
pack_name=self._sensor_wrapper._pack,
class_name=self._sensor_wrapper._class_name,
api_username='sensor_service')
self._client = None
@property
def datastore_service(self):
return self._datastore_service
def get_logger(self, name):
"""
Retrieve an instance of a logger to be used by the sensor class.
"""
logger_name = '%s.%s' % (self._sensor_wrapper._logger.name, name)
logger = logging.getLogger(logger_name)
logger.propagate = True
return logger
##################################
# General methods
##################################
def get_user_info(self):
return self._datastore_service.get_user_info()
##################################
# Sensor related methods
##################################
def dispatch(self, trigger, payload=None, trace_tag=None):
"""
Method which dispatches the trigger.
:param trigger: Full name / reference of the trigger.
:type trigger: ``str``
:param payload: Trigger payload.
:type payload: ``dict``
:param trace_tag: Tracer to track the triggerinstance.
:type trace_tags: ``str``
"""
# empty strings
trace_context = TraceContext(trace_tag=trace_tag) if trace_tag else None
self._logger.debug('Added trace_context %s to trigger %s.', trace_context, trigger)
self.dispatch_with_context(trigger, payload=payload, trace_context=trace_context)
def dispatch_with_context(self, trigger, payload=None, trace_context=None):
"""
Method which dispatches the trigger.
:param trigger: Full name / reference of the trigger.
:type trigger: ``str``
:param payload: Trigger payload.
:type payload: ``dict``
:param trace_context: Trace context to associate with Trigger.
:type trace_context: ``st2common.api.models.api.trace.TraceContext``
"""
# This means specified payload is complied with trigger_type schema, or not.
is_valid = True
try:
validate_trigger_payload(trigger_type_ref=trigger, payload=payload)
except (ValidationError, Exception) as e:
is_valid = False
self._logger.warn('Failed to validate payload (%s) for trigger "%s": %s' %
(str(payload), trigger, str(e)))
# If validation is disabled, still dispatch a trigger even if it failed validation
# This condition prevents unexpected restriction.
if not is_valid and cfg.CONF.system.validate_trigger_payload:
self._logger.warn('Trigger payload validation failed and validation is enabled, not '
'dispatching a trigger "%s" (%s)' % (trigger, str(payload)))
return None
self._logger.debug('Dispatching trigger %s with payload %s.', trigger, payload)
self._dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
##################################
# Methods for datastore management
##################################
def list_values(self, local=True, prefix=None):
return self.datastore_service.list_values(local=local, prefix=prefix)
#.........这里部分代码省略.........
示例9: SensorService
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class SensorService(object):
"""
Instance of this class is passed to the sensor instance and exposes "public"
methods which can be called by the sensor.
"""
DATASTORE_NAME_SEPARATOR = ':'
def __init__(self, sensor_wrapper):
self._sensor_wrapper = sensor_wrapper
self._logger = self._sensor_wrapper._logger
self._dispatcher = TriggerDispatcher(self._logger)
self._client = None
def get_logger(self, name):
"""
Retrieve an instance of a logger to be used by the sensor class.
"""
logger_name = '%s.%s' % (self._sensor_wrapper._logger.name, name)
logger = logging.getLogger(logger_name)
logger.propagate = True
return logger
def dispatch(self, trigger, payload=None, trace_tag=None):
"""
Method which dispatches the trigger.
:param trigger: Full name / reference of the trigger.
:type trigger: ``str``
:param payload: Trigger payload.
:type payload: ``dict``
:param trace_tag: Tracer to track the triggerinstance.
:type trace_tags: ``str``
"""
# empty strings
trace_context = TraceContext(trace_tag=trace_tag) if trace_tag else None
self.dispatch_with_context(trigger, payload=payload, trace_context=trace_context)
def dispatch_with_context(self, trigger, payload=None, trace_context=None):
"""
Method which dispatches the trigger.
:param trigger: Full name / reference of the trigger.
:type trigger: ``str``
:param payload: Trigger payload.
:type payload: ``dict``
:param trace_context: Trace context to associate with Trigger.
:type trace_context: ``st2common.api.models.api.trace.TraceContext``
"""
self._dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
##################################
# Methods for datastore management
##################################
def list_values(self, local=True, prefix=None):
"""
Retrieve all the datastores items.
:param local: List values from a namespace local to this sensor. Defaults to True.
:type: local: ``bool``
:param prefix: Optional key name prefix / startswith filter.
:type prefix: ``str``
:rtype: ``list`` of :class:`KeyValuePair`
"""
client = self._get_api_client()
self._logger.audit('Retrieving all the value from the datastore')
if local:
key_prefix = self._get_datastore_key_prefix() + self.DATASTORE_NAME_SEPARATOR
if prefix:
key_prefix += prefix
else:
key_prefix = prefix
kvps = client.keys.get_all(prefix=key_prefix)
return kvps
def get_value(self, name, local=True):
"""
Retrieve a value from the datastore for the provided key.
By default, value is retrieved from the namespace local to the sensor. If you want to
retrieve a global value from a datastore, pass local=False to this method.
:param name: Key name.
:type name: ``str``
:param local: Retrieve value from a namespace local to the sensor. Defaults to True.
:type: local: ``bool``
#.........这里部分代码省略.........
示例10: WebhooksController
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class WebhooksController(pecan.rest.RestController):
def __init__(self, *args, **kwargs):
super(WebhooksController, self).__init__(*args, **kwargs)
self._hooks = {}
self._base_url = '/webhooks/'
self._trigger_types = [GENERIC_WEBHOOK_TRIGGER_REF]
self._trigger_dispatcher = TriggerDispatcher(LOG)
self._trigger_watcher = TriggerWatcher(create_handler=self._handle_create_trigger,
update_handler=self._handle_update_trigger,
delete_handler=self._handle_delete_trigger,
trigger_types=self._trigger_types)
self._trigger_watcher.start()
@jsexpose(str, status_code=http_client.ACCEPTED)
def post(self, *args, **kwargs):
hook = '/'.join(args) # TODO: There must be a better way to do this.
LOG.info('POST /webhooks/ with hook=%s', hook)
if not self._is_valid_hook(hook):
msg = 'Webhook %s not registered with st2' % hook
return pecan.abort(http_client.NOT_FOUND, msg)
body = pecan.request.body
try:
body = json.loads(body)
except ValueError:
msg = 'Invalid JSON body: %s' % (body)
return pecan.abort(http_client.BAD_REQUEST, msg)
trigger = self._get_trigger_for_hook(hook)
payload = {}
payload['headers'] = self._get_headers_as_dict(pecan.request.headers)
payload['body'] = body
self._trigger_dispatcher.dispatch(trigger, payload=payload)
return body
def _is_valid_hook(self, hook):
# TODO: Validate hook payload with payload_schema.
return hook in self._hooks
def _get_trigger_for_hook(self, hook):
return self._hooks[hook]
def add_trigger(self, trigger):
url = trigger['parameters']['url']
LOG.info('Listening to endpoint: %s', urljoin(self._base_url, url))
self._hooks[url] = trigger
def update_trigger(self, trigger):
pass
def remove_trigger(self, trigger):
url = trigger['parameters']['url']
if url in self._hooks:
LOG.info('Stop listening to endpoint: %s', urljoin(self._base_url, url))
del self._hooks[url]
def _get_headers_as_dict(self, headers):
headers_dict = {}
for key, value in headers.items():
headers_dict[key] = value
return headers_dict
##############################################
# Event handler methods for the trigger events
##############################################
def _handle_create_trigger(self, trigger):
LOG.debug('Calling "add_trigger" method (trigger.type=%s)' % (trigger.type))
trigger = self._sanitize_trigger(trigger=trigger)
self.add_trigger(trigger=trigger)
def _handle_update_trigger(self, trigger):
LOG.debug('Calling "update_trigger" method (trigger.type=%s)' % (trigger.type))
trigger = self._sanitize_trigger(trigger=trigger)
self.update_trigger(trigger=trigger)
def _handle_delete_trigger(self, trigger):
LOG.debug('Calling "remove_trigger" method (trigger.type=%s)' % (trigger.type))
trigger = self._sanitize_trigger(trigger=trigger)
self.remove_trigger(trigger=trigger)
def _sanitize_trigger(self, trigger):
sanitized = trigger._data
if 'id' in sanitized:
# Friendly objectid rather than the MongoEngine representation.
sanitized['id'] = str(sanitized['id'])
return sanitized
示例11: St2Timer
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class St2Timer(object):
"""
A timer interface that uses APScheduler 3.0.
"""
def __init__(self, local_timezone=None):
self._timezone = local_timezone
self._scheduler = BlockingScheduler(timezone=self._timezone)
self._jobs = {}
self._trigger_types = TIMER_TRIGGER_TYPES.keys()
self._trigger_watcher = TriggerWatcher(create_handler=self._handle_create_trigger,
update_handler=self._handle_update_trigger,
delete_handler=self._handle_delete_trigger,
trigger_types=self._trigger_types,
queue_suffix=self.__class__.__name__,
exclusive=True)
self._trigger_dispatcher = TriggerDispatcher(LOG)
def start(self):
self._register_timer_trigger_types()
self._trigger_watcher.start()
self._scheduler.start()
def cleanup(self):
self._scheduler.shutdown(wait=True)
def add_trigger(self, trigger):
self._add_job_to_scheduler(trigger)
def update_trigger(self, trigger):
self.remove_trigger(trigger)
self.add_trigger(trigger)
def remove_trigger(self, trigger):
trigger_id = trigger['id']
try:
job_id = self._jobs[trigger_id]
except KeyError:
LOG.info('Job not found: %s', trigger_id)
return
self._scheduler.remove_job(job_id)
del self._jobs[trigger_id]
def _add_job_to_scheduler(self, trigger):
trigger_type_ref = trigger['type']
trigger_type = TIMER_TRIGGER_TYPES[trigger_type_ref]
try:
jsonschema.validate(trigger['parameters'],
trigger_type['parameters_schema'])
except jsonschema.ValidationError as e:
LOG.error('Exception scheduling timer: %s, %s',
trigger['parameters'], e, exc_info=True)
raise # Or should we just return?
time_spec = trigger['parameters']
time_zone = aps_utils.astimezone(trigger['parameters'].get('timezone'))
time_type = None
if trigger_type['name'] == 'st2.IntervalTimer':
unit = time_spec.get('unit', None)
value = time_spec.get('delta', None)
time_type = IntervalTrigger(**{unit: value, 'timezone': time_zone})
elif trigger_type['name'] == 'st2.DateTimer':
# Raises an exception if date string isn't a valid one.
dat = date_parser.parse(time_spec.get('date', None))
time_type = DateTrigger(dat, timezone=time_zone)
elif trigger_type['name'] == 'st2.CronTimer':
cron = time_spec.copy()
cron['timezone'] = time_zone
time_type = CronTrigger(**cron)
utc_now = date_utils.get_datetime_utc_now()
if hasattr(time_type, 'run_date') and utc_now > time_type.run_date:
LOG.warning('Not scheduling expired timer: %s : %s',
trigger['parameters'], time_type.run_date)
else:
self._add_job(trigger, time_type)
return time_type
def _add_job(self, trigger, time_type, replace=True):
try:
job = self._scheduler.add_job(self._emit_trigger_instance,
trigger=time_type,
args=[trigger],
replace_existing=replace)
LOG.info('Job %s scheduled.', job.id)
self._jobs[trigger['id']] = job.id
except Exception as e:
LOG.error('Exception scheduling timer: %s, %s',
trigger['parameters'], e, exc_info=True)
def _emit_trigger_instance(self, trigger):
utc_now = date_utils.get_datetime_utc_now()
# debug logging is reasonable for this one. A high resolution timer will end up
# trashing standard logs.
LOG.debug('Timer fired at: %s. Trigger: %s', str(utc_now), trigger)
#.........这里部分代码省略.........
示例12: WebhooksController
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class WebhooksController(object):
def __init__(self, *args, **kwargs):
self._hooks = HooksHolder()
self._base_url = '/webhooks/'
self._trigger_types = list(WEBHOOK_TRIGGER_TYPES.keys())
self._trigger_dispatcher = TriggerDispatcher(LOG)
queue_suffix = self.__class__.__name__
self._trigger_watcher = TriggerWatcher(create_handler=self._handle_create_trigger,
update_handler=self._handle_update_trigger,
delete_handler=self._handle_delete_trigger,
trigger_types=self._trigger_types,
queue_suffix=queue_suffix,
exclusive=True)
self._trigger_watcher.start()
self._register_webhook_trigger_types()
def get_all(self):
# Return only the hooks known by this controller.
return self._hooks.get_all()
def get_one(self, url, requester_user):
triggers = self._hooks.get_triggers_for_hook(url)
if not triggers:
abort(http_client.NOT_FOUND)
return
permission_type = PermissionType.WEBHOOK_VIEW
rbac_utils.assert_user_has_resource_db_permission(user_db=requester_user,
resource_db=WebhookDB(name=url),
permission_type=permission_type)
# For demonstration purpose return 1st
return triggers[0]
def post(self, hook, webhook_body_api, headers, requester_user):
body = webhook_body_api.data
permission_type = PermissionType.WEBHOOK_SEND
rbac_utils.assert_user_has_resource_db_permission(user_db=requester_user,
resource_db=WebhookDB(name=hook),
permission_type=permission_type)
headers = self._get_headers_as_dict(headers)
# If webhook contains a trace-tag use that else create create a unique trace-tag.
trace_context = self._create_trace_context(trace_tag=headers.pop(TRACE_TAG_HEADER, None),
hook=hook)
if hook == 'st2' or hook == 'st2/':
# When using st2 or system webhook, body needs to always be a dict
if not isinstance(body, dict):
type_string = get_json_type_for_python_value(body)
msg = ('Webhook body needs to be an object, got: %s' % (type_string))
raise ValueError(msg)
trigger = body.get('trigger', None)
payload = body.get('payload', None)
if not trigger:
msg = 'Trigger not specified.'
return abort(http_client.BAD_REQUEST, msg)
self._trigger_dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
else:
if not self._is_valid_hook(hook):
self._log_request('Invalid hook.', headers, body)
msg = 'Webhook %s not registered with st2' % hook
return abort(http_client.NOT_FOUND, msg)
triggers = self._hooks.get_triggers_for_hook(hook)
payload = {}
payload['headers'] = headers
payload['body'] = body
# Dispatch trigger instance for each of the trigger found
for trigger in triggers:
self._trigger_dispatcher.dispatch(trigger, payload=payload,
trace_context=trace_context)
return Response(json=body, status=http_client.ACCEPTED)
def _is_valid_hook(self, hook):
# TODO: Validate hook payload with payload_schema.
return hook in self._hooks
def _register_webhook_trigger_types(self):
for trigger_type in WEBHOOK_TRIGGER_TYPES.values():
trigger_service.create_trigger_type_db(trigger_type)
def _create_trace_context(self, trace_tag, hook):
# if no trace_tag then create a unique one
if not trace_tag:
trace_tag = 'webhook-%s-%s' % (hook, uuid.uuid4().hex)
return TraceContext(trace_tag=trace_tag)
def add_trigger(self, trigger):
# Note: Permission checking for creating and deleting a webhook is done during rule
# creation
url = self._get_normalized_url(trigger)
#.........这里部分代码省略.........
示例13: ProcessSensorContainer
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class ProcessSensorContainer(object):
"""
Sensor container which runs sensors in a separate process.
"""
def __init__(self, sensors, poll_interval=5):
"""
:param sensors: A list of sensor dicts.
:type sensors: ``list`` of ``dict``
"""
self._sensors = {} # maps sensor_id -> sensor object
self._processes = {} # maps sensor_id -> sensor process
self._dispatcher = TriggerDispatcher(LOG)
self.poll_interval = poll_interval
self.stopped = False
sensors = sensors or []
for sensor_obj in sensors:
sensor_id = self._get_sensor_id(sensor=sensor_obj)
self._sensors[sensor_id] = sensor_obj
def run(self):
self._run_all_sensors()
try:
while not self.stopped:
# Poll for all running processes
sensor_ids = self._sensors.keys()
if len(sensor_ids) >= 1:
self._poll_sensors_for_results(sensor_ids)
eventlet.sleep(self.poll_interval)
except greenlet.GreenletExit:
# This exception is thrown when sensor container manager
# kills the thread which runs process container. Not sure
# if this is the best thing to do.
self.stopped = True
return SUCCESS_EXIT_CODE
except:
LOG.exception('Container failed to run sensors.')
self.stopped = True
return FAILURE_EXIT_CODE
self.stopped = True
LOG.error('Process container quit. It shouldn\'t.')
def _poll_sensors_for_results(self, sensor_ids):
for sensor_id in sensor_ids:
process = self._processes[sensor_id]
status = process.poll()
if status is not None:
# Dead process detected
LOG.info('Process for sensor %s has exited with code %s',
self._sensors[sensor_id]['ref'], status)
sensor = self._sensors[sensor_id]
self._dispatch_trigger_for_sensor_exit(sensor=sensor,
exit_code=status)
self._delete_sensors(sensor_id)
def running(self):
return len(self._processes)
def shutdown(self):
LOG.info('Container shutting down. Invoking cleanup on sensors.')
self.stopped = True
sensor_ids = self._sensors.keys()
for sensor_id in sensor_ids:
self._stop_sensor_process(sensor_id=sensor_id)
LOG.info('All sensors are shut down.')
self._sensors = {}
self._processes = {}
def add_sensor(self, sensor):
"""
Add a new sensor to the container.
:type sensor: ``dict``
"""
sensor_id = self._get_sensor_id(sensor=sensor)
if sensor_id in self._sensors:
LOG.warning('Sensor %s already exists and running.', sensor_id)
return False
self._spawn_sensor_process(sensor=sensor)
LOG.debug('Sensor %s started.', sensor_id)
self._sensors[sensor_id] = sensor
return True
def remove_sensor(self, sensor):
"""
Remove an existing sensor from the container.
:type sensor: ``dict``
#.........这里部分代码省略.........
示例14: _refire_trigger_instance
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
def _refire_trigger_instance(trigger_instance_id, log_):
trigger_instance = TriggerInstance.get_by_id(trigger_instance_id)
trigger_dispatcher = TriggerDispatcher(log_)
trigger_dispatcher.dispatch(trigger=trigger_instance.trigger,
payload=trigger_instance.payload)
示例15: WebhooksController
# 需要导入模块: from st2common.transport.reactor import TriggerDispatcher [as 别名]
# 或者: from st2common.transport.reactor.TriggerDispatcher import dispatch [as 别名]
class WebhooksController(RestController):
def __init__(self, *args, **kwargs):
super(WebhooksController, self).__init__(*args, **kwargs)
self._hooks = HooksHolder()
self._base_url = "/webhooks/"
self._trigger_types = WEBHOOK_TRIGGER_TYPES.keys()
self._trigger_dispatcher = TriggerDispatcher(LOG)
queue_suffix = self.__class__.__name__
self._trigger_watcher = TriggerWatcher(
create_handler=self._handle_create_trigger,
update_handler=self._handle_update_trigger,
delete_handler=self._handle_delete_trigger,
trigger_types=self._trigger_types,
queue_suffix=queue_suffix,
exclusive=True,
)
self._trigger_watcher.start()
self._register_webhook_trigger_types()
@jsexpose()
def get_all(self):
# Return only the hooks known by this controller.
return self._hooks.get_all()
@jsexpose()
def get_one(self, name):
triggers = self._hooks.get_triggers_for_hook(name)
if not triggers:
abort(http_client.NOT_FOUND)
return
# For demonstration purpose return 1st
return triggers[0]
@request_user_has_webhook_permission(permission_type=PermissionType.WEBHOOK_SEND)
@jsexpose(arg_types=[str], status_code=http_client.ACCEPTED)
def post(self, *args, **kwargs):
hook = "/".join(args) # TODO: There must be a better way to do this.
# Note: For backward compatibility reasons we default to application/json if content
# type is not explicitly provided
content_type = pecan.request.headers.get("Content-Type", "application/json")
content_type = parse_content_type_header(content_type=content_type)[0]
body = pecan.request.body
try:
body = self._parse_request_body(content_type=content_type, body=body)
except Exception as e:
self._log_request("Failed to parse request body: %s." % (str(e)), pecan.request)
msg = 'Failed to parse request body "%s": %s' % (body, str(e))
return pecan.abort(http_client.BAD_REQUEST, msg)
headers = self._get_headers_as_dict(pecan.request.headers)
# If webhook contains a trace-tag use that else create create a unique trace-tag.
trace_context = self._create_trace_context(trace_tag=headers.pop(TRACE_TAG_HEADER, None), hook=hook)
if hook == "st2" or hook == "st2/":
return self._handle_st2_webhook(body, trace_context=trace_context)
if not self._is_valid_hook(hook):
self._log_request("Invalid hook.", pecan.request)
msg = "Webhook %s not registered with st2" % hook
return pecan.abort(http_client.NOT_FOUND, msg)
triggers = self._hooks.get_triggers_for_hook(hook)
payload = {}
payload["headers"] = headers
payload["body"] = body
# Dispatch trigger instance for each of the trigger found
for trigger in triggers:
self._trigger_dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
return body
def _parse_request_body(self, content_type, body):
if content_type == "application/json":
self._log_request("Parsing request body as JSON", request=pecan.request)
body = json.loads(body)
elif content_type in ["application/x-www-form-urlencoded", "multipart/form-data"]:
self._log_request("Parsing request body as form encoded data", request=pecan.request)
body = urlparse.parse_qs(body)
else:
raise ValueError('Unsupported Content-Type: "%s"' % (content_type))
return body
def _handle_st2_webhook(self, body, trace_context):
trigger = body.get("trigger", None)
payload = body.get("payload", None)
if not trigger:
msg = "Trigger not specified."
return pecan.abort(http_client.BAD_REQUEST, msg)
self._trigger_dispatcher.dispatch(trigger, payload=payload, trace_context=trace_context)
return body
def _is_valid_hook(self, hook):
#.........这里部分代码省略.........