org.apache.activemq.artemis.jms.client.ActiveMQJMSContext Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including
all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and
JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.jms.client;
import jakarta.jms.BytesMessage;
import jakarta.jms.ConnectionMetaData;
import jakarta.jms.Destination;
import jakarta.jms.ExceptionListener;
import jakarta.jms.IllegalStateRuntimeException;
import jakarta.jms.JMSConsumer;
import jakarta.jms.JMSContext;
import jakarta.jms.JMSException;
import jakarta.jms.JMSProducer;
import jakarta.jms.MapMessage;
import jakarta.jms.Message;
import jakarta.jms.MessageProducer;
import jakarta.jms.ObjectMessage;
import jakarta.jms.Queue;
import jakarta.jms.QueueBrowser;
import jakarta.jms.Session;
import jakarta.jms.StreamMessage;
import jakarta.jms.TemporaryQueue;
import jakarta.jms.TemporaryTopic;
import jakarta.jms.TextMessage;
import jakarta.jms.Topic;
import jakarta.jms.XAConnection;
import jakarta.jms.XASession;
import javax.transaction.xa.XAResource;
import java.io.Serializable;
/**
* ActiveMQ Artemis implementation of a JMSContext.
*/
public class ActiveMQJMSContext implements JMSContext {
private static final boolean DEFAULT_AUTO_START = true;
private final int sessionMode;
private final ThreadAwareContext threadAwareContext;
/**
* Client ACK needs to hold last acked messages, so context.ack calls will be respected.
*/
private volatile Message lastMessagesWaitingAck;
private final ActiveMQConnectionForContext connection;
private volatile Session session;
private boolean autoStart = ActiveMQJMSContext.DEFAULT_AUTO_START;
private MessageProducer innerProducer;
private boolean xa;
private boolean closed;
ActiveMQJMSContext(final ActiveMQConnectionForContext connection,
final int ackMode,
final boolean xa,
ThreadAwareContext threadAwareContext) {
this.connection = connection;
this.sessionMode = ackMode;
this.xa = xa;
this.threadAwareContext = threadAwareContext;
}
public ActiveMQJMSContext(ActiveMQConnectionForContext connection,
int ackMode,
ThreadAwareContext threadAwareContext) {
this(connection, ackMode, false, threadAwareContext);
}
public ActiveMQJMSContext(ActiveMQConnectionForContext connection, ThreadAwareContext threadAwareContext) {
this(connection, SESSION_TRANSACTED, true, threadAwareContext);
}
// XAJMSContext implementation -------------------------------------
public JMSContext getContext() {
return this;
}
public Session getSession() {
checkSession();
return session;
}
public XAResource getXAResource() {
checkSession();
return ((XASession) session).getXAResource();
}
// JMSContext implementation -------------------------------------
@Override
public JMSContext createContext(int sessionMode) {
return connection.createContext(sessionMode);
}
@Override
public JMSProducer createProducer() {
checkSession();
try {
return new ActiveMQJMSProducer(this, getInnerProducer());
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
private synchronized MessageProducer getInnerProducer() throws JMSException {
if (innerProducer == null) {
innerProducer = session.createProducer(null);
}
return innerProducer;
}
/**
*
*/
private void checkSession() {
if (session == null) {
synchronized (this) {
if (closed)
throw new IllegalStateRuntimeException("Context is closed");
if (session == null) {
try {
if (xa) {
session = ((XAConnection) connection).createXASession();
} else {
session = connection.createSession(sessionMode);
}
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
}
}
}
@Override
public String getClientID() {
try {
return connection.getClientID();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void setClientID(String clientID) {
try {
connection.setClientID(clientID);
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public ConnectionMetaData getMetaData() {
try {
return connection.getMetaData();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public ExceptionListener getExceptionListener() {
try {
return connection.getExceptionListener();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void setExceptionListener(ExceptionListener listener) {
try {
connection.setExceptionListener(listener);
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void start() {
try {
connection.start();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void stop() {
threadAwareContext.assertNotMessageListenerThreadRuntime();
try {
connection.stop();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void setAutoStart(boolean autoStart) {
this.autoStart = autoStart;
}
@Override
public boolean getAutoStart() {
return autoStart;
}
@Override
public void close() {
threadAwareContext.assertNotCompletionListenerThreadRuntime();
threadAwareContext.assertNotMessageListenerThreadRuntime();
try {
synchronized (this) {
if (session != null)
session.close();
connection.closeFromContext();
closed = true;
}
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public BytesMessage createBytesMessage() {
checkSession();
try {
return session.createBytesMessage();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public MapMessage createMapMessage() {
checkSession();
try {
return session.createMapMessage();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public Message createMessage() {
checkSession();
try {
return session.createMessage();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public ObjectMessage createObjectMessage() {
checkSession();
try {
return session.createObjectMessage();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public ObjectMessage createObjectMessage(Serializable object) {
checkSession();
try {
return session.createObjectMessage(object);
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public StreamMessage createStreamMessage() {
checkSession();
try {
return session.createStreamMessage();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public TextMessage createTextMessage() {
checkSession();
try {
return session.createTextMessage();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public TextMessage createTextMessage(String text) {
checkSession();
try {
return session.createTextMessage(text);
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public boolean getTransacted() {
checkSession();
try {
return session.getTransacted();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public int getSessionMode() {
return sessionMode;
}
@Override
public void commit() {
threadAwareContext.assertNotCompletionListenerThreadRuntime();
checkSession();
try {
session.commit();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void rollback() {
threadAwareContext.assertNotCompletionListenerThreadRuntime();
checkSession();
try {
session.rollback();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void recover() {
checkSession();
try {
session.recover();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createConsumer(Destination destination) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createConsumer(destination));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createConsumer(Destination destination, String messageSelector) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createConsumer(destination, messageSelector));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createConsumer(destination, messageSelector, noLocal));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public Queue createQueue(String queueName) {
checkSession();
try {
return session.createQueue(queueName);
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public Topic createTopic(String topicName) {
checkSession();
try {
return session.createTopic(topicName);
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createDurableConsumer(Topic topic, String name) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createDurableConsumer(topic, name));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createDurableConsumer(Topic topic, String name, String messageSelector, boolean noLocal) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createDurableConsumer(topic, name, messageSelector, noLocal));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createSharedDurableConsumer(Topic topic, String name) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createSharedDurableConsumer(topic, name));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createSharedDurableConsumer(Topic topic, String name, String messageSelector) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createSharedDurableConsumer(topic, name, messageSelector));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createSharedConsumer(Topic topic, String sharedSubscriptionName) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createSharedConsumer(topic, sharedSubscriptionName));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public JMSConsumer createSharedConsumer(Topic topic, String sharedSubscriptionName, String messageSelector) {
checkSession();
try {
ActiveMQJMSConsumer consumer = new ActiveMQJMSConsumer(this, session.createSharedConsumer(topic, sharedSubscriptionName, messageSelector));
checkAutoStart();
return consumer;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public QueueBrowser createBrowser(Queue queue) {
checkSession();
try {
QueueBrowser browser = session.createBrowser(queue);
checkAutoStart();
return browser;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public QueueBrowser createBrowser(Queue queue, String messageSelector) {
checkSession();
try {
QueueBrowser browser = session.createBrowser(queue, messageSelector);
checkAutoStart();
return browser;
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public TemporaryQueue createTemporaryQueue() {
checkSession();
try {
return session.createTemporaryQueue();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public TemporaryTopic createTemporaryTopic() {
checkSession();
try {
return session.createTemporaryTopic();
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void unsubscribe(String name) {
checkSession();
try {
session.unsubscribe(name);
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
@Override
public void acknowledge() {
checkSession();
if (closed)
throw new IllegalStateRuntimeException("Context is closed");
try {
if (lastMessagesWaitingAck != null) {
lastMessagesWaitingAck.acknowledge();
}
} catch (JMSException e) {
throw JmsExceptionUtils.convertToRuntimeException(e);
}
}
/**
* This is to be used on tests only. It's not part of the interface and it's not guaranteed to be kept
* on the API contract.
*
* @return
*/
public Session getUsedSession() {
return this.session;
}
private synchronized void checkAutoStart() throws JMSException {
if (closed)
throw new IllegalStateRuntimeException("Context is closed");
if (autoStart) {
connection.start();
}
}
/**
* this is to ensure Context.acknowledge would work on ClientACK
*/
Message setLastMessage(final Message lastMessageReceived) {
if (sessionMode == CLIENT_ACKNOWLEDGE && lastMessageReceived != null) {
lastMessagesWaitingAck = lastMessageReceived;
}
return lastMessageReceived;
}
public ThreadAwareContext getThreadAwareContext() {
return threadAwareContext;
}
}