}
//We don't create message counters on temp topics
if (!mDest.isTemporary())
{
MessageCounter counter = new MessageCounter(counterName, null, queue, true, false, dayLimitToUse);
sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
}
}
else
{
if (jmsDestination.isTemporary())
{
throw new InvalidDestinationException("Cannot create a durable subscription on a temporary topic");
}
// We have a durable subscription, look it up
String clientID = connectionEndpoint.getClientID();
if (clientID == null)
{
throw new JMSException("Cannot create durable subscriber without a valid client ID");
}
// See if there any bindings with the same client_id.subscription_name name
String name = MessageQueueNameHelper.createSubscriptionName(clientID, subscriptionName);
Binding binding = postOffice.getBindingForQueueName(name);
if (binding == null)
{
// Does not already exist
if (trace) { log.trace(this + " creating new durable subscription on " + jmsDestination); }
queue = new MessagingQueue(nodeId, name, idm.getID(),
ms, pm, true,
mDest.getMaxSize(), selector,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize(),
mDest.isClustered(),
sp.getRecoverDeliveriesTimeout());
// Durable subs must be bound on ALL nodes of the cluster (if clustered)
postOffice.addBinding(new Binding(new JMSCondition(false, jmsDestination.getName()), queue, true),
postOffice.isClustered() && mDest.isClustered());
queue.activate();
//We don't create message counters on temp topics
if (!mDest.isTemporary())
{
String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + queue.getName();
MessageCounter counter =
new MessageCounter(counterName, subscriptionName, queue, true, true,
mDest.getMessageCounterHistoryDayLimit());
sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
}
}
else
{
//Durable sub already exists
queue = binding.queue;
if (trace) { log.trace(this + " subscription " + subscriptionName + " already exists"); }
//Check if it is already has a subscriber
//We can't have more than one subscriber at a time on the durable sub unless it is clustered
//we need this for clustered since otherwise we wouldn't be able to fail over subcribers for the same durable
//sub onto a node which already has one
if (queue.getLocalDistributor().getNumberOfReceivers() > 0 && !mDest.isClustered())
{
throw new IllegalStateException("Cannot create a subscriber on the durable subscription since it already has subscriber(s)");
}
// If the durable sub exists because it is clustered and was created on this node due to a bind on another node
// then it will have no message counter
String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + queue.getName();
boolean createCounter = false;
if (sp.getMessageCounterManager().getMessageCounter(counterName) == null)
{
createCounter = true;
}
// From javax.jms.Session Javadoc (and also JMS 1.1 6.11.1):
// A client can change an existing durable subscription by creating a durable
// TopicSubscriber with the same name and a new topic and/or message selector.
// Changing a durable subscriber is equivalent to unsubscribing (deleting) the old
// one and creating a new one.
String filterString = queue.getFilter() != null ? queue.getFilter().getFilterString() : null;
boolean selectorChanged =
(selectorString == null && filterString != null) ||
(filterString == null && selectorString != null) ||
(filterString != null && selectorString != null &&
!filterString.equals(selectorString));
if (trace) { log.trace("selector " + (selectorChanged ? "has" : "has NOT") + " changed"); }
String oldTopicName = ((JMSCondition)binding.condition).getName();
boolean topicChanged = !oldTopicName.equals(jmsDestination.getName());
if (log.isTraceEnabled()) { log.trace("topic " + (topicChanged ? "has" : "has NOT") + " changed"); }
if (selectorChanged || topicChanged)
{
if (trace) { log.trace("topic or selector changed so deleting old subscription"); }
// Unbind the durable subscription
// Durable subs must be unbound on ALL nodes of the cluster
postOffice.removeBinding(queue.getName(), postOffice.isClustered() && mDest.isClustered());
// create a fresh new subscription
queue = new MessagingQueue(nodeId, name, idm.getID(), ms, pm, true,
mDest.getMaxSize(), selector,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize(),
mDest.isClustered(),
sp.getRecoverDeliveriesTimeout());
// Durable subs must be bound on ALL nodes of the cluster
postOffice.addBinding(new Binding(new JMSCondition(false, jmsDestination.getName()), queue, true),
postOffice.isClustered() && mDest.isClustered());
queue.activate();
if (!mDest.isTemporary())
{
createCounter = true;
}
}
if (createCounter)
{
MessageCounter counter =
new MessageCounter(counterName, subscriptionName, queue, true, true,
mDest.getMessageCounterHistoryDayLimit());
sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
}
}