Example #1
0
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)
Example #2
0
 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(),
         )
Example #3
0
    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)
Example #4
0
 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(),
         )
Example #5
0
    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)
Example #6
0
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
Example #9
0
def test_messages_dict_message():
    message = Message({"test key": "test value"})
    assert message.payload() == '{"test key": "test value"}'
Example #10
0
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