本文整理汇总了Python中st2common.services.triggerwatcher.TriggerWatcher类的典型用法代码示例。如果您正苦于以下问题:Python TriggerWatcher类的具体用法?Python TriggerWatcher怎么用?Python TriggerWatcher使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了TriggerWatcher类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: __init__
def __init__(self, pack, file_path, class_name, trigger_types,
poll_interval=None, parent_args=None):
"""
:param pack: Name of the pack this sensor belongs to.
:type pack: ``str``
:param file_path: Path to the sensor module file.
:type file_path: ``str``
:param class_name: Sensor class name.
:type class_name: ``str``
:param trigger_types: A list of references to trigger types which
belong to this sensor.
:type trigger_types: ``list`` of ``str``
:param poll_interval: Sensor poll interval (in seconds).
:type poll_interval: ``int`` or ``None``
:param parent_args: Command line arguments passed to the parent process.
:type parse_args: ``list``
"""
self._pack = pack
self._file_path = file_path
self._class_name = class_name
self._trigger_types = trigger_types or []
self._poll_interval = poll_interval
self._parent_args = parent_args or []
self._trigger_names = {}
# 1. Parse the config with inherited parent args
try:
config.parse_args(args=self._parent_args)
except Exception:
pass
# 2. Establish DB connection
username = cfg.CONF.database.username if hasattr(cfg.CONF.database, 'username') else None
password = cfg.CONF.database.password if hasattr(cfg.CONF.database, 'password') else None
db_setup_with_retry(cfg.CONF.database.db_name, cfg.CONF.database.host,
cfg.CONF.database.port, username=username, password=password)
# 3. Instantiate the watcher
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='sensorwrapper_%s_%s' %
(self._pack, self._class_name),
exclusive=True)
# 4. Set up logging
self._logger = logging.getLogger('SensorWrapper.%s.%s' %
(self._pack, self._class_name))
logging.setup(cfg.CONF.sensorcontainer.logging)
if '--debug' in parent_args:
set_log_level_for_all_loggers()
self._sensor_instance = self._get_sensor_instance()
示例2: __init__
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='timers')
self._trigger_dispatcher = TriggerDispatcher(LOG)
示例3: __init__
def __init__(self, local_timezone=None):
self._timezone = local_timezone
self._scheduler = BlockingScheduler(timezone=self._timezone)
self._jobs = {}
self._trigger_types = list(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)
示例4: __init__
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()
示例5: __init__
def __init__(self):
self._timers = TimersHolder()
self._trigger_types = TIMER_TRIGGER_TYPES.keys()
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_timer_trigger_types()
self._allowed_timer_types = TIMER_TRIGGER_TYPES.keys()
示例6: __init__
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)
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='webhooks')
self._trigger_watcher.start()
self._register_webhook_trigger_types()
示例7: __init__
def __init__(self, *args, **kwargs):
self._hooks = HooksHolder()
self._base_url = '/webhooks/'
self._trigger_types = list(WEBHOOK_TRIGGER_TYPES.keys())
self._trigger_dispatcher_service = TriggerDispatcherService(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()
示例8: __init__
def __init__(self, pack, file_path, class_name, trigger_types,
poll_interval=None, parent_args=None):
"""
:param pack: Name of the pack this sensor belongs to.
:type pack: ``str``
:param file_path: Path to the sensor module file.
:type file_path: ``str``
:param class_name: Sensor class name.
:type class_name: ``str``
:param trigger_types: A list of references to trigger types which
belong to this sensor.
:type trigger_types: ``list`` of ``str``
:param poll_interval: Sensor poll interval (in seconds).
:type poll_interval: ``int`` or ``None``
:param parent_args: Command line arguments passed to the parent process.
:type parse_args: ``list``
"""
self._pack = pack
self._file_path = file_path
self._class_name = class_name
self._trigger_types = trigger_types or []
self._poll_interval = poll_interval
self._parent_args = parent_args or []
self._trigger_names = {}
# 1. Parse the config with inherited parent args
try:
config.parse_args(args=self._parent_args)
except Exception:
pass
# 2. Instantiate the watcher
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)
# 3. Set up logging
self._logger = logging.getLogger('SensorWrapper.%s' %
(self._class_name))
logging.setup(cfg.CONF.sensorcontainer.logging)
self._sensor_instance = self._get_sensor_instance()
示例9: __init__
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()
示例10: SensorWrapper
class SensorWrapper(object):
def __init__(self, pack, file_path, class_name, trigger_types,
poll_interval=None, parent_args=None):
"""
:param pack: Name of the pack this sensor belongs to.
:type pack: ``str``
:param file_path: Path to the sensor module file.
:type file_path: ``str``
:param class_name: Sensor class name.
:type class_name: ``str``
:param trigger_types: A list of references to trigger types which
belong to this sensor.
:type trigger_types: ``list`` of ``str``
:param poll_interval: Sensor poll interval (in seconds).
:type poll_interval: ``int`` or ``None``
:param parent_args: Command line arguments passed to the parent process.
:type parse_args: ``list``
"""
self._pack = pack
self._file_path = file_path
self._class_name = class_name
self._trigger_types = trigger_types or []
self._poll_interval = poll_interval
self._parent_args = parent_args or []
self._trigger_names = {}
# 1. Parse the config with inherited parent args
try:
config.parse_args(args=self._parent_args)
except Exception:
pass
# 2. Establish DB connection
username = cfg.CONF.database.username if hasattr(cfg.CONF.database, 'username') else None
password = cfg.CONF.database.password if hasattr(cfg.CONF.database, 'password') else None
db_setup_with_retry(cfg.CONF.database.db_name, cfg.CONF.database.host,
cfg.CONF.database.port, username=username, password=password,
ssl=cfg.CONF.database.ssl, ssl_keyfile=cfg.CONF.database.ssl_keyfile,
ssl_certfile=cfg.CONF.database.ssl_certfile,
ssl_cert_reqs=cfg.CONF.database.ssl_cert_reqs,
ssl_ca_certs=cfg.CONF.database.ssl_ca_certs,
ssl_match_hostname=cfg.CONF.database.ssl_match_hostname)
# 3. Instantiate the watcher
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='sensorwrapper_%s_%s' %
(self._pack, self._class_name),
exclusive=True)
# 4. Set up logging
self._logger = logging.getLogger('SensorWrapper.%s.%s' %
(self._pack, self._class_name))
logging.setup(cfg.CONF.sensorcontainer.logging)
if '--debug' in parent_args:
set_log_level_for_all_loggers()
self._sensor_instance = self._get_sensor_instance()
def run(self):
atexit.register(self.stop)
self._trigger_watcher.start()
self._logger.info('Watcher started')
self._logger.info('Running sensor initialization code')
self._sensor_instance.setup()
if self._poll_interval:
message = ('Running sensor in active mode (poll interval=%ss)' %
(self._poll_interval))
else:
message = 'Running sensor in passive mode'
self._logger.info(message)
try:
self._sensor_instance.run()
except Exception as e:
# Include traceback
msg = ('Sensor "%s" run method raised an exception: %s.' %
(self._class_name, str(e)))
self._logger.warn(msg, exc_info=True)
raise Exception(msg)
def stop(self):
# Stop watcher
self._logger.info('Stopping trigger watcher')
self._trigger_watcher.stop()
# Run sensor cleanup code
self._logger.info('Invoking cleanup on sensor')
#.........这里部分代码省略.........
示例11: St2Timer
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
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
示例13: WebhooksController
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_service = TriggerDispatcherService(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_service.dispatch_with_context(trigger=trigger,
payload=payload,
trace_context=trace_context,
throw_on_validation_error=True)
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_dict in triggers:
# TODO: Instead of dispatching the whole dict we should just
# dispatch TriggerDB.ref or similar
self._trigger_dispatcher_service.dispatch_with_context(trigger=trigger_dict,
payload=payload,
trace_context=trace_context,
throw_on_validation_error=True)
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):
#.........这里部分代码省略.........
示例14: WebhooksController
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)
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='webhooks')
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
@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.
body = pecan.request.body
try:
body = json.loads(body)
except ValueError:
self._log_request('Invalid JSON body.', pecan.request)
msg = 'Invalid JSON body: %s' % (body)
return pecan.abort(http_client.BAD_REQUEST, msg)
if hook == 'st2' or hook == 'st2/':
return self._handle_st2_webhook(body)
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'] = self._get_headers_as_dict(pecan.request.headers)
payload['body'] = body
self._trigger_dispatcher.dispatch(trigger, payload=payload)
return body
def _handle_st2_webhook(self, body):
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)
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 _register_webhook_trigger_types(self):
for trigger_type in WEBHOOK_TRIGGER_TYPES.values():
trigger_service.create_trigger_type_db(trigger_type)
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
#.........这里部分代码省略.........
示例15: WebhooksController
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):
#.........这里部分代码省略.........