Skip to content

Commit

Permalink
Merge pull request #4151 from StackStorm/trigger_instance_filter_trig…
Browse files Browse the repository at this point in the history
…ger_type

Add trigger type reference based filtering to the /v1/triggerinstances API endpoint
  • Loading branch information
Kami authored May 29, 2018
2 parents 39b93d3 + 2bca04b commit 23e2d2f
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Added
values - ``succeeded`` (trigger instance matched a rule and action execution was triggered
successfully), ``failed`` (trigger instance matched a rule, but it didn't result in an action
execution due to Jinja rendering failure or other exception). (improvement) #4134
* Add trigger type reference based filtering to the ``/v1/triggerinstances`` API endpoint - e.g.
``/v1/triggerinstances?trigger_type=core.st2.webhook``. (new feature) #4151

Changed
~~~~~~~
Expand Down
8 changes: 7 additions & 1 deletion st2api/st2api/controllers/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,13 @@ def _get_all(self, exclude_fields=None, include_fields=None, advanced_filters=No
if k in ['id', 'name'] and isinstance(filter_value, list):
filters[k + '__in'] = filter_value
else:
filters['__'.join(v.split('.'))] = filter_value
field_name_split = v.split('.')

# Make sure filter value is a list when using "in" filter
if field_name_split[-1] == 'in' and not isinstance(filter_value, (list, tuple)):
filter_value = [filter_value]

filters['__'.join(field_name_split)] = filter_value

if advanced_filters:
for token in advanced_filters.split(' '):
Expand Down
19 changes: 17 additions & 2 deletions st2api/st2api/controllers/v1/triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,10 @@ class TriggerInstanceController(TriggerInstanceControllerMixin, resource.Resourc
the lifecycle of TriggerInstances in the system.
"""
supported_filters = {
'trigger': 'trigger',
'timestamp_gt': 'occurrence_time.gt',
'timestamp_lt': 'occurrence_time.lt',
'status': 'status'
'status': 'status',
'trigger': 'trigger.in'
}

filter_transform_functions = {
Expand Down Expand Up @@ -393,6 +393,21 @@ def get_all(self, sort=None, offset=0, limit=None, requester_user=None, **raw_fi
Handles requests:
GET /triggerinstances/
"""
# If trigger_type filter is provided, filter based on the TriggerType via Trigger object
trigger_type_ref = raw_filters.get('trigger_type', None)

if trigger_type_ref:
# 1. Retrieve TriggerType object id which match this trigger_type ref
trigger_dbs = Trigger.query(type=trigger_type_ref,
only_fields=['ref', 'name', 'pack', 'type'])
trigger_refs = [trigger_db.ref for trigger_db in trigger_dbs]
raw_filters['trigger'] = trigger_refs

if trigger_type_ref and len(raw_filters.get('trigger', [])) == 0:
# Empty list means trigger_type_ref filter was provided, but we matched no Triggers so
# we should return back empty result
return []

trigger_instances = self._get_trigger_instances(sort=sort,
offset=offset,
limit=limit,
Expand Down
24 changes: 24 additions & 0 deletions st2api/tests/unit/controllers/v1/test_triggerinstances.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ def test_get_all_filter_by_timestamp(self):
resp = self.app.get('/v1/triggerinstances?timestamp_lt=%s' % (timestamp_middle))
self.assertEqual(len(resp.json), 1)

def test_get_all_trigger_type_ref_filtering(self):
# 1. Invalid / inexistent trigger type ref
resp = self.app.get('/v1/triggerinstances?trigger_type=foo.bar.invalid')
self.assertEqual(resp.status_int, http_client.OK)
self.assertEqual(len(resp.json), 0)

# 2. Valid trigger type ref with corresponding trigger instances
resp = self.app.get('/v1/triggerinstances?trigger_type=dummy_pack_1.st2.test.triggertype0')
self.assertEqual(resp.status_int, http_client.OK)
self.assertEqual(len(resp.json), 1)

# 3. Valid trigger type ref with no corresponding trigger instances
resp = self.app.get('/v1/triggerinstances?trigger_type=dummy_pack_1.st2.test.triggertype3')
self.assertEqual(resp.status_int, http_client.OK)
self.assertEqual(len(resp.json), 0)

def test_reemit_trigger_instance(self):
resp = self.app.get('/v1/triggerinstances')
self.assertEqual(resp.status_int, http_client.OK)
Expand Down Expand Up @@ -127,9 +143,17 @@ def _setupTriggerTypes(cls):
'payload_schema': {'tp1': None, 'tp2': None, 'tp3': None},
'parameters_schema': {'param1': {'type': 'object'}}
}
TRIGGERTYPE_3 = {
'name': 'st2.test.triggertype3',
'pack': 'dummy_pack_1',
'description': 'test trigger',
'payload_schema': {'tp1': None, 'tp2': None, 'tp3': None},
'parameters_schema': {'param1': {'type': 'object'}}
}
cls.app.post_json('/v1/triggertypes', TRIGGERTYPE_0, expect_errors=False)
cls.app.post_json('/v1/triggertypes', TRIGGERTYPE_1, expect_errors=False)
cls.app.post_json('/v1/triggertypes', TRIGGERTYPE_2, expect_errors=False)
cls.app.post_json('/v1/triggertypes', TRIGGERTYPE_3, expect_errors=False)

@classmethod
def _setupTriggers(cls):
Expand Down
4 changes: 4 additions & 0 deletions st2common/st2common/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3918,6 +3918,10 @@ paths:
description: Start timestamp greater than filter
type: string
pattern: ^\d{4}\-\d{2}\-\d{2}(\s|T)\d{2}:\d{2}:\d{2}(\.\d{3,6})?(Z|\+00|\+0000|\+00:00)$
- name: trigger_type
in: query
description: Trigger type filter
type: string
x-parameters:
- name: user
in: context
Expand Down
4 changes: 4 additions & 0 deletions st2common/st2common/openapi.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -3914,6 +3914,10 @@ paths:
description: Start timestamp greater than filter
type: string
pattern: {{ ISO8601_UTC_REGEX }}
- name: trigger_type
in: query
description: Trigger type filter
type: string
x-parameters:
- name: user
in: context
Expand Down

0 comments on commit 23e2d2f

Please sign in to comment.