160 lines
6.0 KiB
Python
160 lines
6.0 KiB
Python
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
import logging
|
|
|
|
from .notes import MAX_VERBOSITY
|
|
from .notes import MIN_VERBOSITY
|
|
from .notes import Query
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
# Constants and magic numbers for actions:
|
|
# [7:33] to slice a string like:
|
|
# action/12345678901234567890123456
|
|
# matching the patterns in this helper.
|
|
ACTION_KEY_PATTERN = "action/{}"
|
|
ACTION_LOOKUP_PATTERN = "action/"
|
|
ACTION_ID_START = 7
|
|
ACTION_ID_END = 33
|
|
|
|
|
|
class NotesHelper:
|
|
"""Notes Helper
|
|
|
|
Provides helper methods for the common use cases for notes
|
|
:param notes_manager: the NotesManager object to use
|
|
"""
|
|
def __init__(self, notes_manager):
|
|
self.nm = notes_manager
|
|
|
|
def _failsafe_make_note(self, assoc_id, subject, sub_type, note_val,
|
|
verbosity=None, link_url=None, is_auth_link=None):
|
|
"""LOG and continue on any note creation failure"""
|
|
try:
|
|
self.nm.create(
|
|
assoc_id=assoc_id,
|
|
subject=subject,
|
|
sub_type=sub_type,
|
|
note_val=note_val,
|
|
verbosity=verbosity,
|
|
link_url=link_url,
|
|
is_auth_link=is_auth_link,
|
|
)
|
|
except Exception as ex:
|
|
LOG.warn(
|
|
"Creating note for {} encountered a problem, exception info "
|
|
"follows, but processing is not halted for notes.",
|
|
assoc_id
|
|
)
|
|
LOG.exception(ex)
|
|
|
|
def _failsafe_get_notes(self, assoc_id_pattern, max_verbosity,
|
|
exact_match):
|
|
"""LOG and continue on any note retrieval failure"""
|
|
try:
|
|
q = Query(assoc_id_pattern, max_verbosity, exact_match)
|
|
return self.nm.retrieve(q)
|
|
except Exception as ex:
|
|
LOG.warn(
|
|
"Note retrieval for {} encountered a problem, exception "
|
|
"info follows, but processing is not halted for notes.",
|
|
assoc_id_pattern
|
|
)
|
|
LOG.exception(ex)
|
|
return []
|
|
|
|
def make_action_note(self, action_id, note_val, subject=None,
|
|
sub_type=None, verbosity=None, link_url=None,
|
|
is_auth_link=None):
|
|
"""Creates an action note using a convention for the note's assoc_id
|
|
|
|
:param action_id: the ULID id of an action
|
|
:param note_val: the text for the note
|
|
:param subject: optional subject for the note. Defaults to the
|
|
action_id
|
|
:param sub_type: optional subject type for the note, defaults to
|
|
"action metadata"
|
|
:param verbosity: optional verbosity for the note, defaults to 1,
|
|
i.e.: summary level
|
|
:param link_url: optional link URL if there's additional information
|
|
to retreive from another source.
|
|
:param is_auth_link: optional, defaults to False, indicating if there
|
|
is a need to send a Shipyard service account token with the
|
|
request to the optional URL
|
|
"""
|
|
assoc_id = ACTION_KEY_PATTERN.format(action_id)
|
|
if subject is None:
|
|
subject = action_id
|
|
if sub_type is None:
|
|
sub_type = "action metadata"
|
|
if verbosity is None:
|
|
verbosity = 1
|
|
|
|
self._failsafe_make_note(
|
|
assoc_id=assoc_id,
|
|
subject=subject,
|
|
sub_type=sub_type,
|
|
note_val=note_val,
|
|
verbosity=verbosity,
|
|
link_url=link_url,
|
|
is_auth_link=is_auth_link,
|
|
)
|
|
|
|
def get_all_action_notes(self, verbosity=None):
|
|
"""Retrieve notes for all actions, in a dictionary keyed by action id.
|
|
|
|
:param verbosity: optional, 1-5, the maximum verbosity level to
|
|
retrieve, defaults to 1 (most summary level)
|
|
|
|
Warning: if there are a lot of URL links in notes, this could take a
|
|
long time. The default verbosity of 1 attempts to avoid this as there
|
|
is less expectation of URL links on summary notes.
|
|
"""
|
|
max_verbosity = verbosity or MIN_VERBOSITY
|
|
notes = self._failsafe_get_notes(
|
|
assoc_id_pattern=ACTION_LOOKUP_PATTERN,
|
|
max_verbosity=verbosity,
|
|
exact_match=False
|
|
)
|
|
note_dict = {}
|
|
for n in notes:
|
|
# magic numbers [7:33] to slice a string like:
|
|
# action/12345678901234567890123456/something
|
|
# matching the convention in this helper.
|
|
# in the case where there are non-compliant, the slice will make
|
|
# the action_id a garbage key and that note will not be easily
|
|
# associated.
|
|
action_id = n.assoc_id[ACTION_ID_START:ACTION_ID_END]
|
|
if action_id not in note_dict:
|
|
note_dict[action_id] = []
|
|
note_dict[action_id].append(n)
|
|
return note_dict
|
|
|
|
def get_action_notes(self, action_id, verbosity=None):
|
|
"""Retrive notes related to a particular action
|
|
|
|
:param action_id: the action for which to retrieve notes.
|
|
:param verbosity: optional, 1-5, the maximum verbosity level to
|
|
retrieve, defaults to 5 (most detailed level)
|
|
"""
|
|
assoc_id_pattern = ACTION_KEY_PATTERN.format(action_id)
|
|
max_verbosity = verbosity or MAX_VERBOSITY
|
|
exact_match = True
|
|
return self._failsafe_get_notes(
|
|
assoc_id_pattern=assoc_id_pattern,
|
|
max_verbosity=max_verbosity,
|
|
exact_match=exact_match
|
|
)
|