Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions st2common/st2common/services/triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def create_trigger_db(trigger_api):
return trigger_db


def create_or_update_trigger_db(trigger):
def create_or_update_trigger_db(trigger, log_not_unique_error_as_debug=False):
"""
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: We want to default this to False everywhere because in other context, this error would indeed be fatal.

Create a new TriggerDB model if one doesn't exist yet or update existing
one.
Expand All @@ -269,7 +269,8 @@ def create_or_update_trigger_db(trigger):
if is_update:
trigger_db.id = existing_trigger_db.id

trigger_db = Trigger.add_or_update(trigger_db)
trigger_db = Trigger.add_or_update(trigger_db,
log_not_unique_error_as_debug=log_not_unique_error_as_debug)

extra = {'trigger_db': trigger_db}

Expand Down Expand Up @@ -331,13 +332,20 @@ def cleanup_trigger_db_for_rule(rule_db):
Trigger.delete_if_unreferenced(existing_trigger_db)


def create_trigger_type_db(trigger_type):
def create_trigger_type_db(trigger_type, log_not_unique_error_as_debug=False):
"""
Creates a trigger type db object in the db given trigger_type definition as dict.

:param trigger_type: Trigger type model.
:type trigger_type: ``dict``

:param log_not_unique_error_as_debug: True to lot NotUnique errors under debug instead of
error log level. This is to be used in scenarios where
failure is non-fatal (e.g. when services register
internal trigger types which is an idempotent
operation).
:type log_not_unique_error_as_debug: ``bool``

:rtype: ``object``
"""
trigger_type_api = TriggerTypeAPI(**trigger_type)
Expand All @@ -349,13 +357,23 @@ def create_trigger_type_db(trigger_type):
if not trigger_type_db:
trigger_type_db = TriggerTypeAPI.to_model(trigger_type_api)
LOG.debug('verified trigger and formulated TriggerDB=%s', trigger_type_db)
trigger_type_db = TriggerType.add_or_update(trigger_type_db)
trigger_type_db = TriggerType.add_or_update(trigger_type_db,
log_not_unique_error_as_debug=log_not_unique_error_as_debug)

return trigger_type_db


def create_shadow_trigger(trigger_type_db):
def create_shadow_trigger(trigger_type_db, log_not_unique_error_as_debug=False):
"""
Create a shadow trigger for TriggerType with no parameters.

:param log_not_unique_error_as_debug: True to lot NotUnique errors under debug instead of
error log level. This is to be used in scenarios where
failure is non-fatal (e.g. when services register
internal trigger types which is an idempotent
operation).
:type log_not_unique_error_as_debug: ``bool``

"""
trigger_type_ref = trigger_type_db.get_reference().ref

Expand All @@ -368,16 +386,24 @@ def create_shadow_trigger(trigger_type_db):
'type': trigger_type_ref,
'parameters': {}}

return create_or_update_trigger_db(trigger)
return create_or_update_trigger_db(trigger,
log_not_unique_error_as_debug=log_not_unique_error_as_debug)


def create_or_update_trigger_type_db(trigger_type):
def create_or_update_trigger_type_db(trigger_type, log_not_unique_error_as_debug=False):
"""
Create or update a trigger type db object in the db given trigger_type definition as dict.

:param trigger_type: Trigger type model.
:type trigger_type: ``dict``

:param log_not_unique_error_as_debug: True to lot NotUnique errors under debug instead of
error log level. This is to be used in scenarios where
failure is non-fatal (e.g. when services register
internal trigger types which is an idempotent
operation).
:type log_not_unique_error_as_debug: ``bool``

:rtype: ``object``
"""
assert isinstance(trigger_type, dict)
Expand All @@ -399,7 +425,8 @@ def create_or_update_trigger_type_db(trigger_type):
trigger_type_api.id = existing_trigger_type_db.id

try:
trigger_type_db = TriggerType.add_or_update(trigger_type_api)
trigger_type_db = TriggerType.add_or_update(trigger_type_api,
log_not_unique_error_as_debug=log_not_unique_error_as_debug)
except StackStormDBObjectConflictError:
# Operation is idempotent and trigger could have already been created by
# another process. Ignore object already exists because it simply means
Expand Down
18 changes: 13 additions & 5 deletions st2common/st2common/triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# limitations under the License.

from __future__ import absolute_import

import six

from mongoengine import ValidationError
Expand All @@ -23,7 +24,8 @@
from st2common import log as logging
from st2common.constants.triggers import (INTERNAL_TRIGGER_TYPES, ACTION_SENSOR_TRIGGER)
from st2common.exceptions.db import StackStormDBObjectConflictError
from st2common.services.triggers import create_trigger_type_db, create_shadow_trigger
from st2common.services.triggers import create_trigger_type_db
from st2common.services.triggers import create_shadow_trigger
from st2common.services.triggers import get_trigger_type_db
from st2common.models.system.common import ResourceReference

Expand All @@ -36,7 +38,8 @@

def _register_internal_trigger_type(trigger_definition):
try:
trigger_type_db = create_trigger_type_db(trigger_type=trigger_definition)
trigger_type_db = create_trigger_type_db(trigger_type=trigger_definition,
log_not_unique_error_as_debug=True)
except (NotUniqueError, StackStormDBObjectConflictError):
# We ignore conflict error since this operation is idempotent and race is not an issue
LOG.debug('Internal trigger type "%s" already exists, ignoring...' %
Expand All @@ -52,12 +55,13 @@ def _register_internal_trigger_type(trigger_definition):
# trigger types with parameters do no require a shadow trigger.
if trigger_type_db and not trigger_type_db.parameters_schema:
try:
trigger_db = create_shadow_trigger(trigger_type_db)
trigger_db = create_shadow_trigger(trigger_type_db,
log_not_unique_error_as_debug=True)

extra = {'trigger_db': trigger_db}
LOG.audit('Trigger created for parameter-less internal TriggerType. Trigger.id=%s' %
(trigger_db.id), extra=extra)
except StackStormDBObjectConflictError:
except (NotUniqueError, StackStormDBObjectConflictError):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

LOG.debug('Shadow trigger "%s" already exists. Ignoring.',
trigger_type_db.get_reference().ref, exc_info=True)

Expand All @@ -73,7 +77,11 @@ def register_internal_trigger_types():
"""
Register internal trigger types.

Note: This method blocks until all the trigger types have been registered.
NOTE 1: This method blocks until all the trigger types have been registered.

NOTE 2: We log "NotUniqueError" errors under debug and not error. Those errors are not fatal
because this operation is idempotent and NotUniqueError simply means internal trigger type
has already been registered by some other service.
"""
action_sensor_enabled = cfg.CONF.action_sensor.enable

Expand Down