}
}
int consumerID = connectionEndpoint.getServerPeer().getNextObjectID();
Binding binding = null;
// Always validate the selector first
Selector selector = null;
if (selectorString != null)
{
selector = new Selector(selectorString);
}
if (jmsDestination.isTopic())
{
JMSCondition topicCond = new JMSCondition(false, jmsDestination.getName());
if (subscriptionName == null)
{
// non-durable subscription
if (log.isTraceEnabled()) { log.trace(this + " creating new non-durable subscription on " + jmsDestination); }
// Create the non durable sub
PagingFilteredQueue q;
if (postOffice.isLocal() || !mDest.isClustered())
{
q = new PagingFilteredQueue(new GUID().toString(), idm.getID(), ms, pm, true, false,
mDest.getMaxSize(), selector,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize());
binding = postOffice.bindQueue(topicCond, q);
}
else
{
q = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, new GUID().toString(),
idm.getID(), ms, pm, true, false,
mDest.getMaxSize(), selector, tr,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize());
ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
binding = cpo.bindClusteredQueue(topicCond, (LocalClusteredQueue)q);
}
String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + q.getName();
int dayLimitToUse = mDest.getMessageCounterHistoryDayLimit();
if (dayLimitToUse == -1)
{
//Use override on server peer
dayLimitToUse = sp.getDefaultMessageCounterHistoryDayLimit();
}
MessageCounter counter =
new MessageCounter(counterName, null, q, 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 = postOffice.getBindingForQueueName(name);
if (binding == null)
{
// Does not already exist
if (trace) { log.trace(this + " creating new durable subscription on " + jmsDestination); }
PagingFilteredQueue q;
if (postOffice.isLocal())
{
q = new PagingFilteredQueue(name, idm.getID(), ms, pm, true, true,
mDest.getMaxSize(), selector,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize());
binding = postOffice.bindQueue(topicCond, q);
}
else
{
q = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, name, idm.getID(),
ms, pm, true, true,
mDest.getMaxSize(), selector, tr,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize());
ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
if (mDest.isClustered())
{
binding = cpo.bindClusteredQueue(topicCond, (LocalClusteredQueue)q);
}
else
{
binding = cpo.bindQueue(topicCond, q);
}
}
String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + q.getName();
MessageCounter counter =
new MessageCounter(counterName, subscriptionName, q, true, true,
mDest.getMessageCounterHistoryDayLimit());
sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
}
else
{
//Durable sub already exists
if (trace) { log.trace(this + " subscription " + subscriptionName + " already exists"); }
// 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 =
binding.getQueue().getFilter() != null ?
binding.getQueue().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"); }
JMSCondition cond = (JMSCondition)binding.getCondition();
boolean topicChanged = !cond.getName().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
if (mDest.isClustered() && !postOffice.isLocal())
{
ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
cpo.unbindClusteredQueue(name);
}
else
{
postOffice.unbindQueue(name);
}
// create a fresh new subscription
PagingFilteredQueue q;
if (postOffice.isLocal())
{
q = new PagingFilteredQueue(name, idm.getID(), ms, pm, true, true,
mDest.getMaxSize(), selector,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize());
binding = postOffice.bindQueue(topicCond, q);
}
else
{
q = new LocalClusteredQueue((ClusteredPostOffice)postOffice, nodeId, name, idm.getID(), ms, pm, true, true,
mDest.getMaxSize(), selector, tr,
mDest.getFullSize(),
mDest.getPageSize(),
mDest.getDownCacheSize());
ClusteredPostOffice cpo = (ClusteredPostOffice)postOffice;
if (mDest.isClustered())
{
binding = cpo.bindClusteredQueue(topicCond, (LocalClusteredQueue)q);
}
else
{
binding = cpo.bindQueue(topicCond, (LocalClusteredQueue)q);
}
}
String counterName = TopicService.SUBSCRIPTION_MESSAGECOUNTER_PREFIX + q.getName();
MessageCounter counter =
new MessageCounter(counterName, subscriptionName, q, true, true,
mDest.getMessageCounterHistoryDayLimit());
sp.getMessageCounterManager().registerMessageCounter(counterName, counter);
}
}
}
}
else
{
// Consumer on a jms queue
// Let's find the binding
binding = postOffice.getBindingForQueueName(jmsDestination.getName());
if (binding == null)
{
throw new IllegalStateException("Cannot find binding for jms queue: " + jmsDestination.getName());
}
}
int prefetchSize = connectionEndpoint.getPrefetchSize();
Queue dlqToUse = mDest.getDLQ() == null ? defaultDLQ : mDest.getDLQ();
Queue expiryQueueToUse = mDest.getExpiryQueue() == null ? defaultExpiryQueue : mDest.getExpiryQueue();
long redeliveryDelay = mDest.getRedeliveryDelay();
if (redeliveryDelay == 0)
{
redeliveryDelay = sp.getDefaultRedeliveryDelay();
}
ServerConsumerEndpoint ep =
new ServerConsumerEndpoint(consumerID, (PagingFilteredQueue)binding.getQueue(),
binding.getQueue().getName(), this, selectorString, noLocal,
jmsDestination, dlqToUse, expiryQueueToUse, redeliveryDelay);
ConsumerAdvised advised;
// Need to synchronized to prevent a deadlock