class StoragePolicyProcessorJmsMessageListener {

    @JmsListener(id = HerdJmsDestinationResolver.SQS_DESTINATION_STORAGE_POLICY_SELECTOR_JOB_SQS_QUEUE,
        containerFactory = "storagePolicyProcessorJmsListenerContainerFactory",
        destination = HerdJmsDestinationResolver.SQS_DESTINATION_STORAGE_POLICY_SELECTOR_JOB_SQS_QUEUE)
    public void processMessage(String payload, @Headers Map<Object, Object> allHeaders)
    {
        LOGGER.info("Message received from the JMS queue. jmsQueueName=\"{}\" jmsMessageHeaders=\"{}\" jmsMessagePayload={}",
            HerdJmsDestinationResolver.SQS_DESTINATION_STORAGE_POLICY_SELECTOR_JOB_SQS_QUEUE, allHeaders, payload);

        // Process the message as storage policy selection message.
        try
        {
            // Process messages coming from the storage policy selector job.
            StoragePolicySelection storagePolicySelection = jsonHelper.unmarshallJsonToObject(StoragePolicySelection.class, payload);

            LOGGER.debug("Received storage policy selection message: businessObjectDataKey={} storagePolicyKey={} storagePolicyVersion={}",
                jsonHelper.objectToJson(storagePolicySelection.getBusinessObjectDataKey()),
                jsonHelper.objectToJson(storagePolicySelection.getStoragePolicyKey()), storagePolicySelection.getStoragePolicyVersion());

            // Process the storage policy selection message.
            storagePolicyProcessorService.processStoragePolicySelectionMessage(storagePolicySelection);
        }
        catch (RuntimeException | IOException e)
        {
            // Log a warning message if storage unit status is already ARCHIVED. Such error case is typically caused by a duplicate SQS message.
            if (e instanceof IllegalArgumentException &&
                e.getMessage().startsWith(String.format("Storage unit status is \"%s\"", StorageUnitStatusEntity.ARCHIVED)))
            {
                LOGGER.warn("Failed to process message from the JMS queue. jmsQueueName=\"{}\" jmsMessagePayload={}",
                    HerdJmsDestinationResolver.SQS_DESTINATION_STORAGE_POLICY_SELECTOR_JOB_SQS_QUEUE, payload, e);
            }
            // Otherwise, log an error.
            else
            {
                LOGGER.error("Failed to process message from the JMS queue. jmsQueueName=\"{}\" jmsMessagePayload={}",
                    HerdJmsDestinationResolver.SQS_DESTINATION_STORAGE_POLICY_SELECTOR_JOB_SQS_QUEUE, payload, e);
            }
        }
    }

}