public void configure(Broker broker, SystemUsage memoryManager, DurableTopicSubscription sub) { String clientId = sub.getSubscriptionKey().getClientId(); String subName = sub.getSubscriptionKey().getSubscriptionName(); sub.setCursorMemoryHighWaterMark(getCursorMemoryHighWaterMark()); configurePrefetch(sub); if (pendingDurableSubscriberPolicy != null) { PendingMessageCursor cursor = pendingDurableSubscriberPolicy.getSubscriberPendingMessageCursor(broker,clientId, subName,sub.getPrefetchSize(),sub); cursor.setSystemUsage(memoryManager); sub.setPending(cursor); } int auditDepth = getMaxAuditDepth(); if (auditDepth == BaseDestination.MAX_AUDIT_DEPTH && this.isPrioritizedMessages()) { sub.setMaxAuditDepth(auditDepth * 10); } else { sub.setMaxAuditDepth(auditDepth); } sub.setMaxProducersToAudit(getMaxProducersToAudit()); sub.setUsePrefetchExtension(isUsePrefetchExtension()); }
sub = new DurableTopicSubscription(broker, usageManager, context, info, keepDurableSubsActive);
if (sub != null) { if (!context.isAllowLinkStealing() && sub.isActive()) { throw new JMSException("Durable consumer is in use for client: " + clientId + " and subscriptionName: " + subscriptionName); if (hasDurableSubChanged(info, sub.getConsumerInfo())) { destinationsLock.readLock().unlock(); super.removeConsumer(context, sub.getConsumerInfo()); super.addConsumer(context, info); sub = durableSubscriptions.get(key); } else { if (sub.getConsumerInfo().getConsumerId() != null) { subscriptions.remove(sub.getConsumerInfo().getConsumerId()); sub.info = info; sub.context = context; sub.deactivate(keepDurableSubsActive, info.getLastDeliveredSequenceId()); sub.setSelector(sub.getSelector()); sub.activate(usageManager, context, info, broker); return sub; } else {
@Override public synchronized String toString() { return "DurableTopicSubscription-" + getSubscriptionKey() + ", id=" + info.getConsumerId() + ", active=" + isActive() + ", destinations=" + durableDestinations.size() + ", total=" + getSubscriptionStatistics().getEnqueues().getCount() + ", pending=" + getPendingQueueSize() + ", dispatched=" + getSubscriptionStatistics().getDispatched().getCount() + ", inflight=" + dispatched.size() + ", prefetchExtension=" + getPrefetchExtension(); }
@Override public boolean recoverMessage(Message message) throws Exception { message.setRegionDestination(Topic.this); try { msgContext.setMessageReference(message); if (subscription.matches(message, msgContext)) { subscription.add(message); } } catch (IOException e) { LOG.error("Failed to recover this message {}", message, e); } return true; }
for (Destination destination : durableDestinations.values()) { Topic topic = (Topic) destination; add(context, topic); topic.activate(context, this); if (!((AbstractPendingMessageCursor) pending).isStarted() || !keepDurableSubsActive) { pending.setSystemUsage(memoryManager); pending.setMemoryUsageHighWaterMark(getCursorMemoryHighWaterMark()); pending.setMaxAuditDepth(getMaxAuditDepth()); pending.setMaxProducersToAudit(getMaxProducersToAudit()); pending.start(); dispatchPending(); this.usageManager.getMemoryUsage().addUsageListener(this);
String clientId = subscription.getSubscriptionKey().getClientId(); String subscriptionName = subscription.getSubscriptionKey().getSubscriptionName(); SubscriptionInfo info = topicStore.lookupSubscription(clientId, subscriptionName); if (info != null) { if (hasDurableSubChanged(info, subscription.getConsumerInfo())) { subscription.setSelector(subscription.getConsumerInfo().getSelector()); synchronized (consumers) { consumers.remove(subscription); info = new SubscriptionInfo(); info.setClientId(clientId); info.setSelector(subscription.getConsumerInfo().getSelector()); info.setSubscriptionName(subscriptionName); info.setDestination(getActiveMQDestination()); info.setNoLocal(subscription.getConsumerInfo().isNoLocal()); info.setSubscribedDestination(subscription.getConsumerInfo().getDestination()); topicStore.addSubscription(info, subscription.getConsumerInfo().isRetroactive()); if (subscription.isRecoveryRequired()) { topicStore.recoverSubscription(clientId, subscriptionName, new MessageRecoveryListener() { @Override
info.getSubscriptionName()); if (sub.isActive()) { throw new JMSException("Durable consumer is in use"); } else { if (subscriptions.get(sub.getConsumerInfo().getConsumerId()) != null) { super.removeConsumer(context, sub.getConsumerInfo()); } else {
@Override public void acknowledge(ConnectionContext context, Subscription sub, final MessageAck ack, final MessageReference node) throws IOException { if (topicStore != null && node.isPersistent()) { DurableTopicSubscription dsub = (DurableTopicSubscription) sub; SubscriptionKey key = dsub.getSubscriptionKey(); topicStore.acknowledge(context, key.getClientId(), key.getSubscriptionName(), node.getMessageId(), convertToNonRangedAck(ack, node)); } messageConsumed(context, node); }
@Override public void removeConsumer(ConnectionContext context, ConsumerInfo info) throws Exception { if (info.isDurable()) { SubscriptionKey key = new SubscriptionKey(context.getClientId(), info.getSubscriptionName()); DurableTopicSubscription sub = durableSubscriptions.get(key); if (sub != null) { // deactivate only if given context is same // as what is in the sub. otherwise, during linksteal // sub will get new context, but will be removed here if (sub.getContext() == context) { sub.deactivate(keepDurableSubsActive, info.getLastDeliveredSequenceId()); } } } else { super.removeConsumer(context, info); } }
@Override public void add(ConnectionContext context, Destination destination) throws Exception { if (!destinations.contains(destination)) { super.add(context, destination); } // do it just once per destination if (durableDestinations.containsKey(destination.getActiveMQDestination())) { return; } durableDestinations.put(destination.getActiveMQDestination(), destination); if (active.get() || keepDurableSubsActive) { Topic topic = (Topic) destination; topic.activate(context, this); getSubscriptionStatistics().getEnqueues().add(pending.size()); } else if (destination.getMessageStore() != null) { TopicMessageStore store = (TopicMessageStore) destination.getMessageStore(); try { getSubscriptionStatistics().getEnqueues().add(store.getMessageCount(subscriptionKey.getClientId(), subscriptionKey.getSubscriptionName())); } catch (IOException e) { JMSException jmsEx = new JMSException("Failed to retrieve enqueueCount from store " + e); jmsEx.setLinkedException(e); throw jmsEx; } } dispatchPending(); }
protected List<SubscriptionInfo> lookupSubscription(String clientId) throws MQTTProtocolException { List<SubscriptionInfo> result = new ArrayList<SubscriptionInfo>(); RegionBroker regionBroker; try { regionBroker = (RegionBroker) brokerService.getBroker().getAdaptor(RegionBroker.class); } catch (Exception e) { throw new MQTTProtocolException("Error recovering durable subscriptions: " + e.getMessage(), false, e); } final TopicRegion topicRegion = (TopicRegion) regionBroker.getTopicRegion(); List<DurableTopicSubscription> subscriptions = topicRegion.lookupSubscriptions(clientId); if (subscriptions != null) { for (DurableTopicSubscription subscription : subscriptions) { LOG.debug("Recovered durable sub:{} on connect", subscription); SubscriptionInfo info = new SubscriptionInfo(); info.setDestination(subscription.getActiveMQDestination()); info.setSubcriptionName(subscription.getSubscriptionKey().getSubscriptionName()); info.setClientId(clientId); result.add(info); } } return result; } }
String clientId = subscription.getSubscriptionKey().getClientId(); String subscriptionName = subscription.getSubscriptionKey().getSubscriptionName(); String selector = subscription.getConsumerInfo().getSelector(); SubscriptionInfo info = topicStore.lookupSubscription(clientId, subscriptionName); if (info != null) { info.setDestination(getActiveMQDestination()); info.setSubscribedDestination(subscription.getConsumerInfo().getDestination()); topicStore.addSubsciption(info, subscription.getConsumerInfo().isRetroactive()); if (subscription.isRecoveryRequired()) { topicStore.recoverSubscription(clientId, subscriptionName, new MessageRecoveryListener() { public boolean recoverMessage(Message message) throws Exception {
super.addSubscription(context, sub); sub.add(context, this); if(dsub.isActive()) { synchronized (consumers) { boolean hasSubscription = false; if (currentSub.getConsumerInfo().isDurable()) { DurableTopicSubscription dcurrentSub = (DurableTopicSubscription) currentSub; if (dcurrentSub.getSubscriptionKey().equals(dsub.getSubscriptionKey())) { hasSubscription = true; break; durableSubscribers.put(dsub.getSubscriptionKey(), dsub);
@Override public void onUsageChanged(Usage usage, int oldPercentUsage, int newPercentUsage) { if (oldPercentUsage > newPercentUsage && oldPercentUsage >= 90) { try { dispatchPending(); } catch (IOException e) { LOG.warn("problem calling dispatchMatched", e); } } }
if (sub != null && NetworkBridgeUtils.matchesNetworkConfig(config, sub.getConsumerInfo().getDestination())) { ConsumerInfo ci = sub.getConsumerInfo().copy(); ci.setClientId(key.getClientId()); subscriptionInfos.add(ci);
DurableTopicSubscription sub = durableSubscriptions.get(key); if (sub != null) { if (sub.isActive()) { throw new JMSException("Durable consumer is in use for client: " + clientId + " and subscriptionName: " + subscriptionName); if (hasDurableSubChanged(info, sub.getConsumerInfo())) { super.removeConsumer(context, sub.getConsumerInfo()); super.addConsumer(context, info); sub = durableSubscriptions.get(key); } else { if (sub.getConsumerInfo().getConsumerId() != null) { subscriptions.remove(sub.getConsumerInfo().getConsumerId()); sub.activate(usageManager, context, info); return sub; } else {
public void deleteSubscription(ConnectionContext context, SubscriptionKey key) throws Exception { if (topicStore != null) { topicStore.deleteSubscription(key.clientId, key.subscriptionName); DurableTopicSubscription removed = durableSubscribers.remove(key); if (removed != null) { destinationStatistics.getConsumers().decrement(); // deactivate and remove removed.deactivate(false, 0l); consumers.remove(removed); } } }
public synchronized String toString() { return "DurableTopicSubscription-" + getSubscriptionKey() + ", id=" + info.getConsumerId() + ", destinations=" + destinations.size() + ", total=" + enqueueCounter + ", pending=" + getPendingQueueSize() + ", dispatched=" + dispatchCounter + ", inflight=" + dispatched.size() + ", prefetchExtension=" + this.prefetchExtension; }
public DurableTopicSubscription(Broker broker, SystemUsage usageManager, ConnectionContext context, ConsumerInfo info, boolean keepDurableSubsActive) throws JMSException { super(broker, usageManager, context, info); this.pending = new StoreDurableSubscriberCursor(broker, context.getClientId(), info.getSubscriptionName(), info.getPrefetchSize(), this); this.pending.setSystemUsage(usageManager); this.pending.setMemoryUsageHighWaterMark(getCursorMemoryHighWaterMark()); this.keepDurableSubsActive = keepDurableSubsActive; subscriptionKey = new SubscriptionKey(context.getClientId(), info.getSubscriptionName()); }