def message_source_all_negative(): message_content: EventMessage = { "event": { "uuid": "1770dbcd-0abf-4293-ac62-dd26964f80b0", "event_type": PE_BECKMAN_SOURCE_ALL_NEGATIVES, "occured_at": "2020-11-26T15:58:20", "user_identifier": "test1", "subjects": [ { "role_type": "cherrypicking_source_labware", "subject_type": "plate", "friendly_name": "plate-barcode", "uuid": "00000000-1111-2222-3333-555555555556", }, { "role_type": "robot", "subject_type": "robot", "friendly_name": "robot-serial", "uuid": "00000000-1111-2222-3333-555555555557", }, ], "metadata": {}, }, "lims": "LH_TEST", } return Message(message_content)
def publish(self, message: Message, routing_key: str) -> None: if message is not None and routing_key is not None: logger.debug("Publishing message") self._channel.basic_publish( exchange=app.config["RMQ_EXCHANGE"], routing_key=routing_key, body=message.payload(), )
def render(self) -> Message: message_content = self.construct_event_message( event_uuid=self._event_uuid, occured_at=self._occured_at, subjects=self._subjects, metadata=self._metadata, ) return Message(message_content)
def send_warehouse_message(self, message: Message) -> None: """Publishes a message to the exchange as specified in configuration.""" logger.info("Attempting to publish the constructed plate event message") with Broker() as broker_channel: broker_channel.basic_publish( exchange=app.config["RMQ_EXCHANGE"], routing_key=self.routing_key, body=message.payload(), )
def render(self) -> Message: message_content = self.construct_sequencescape_message( barcode=self._barcode, purpose_uuid=app.config["SS_UUID_PLATE_PURPOSE_CHERRYPICKED"], study_uuid=app.config["SS_UUID_STUDY_CHERRYPICKED"], wells=self._contents, events=[], ) return Message(message_content)
def message_unknown(): message_content: EventMessage = { "event": { "uuid": "1770dbcd-0abf-4293-ac62-dd26964f80b0", "event_type": "no_callbacks", "occured_at": "2020-11-26T15:58:20", "user_identifier": "test1", "subjects": [], "metadata": {}, }, "lims": "LH_TEST", } return Message(message_content)
def test_fail_plate_from_barcode_internal_error_failed_broker_initialise( client, base_url): with patch( "lighthouse.routes.common.cherrypicked_plates.construct_cherrypicking_plate_failed_message" ) as mock_construct: with patch("lighthouse.routes.common.cherrypicked_plates.Broker", side_effect=Exception()): mock_construct.return_value = [], Message({"test": "me"}) response = client.get( f"{base_url}?barcode=plate_1&user_id=test_user" "&robot=BKRB0001&failure_type=robot_crashed") assert response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR assert ERROR_UNEXPECTED_CHERRYPICKING_FAILURE in response.json[ "errors"][0]
def test_fail_plate_from_barcode_success(client, base_url): with patch( "lighthouse.routes.common.cherrypicked_plates.construct_cherrypicking_plate_failed_message" ) as mock_construct: routing_key = "test.routing.key" with patch( "lighthouse.routes.common.cherrypicked_plates.get_routing_key", return_value=routing_key): with patch("lighthouse.routes.common.cherrypicked_plates.Broker" ) as mock_broker: test_errors = ["error 1", "error 2"] test_message = Message({"test": "me"}) mock_construct.return_value = test_errors, test_message response = client.get( f"{base_url}?barcode=plate_1&user_id=test_user" "&robot=BKRB0001&failure_type=robot_crashed") mock_broker().publish.assert_called_with( test_message, routing_key) mock_broker()._close_connection.assert_called() assert response.status_code == HTTPStatus.OK assert response.json["errors"] == test_errors
def test_messages_dict_message(): message = Message({"test key": "test value"}) assert message.payload() == '{"test key": "test value"}'
def construct_cherrypicking_plate_failed_message( barcode: str, user_id: str, robot_serial_number: str, failure_type: str) -> Tuple[List[str], Optional[Message]]: try: subjects, errors = [], [] # Add robot and destination plate subjects subjects.append(__robot_subject(robot_serial_number)) subjects.append(construct_destination_plate_message_subject(barcode)) # Try to add sample and source plate subjects dart_samples = None try: dart_samples = find_dart_source_samples_rows(barcode) except Exception as e: # a failed DART connection is valid: # it may be caused by the failure the user is trying to record logger.info(f"Failed to connect to DART: {e}") if dart_samples is None: # still send message, but inform caller that DART connection could not be made msg = ( f"There was an error connecting to DART for destination plate '{barcode}'. " "As this may be due to the failure you are reporting, a destination plate failure " "has still been recorded, but without sample and source plate information" ) logger.info(msg) errors.append(msg) elif len(dart_samples) == 0: # still send message, but inform caller that no samples were in the destination plate msg = ( f"No samples were found in DART for destination plate '{barcode}'. As this may be " "due to the failure you are reporting, a destination plate failure has still been " "recorded, but without sample and source plate information") logger.info(msg) errors.append(msg) else: mongo_samples = find_samples( query_for_cherrypicked_samples(dart_samples)) if mongo_samples is None: return [ f"No sample data found in Mongo matching DART samples in plate '{barcode}'" ], None if not check_matching_sample_numbers(dart_samples, mongo_samples): return [ f"Mismatch in destination and source sample data for plate '{barcode}'" ], None # Add sample subjects for control and non-control DART entries dart_control_rows = [ row_to_dict(row) for row in rows_with_controls(dart_samples) ] subjects.extend([ __sample_subject_for_dart_control_row(r) for r in dart_control_rows ]) subjects.extend([ construct_mongo_sample_message_subject(s) for s in mongo_samples ]) # Add source plate subjects source_plates = get_source_plates_for_samples(mongo_samples) if not source_plates: return [ f"No source plate data found in Mongo for DART samples in plate '{barcode}'" ], None subjects.extend(__mongo_source_plate_subjects(source_plates)) # Construct message message_content = { "event": { "uuid": str(uuid4()), "event_type": PE_BECKMAN_DESTINATION_FAILED, "occured_at": get_message_timestamp(), "user_identifier": user_id, "subjects": subjects, "metadata": { "failure_type": failure_type }, }, "lims": app.config["RMQ_LIMS_ID"], } return errors, Message(message_content) except Exception as e: logger.error( "Failed to construct a cherrypicking plate failed message") logger.exception(e) return [ "An unexpected error occurred attempting to construct the cherrypicking plate " f"failed event message: {e}" ], None