Как определить, запущена или остановлена очередь JMS?

#java #jms #oracle-aq

#java #jms #oracle-aq

Вопрос:

У меня есть служба Java, которая получает сообщения из расширенной очереди Oracle. Я могу создать соединение, прослушивать и получать сообщения нормально. Я вижу, что вы можете останавливать и начинать прослушивать сообщения, поэтому я внедрил для этого элементы управления. Тем не менее, я хотел бы иметь возможность сообщать о текущем состоянии прослушивателя. Я могу видеть, есть ли она, но как я могу определить, остановлена она или запущена?

У меня есть класс контейнера в соответствии с ( Listener это мой собственный класс (реализующий оба MessageListener и ExceptionListener ), который на самом деле что-то делает с сообщением)

 public class QueueContainer {
  private static final String QUEUE_NAME = "foo";

  private final Connection dbConnection;
  private final QueueConnection queueConnection;
  private final QueueSession queueSession;
  private final Queue queue;
  private final MessageConsumer consumer;
  private final Listener listener;

public QueueContainer(final Connection dbConnection ) {
    try {
      this.dbConnection = dbConnection;
      queueConnection = AQjmsQueueConnectionFactory.createQueueConnection(dbConnection);
      queueSession = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
      queue = ((AQjmsSession) queueSession).getQueue(context.getEnvironment(), QUEUE_NAME);
      consumer = queueSession.createConsumer(queue);
      listener = new Listener(QUEUE_NAME);
      consumer.setMessageListener(listener);
      queueConnection.setExceptionListener(listener);
    } catch (JMSException | SQLException e) {
      throw new RunTimeException("Queue Exception", e);
    }
  }
  public void startListening() {
    try {
      queueConnection.start();

    } catch (JMSException e) {
      throw new RunTimeException("Failed to start listening to queue", e);
    }
  }

  public void stopListening() {
    try {
      queueConnection.stop();
    } catch (JMSException e) {
      throw new RunTimeException("Failed to stop listening to queue", e);
    }
  }

  public void close() {
    if (queueConnection != null) {
      try {
        queueConnection.close();
      } catch (JMSException e) {
        throw new RunTimeException("Failed to stop listening to queue", e);
      }
    }
  }

  public boolean isRunning() {
    try {
      // This doesn't work - I can't distinguish between started and stopped
      return queueConnection.getClientID() != null;
    } catch (JMSException e) {
      LOGGER.warn("Failed to get queue client ID", e);
      return false;
    }
  }
  

Я не вижу, что вставить isRunning , чтобы можно было отличить остановленный прослушиватель от запущенного

Ответ №1:

JMS API предполагает, что вы сами знаете, что вы сделали. Так почему бы не добавить логический флаг и отслеживать это?

     private volatile boolean isListening = false;
    ...

    public void startListening() {
    try {
      queueConnection.start();
      isListening = true;
    } catch (JMSException e) {
      throw new RunTimeException("Failed to start listening to queue", e);
    }
  }

  public void stopListening() {
    try {
      queueConnection.stop();
      isListening = false;
    } catch (JMSException e) {
      throw new RunTimeException("Failed to stop listening to queue", e);
    }
  }

  public void close() {
    if (queueConnection != null) {
      try {
        queueConnection.close();
        isListening = false;
      } catch (JMSException e) {
        throw new RunTimeException("Failed to stop listening to queue", e);
      }
    }
  }

  public boolean isRunning() {
      return isListening;
  }
  

Комментарии:

1. Подойдет. Надеялся, что он сообщит — предположительно, могут произойти вещи, которые остановят это. Но я повторно подключусь из обработчика исключений и обработаю это там.

Ответ №2:

Нет вызова JMS API для определения того, javax.jms.Connection запущена или нет.

Для ясности, сама очередь не является объектом, который запускается или останавливается. Соединение запущено или остановлено.

Вы можете получить эту информацию из объекта реализации Oracle Advanced Queue, но я не знаком с этой реализацией, поэтому не могу сказать. Очевидно, что любое решение, использующее объект реализации, а не стандартный API, не будет переносимым.