All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rabbitmq.jms.client.RmqJmsConsumer Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2022 VMware, Inc. or its affiliates. All rights reserved.
package com.rabbitmq.jms.client;

import static com.rabbitmq.jms.client.Utils.wrap;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.jms.JMSConsumer;
import javax.jms.JMSException;
import javax.jms.JMSRuntimeException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageFormatException;
import javax.jms.MessageFormatRuntimeException;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.StreamMessage;

class RmqJmsConsumer implements JMSConsumer {

  private final Session session;
  private final MessageConsumer consumer;
  private final Queue failedBodyConversionMessages = new ConcurrentLinkedQueue<>();

  RmqJmsConsumer(Session session, MessageConsumer consumer) {
    this.session = session;
    this.consumer = consumer;
  }

  @Override
  public String getMessageSelector() {
    return wrap(() -> this.consumer.getMessageSelector());
  }

  @Override
  public MessageListener getMessageListener() throws JMSRuntimeException {
    return wrap(() -> this.consumer.getMessageListener());
  }

  @Override
  public void setMessageListener(MessageListener listener) throws JMSRuntimeException {
    wrap(() -> this.consumer.setMessageListener(listener));
  }

  @Override
  public Message receive() {
    return wrap(() -> this.consumer.receive());
  }

  @Override
  public Message receive(long timeout) {
    return wrap(() -> this.consumer.receive(timeout));
  }

  @Override
  public Message receiveNoWait() {
    return wrap(() -> this.consumer.receiveNoWait());
  }

  @Override
  public void close() {
    wrap(() -> this.consumer.close());
  }

  @Override
  public  T receiveBody(Class c) {
    Message message = failedBodyConversionMessages.poll();
    if (message == null) {
      message = this.receive();
    }
    return handleBodyConversion(message, c);
  }

  @Override
  public  T receiveBody(Class c, long timeout) {
    Message message = failedBodyConversionMessages.poll();
    if (message == null) {
      message = this.receive(timeout);
    }
    return handleBodyConversion(message, c);
  }

  @Override
  public  T receiveBodyNoWait(Class c) {
    Message message = failedBodyConversionMessages.poll();
    if (message == null) {
      message = this.receiveNoWait();
    }
    return handleBodyConversion(message, c);
  }

  private  T handleBodyConversion(Message message, Class c) {
    return wrap(() -> {
      if (message == null) {
        return null;
      } else if (message instanceof StreamMessage) {
        if (isAutoAckOrDupsOk()) {
          failedBodyConversionMessages.offer(message);
        }
        throw new MessageFormatRuntimeException(
            "Not possible to call receiveBody on a StreamMessage");
      } else {
        try {
          return message.getBody(c);
        } catch (MessageFormatException e) {
          if (isAutoAckOrDupsOk()) {
            failedBodyConversionMessages.offer(message);
          }
          throw new MessageFormatRuntimeException(e.getMessage(), e.getErrorCode(), e);
        }
      }
    });
  }

  private boolean isAutoAckOrDupsOk() throws JMSException {
    return this.session.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE
        || this.session.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy