You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
4.4 KiB

# Copyright (C) 2005-2024 Splunk Inc. All Rights Reserved.
from itsi.content_packs import constants
from itsi.content_packs.itoa import (
get_itoa_object_class,
get_itoa_object_id,
get_itoa_object_title
)
from itsi.content_packs.journal import EntryType
class ItoaContentWriter(object):
"""
Handles the saving of content objects into ITSI.
"""
def __init__(self, logger, session_key):
"""
:param logger: a logger instance
:type logger: Logger
:param session_key: the session key
:type session_key: str
"""
self.logger = logger
self.session_key = session_key
def write(self, content_objects, journal):
"""
Writes the given content objects to storage.
:param content_objects: the content objects data
:type content_objects: dict
:param journal: a journal instance
:type journal: TransactionJournal
:return: a dict of content objects data
:rtype: dict
"""
results = {}
content_types = sorted(content_objects.keys(), key=lambda x: constants.CONTENT_TYPE_WRITE_PRIORITY[x])
for content_type in content_types:
objects = content_objects[content_type]
if not objects:
continue
object_ids = self.write_objects(content_type, objects, journal=journal)
objects_data = self.construct_objects_data(content_type, object_ids, objects)
if objects_data:
results[content_type] = objects_data
return results
def write_objects(self, content_type, objects, journal):
"""
Writes the given objects for a content type to storage.
:param content_type: the content type
:type content_type: str
:param objects: a list of objects data
:type objects: list
:param journal: a journal instance
:type journal: TransactionJournal
:return: a list of successfully written object ids
:rtype: list
"""
itoa_object_class = get_itoa_object_class(content_type)
if not itoa_object_class:
error_message = f'Unexpected writing of unsupported content_type="{content_type}"'
self.logger.error(error_message)
journal.failure({
'error_message': error_message,
'type': EntryType.INVALID_CONTENT_TYPE,
'content_type': content_type,
'ids': list({get_itoa_object_id(content_type, obj) for obj in objects}),
'titles': list({get_itoa_object_title(content_type, obj) for obj in objects})
})
return []
handler = itoa_object_class(self.session_key, 'nobody')
handler.skip_service_template_update = True
try:
object_ids = handler.save_batch(
'nobody',
objects,
validate_names=False
)
except Exception as ex:
self.logger.error('Failed to create objects for content_type="%s"', content_type)
self.logger.exception(ex)
journal.failure({
'error_message': str(ex),
'type': EntryType.ERROR_OBJECTS_SAVE,
'content_type': content_type,
'ids': list({get_itoa_object_id(content_type, obj) for obj in objects}),
'titles': list({get_itoa_object_title(content_type, obj) for obj in objects})
})
return []
return object_ids
def construct_objects_data(self, content_type, object_ids, objects):
"""
Constructs the objects data for the given list of object ids.
:param content_type: the content type
:type content_type: str
:param object_ids: a list of object ids
:type object_ids: list
:param objects: a list of object data
:type objects: list
:return: a list of object data
:rtype: list
"""
lookup = { get_itoa_object_id(content_type, obj): obj for obj in objects }
objects_data = []
for object_id in object_ids:
if object_id not in lookup:
continue
data = lookup[object_id]
objects_data.append({
'id': object_id,
'title': get_itoa_object_title(content_type, data)
})
return objects_data