"""Participant Handlers.""" from switchboard_consumer.constants import entity_type from switchboard_consumer.constants.exceptions import ( ParticipantHandlerError, ParticipantHandlerGraphQLError) from switchboard_consumer.formatters.artist import ( format_artist_result, format_create_artist_input, format_filter_artists_input, format_get_artist_input, format_participant) from switchboard_consumer.utils.graphql import is_error from switchboard_consumer.utils.message import (create_processing_result) class BaseParticipantHandler: """"BaseParticipantHandler.""" def __init__( self, logger, orchard_client, message, vendor_id, subaccount_id): """Create a BaseParticipantHandler instance. Args: logger: Logger instance orchard_client: OrchardClient instance message: Incoming KafkaMessage vendor_id: target vendor id subaccount_id: target subaccount id """ self.logger = logger self.orchard_client = orchard_client self.message = message self.correlation_id = self.message.correlation_id self.vendor_id = vendor_id # 0 because the personnel mutation always requires a subaccount value self.subaccount_id = subaccount_id or 0 def process(self, data): """Process participants.""" raise NotImplementedError() def handle_participant(self, participant, role, source_mapping, target_mapping): """Handle creating orchard artist data for a participant.""" self._create_label_participant(participant) name = participant['name'] if target_mapping: result = self._get_artist(target_mapping['localId']) if result['vendorId'] != self.vendor_id: # We have to create the participant under the target vendor. # Check if there's an artist already present on vendor find_artist_results = self._find_artists(name) if not find_artist_results: # If no artist found, create one return self._create_artist(participant, role, source_mapping) else: # Artists found, use the first one to build mapping existing_artist = find_artist_results[0] return self._build_result_mapping(source_mapping, existing_artist, role) else: # Valid mapping already in place return None, format_participant(target_mapping['localId'], name, role) else: # Check if there's an artist already present on vendor find_artist_results = self._find_artists(name) if not find_artist_results: # If no artist found, create one return self._create_artist(participant, role, source_mapping) else: # Artists have been found, use the first one to build mapping existing_artist = find_artist_results[0] return self._build_result_mapping(source_mapping, existing_artist, role) def _get_artist(self, artist_id): """Perform get artist through graphql-product.""" query_input = format_get_artist_input(artist_id) result = self.orchard_client.get_artist(query_input, self.correlation_id) if not result: # No artist found but we have been provided an orchard mapping. # Has the artist been deleted from the Orchard DB? message = 'Orchard artist mapping provided not found in Orchard' self.logger.error(message) raise ParticipantHandlerError(message) if is_error(result): errors = result.get('errors') message = 'Error encountered getting artist info from Orchard' self.logger.error(message, custom_fields={'raw_errors': errors}) raise ParticipantHandlerGraphQLError(message, errors) return result def _create_artist(self, participant, role, source_artist_mapping): """Perform create artist through graphql-product.""" artist_name = participant['name'] result = self.orchard_client.create_artist( format_create_artist_input( artist_name, self.vendor_id ), self.correlation_id ) if is_error(result): errors = result.get('errors') message = 'Error encountered creating artist' self.logger.error(message, custom_fields={'raw_errors': errors}) raise ParticipantHandlerGraphQLError(message, errors) return self._build_result_mapping(source_artist_mapping, result, role) def _create_label_participant(self, participant): """Perform create label participant through graphql-product""" label_participant_result = \ self.orchard_client.create_label_participant( participant, self.vendor_id, self.subaccount_id, self.correlation_id ) if is_error(label_participant_result): errors = label_participant_result.get('errors') message = 'Error encountered creating label participant' self.logger.error(message, custom_fields={'raw_errors': errors}) raise ParticipantHandlerGraphQLError(message, errors) def _find_artists(self, artist_name): query_input = format_filter_artists_input(artist_name, self.vendor_id) result = self.orchard_client.filter_artists(query_input, self.correlation_id) if is_error(result): errors = result.get('errors') message = 'Error encountered finding artist in Orchard' self.logger.warning(message, custom_fields={'raw_errors': errors}) raise ParticipantHandlerGraphQLError(message, errors) return result def _build_result_mapping(self, source_artist_mapping, artist_result, role): """Build a result mapping for participant. Returns: (tuple): tuple containing: processing_result (dict): processing result message artist_result (dict): formatted artist info """ participant_mapping = ([source_artist_mapping] + # noqa format_artist_result(artist_result['artistId'])) return (create_processing_result(participant_mapping, self.message, entity_type=entity_type.PARTICIPANT), format_participant(artist_result['artistId'], artist_result['artistName'], role))