# 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