content: /**
   * 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.broker.region.policy;
  
  import java.util.Set;
  
  import org.apache.activemq.ActiveMQPrefetchPolicy;
  import org.apache.activemq.broker.Broker;
  import org.apache.activemq.broker.region.BaseDestination;
  import org.apache.activemq.broker.region.Destination;
  import org.apache.activemq.broker.region.DurableTopicSubscription;
  import org.apache.activemq.broker.region.Queue;
  import org.apache.activemq.broker.region.QueueBrowserSubscription;
  import org.apache.activemq.broker.region.QueueSubscription;
  import org.apache.activemq.broker.region.Subscription;
  import org.apache.activemq.broker.region.Topic;
  import org.apache.activemq.broker.region.TopicSubscription;
  import org.apache.activemq.broker.region.cursors.PendingMessageCursor;
  import org.apache.activemq.broker.region.group.GroupFactoryFinder;
  import org.apache.activemq.broker.region.group.MessageGroupMapFactory;
  import org.apache.activemq.filter.DestinationMapEntry;
  import org.apache.activemq.network.NetworkBridgeFilterFactory;
  import org.apache.activemq.usage.SystemUsage;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   * Represents an entry in a {@link PolicyMap} for assigning policies to a
   * specific destination or a hierarchical wildcard area of destinations.
   *
   * @org.apache.xbean.XBean
   *
   */
  public class PolicyEntry extends DestinationMapEntry {
  
      private static final Logger LOG = LoggerFactory.getLogger(PolicyEntry.class);
      private DispatchPolicy dispatchPolicy;
      private SubscriptionRecoveryPolicy subscriptionRecoveryPolicy;
      private boolean sendAdvisoryIfNoConsumers;
      private boolean sendDuplicateFromStoreToDLQ = false;
      private DeadLetterStrategy deadLetterStrategy = Destination.DEFAULT_DEAD_LETTER_STRATEGY;
      private PendingMessageLimitStrategy pendingMessageLimitStrategy;
      private MessageEvictionStrategy messageEvictionStrategy;
      private long memoryLimit;
      private String messageGroupMapFactoryType = "cached";
      private MessageGroupMapFactory messageGroupMapFactory;
      private PendingQueueMessageStoragePolicy pendingQueuePolicy;
      private PendingDurableSubscriberMessageStoragePolicy pendingDurableSubscriberPolicy;
      private PendingSubscriberMessageStoragePolicy pendingSubscriberPolicy;
      private int maxProducersToAudit=BaseDestination.MAX_PRODUCERS_TO_AUDIT;
      private int maxAuditDepth=BaseDestination.MAX_AUDIT_DEPTH;
      private int maxQueueAuditDepth=BaseDestination.MAX_AUDIT_DEPTH;
      private boolean enableAudit=true;
      private boolean producerFlowControl = true;
      private boolean alwaysRetroactive = false;
      private long blockedProducerWarningInterval = Destination.DEFAULT_BLOCKED_PRODUCER_WARNING_INTERVAL;
      private boolean optimizedDispatch=false;
      private int maxPageSize=BaseDestination.MAX_PAGE_SIZE;
      private int maxBrowsePageSize=BaseDestination.MAX_BROWSE_PAGE_SIZE;
      private boolean useCache=true;
      private long minimumMessageSize=1024;
      private boolean useConsumerPriority=true;
      private boolean strictOrderDispatch=false;
      private boolean lazyDispatch=false;
      private int timeBeforeDispatchStarts = 0;
      private int consumersBeforeDispatchStarts = 0;
      private boolean advisoryForSlowConsumers;
      private boolean advisoryForFastProducers;
      private boolean advisoryForDiscardingMessages;
      private boolean advisoryWhenFull;
      private boolean advisoryForDelivery;
      private boolean advisoryForConsumed;
      private boolean advisoryForDispatched;
      private boolean includeBodyForAdvisory;
      private long expireMessagesPeriod = BaseDestination.EXPIRE_MESSAGE_PERIOD;
      private int maxExpirePageSize = BaseDestination.MAX_BROWSE_PAGE_SIZE;
      private int queuePrefetch=ActiveMQPrefetchPolicy.DEFAULT_QUEUE_PREFETCH;
      private int queueBrowserPrefetch=ActiveMQPrefetchPolicy.DEFAULT_QUEUE_BROWSER_PREFETCH;
      private int topicPrefetch=ActiveMQPrefetchPolicy.DEFAULT_TOPIC_PREFETCH;
      private int durableTopicPrefetch=ActiveMQPrefetchPolicy.DEFAULT_DURABLE_TOPIC_PREFETCH;
      private boolean usePrefetchExtension = true;
      private int cursorMemoryHighWaterMark = 70;
      private int storeUsageHighWaterMark = 100;
      private SlowConsumerStrategy slowConsumerStrategy;
      private boolean prioritizedMessages;
      private boolean allConsumersExclusiveByDefault;
      private boolean gcInactiveDestinations;
      private boolean gcWithNetworkConsumers;
      private long inactiveTimeoutBeforeGC = BaseDestination.DEFAULT_INACTIVE_TIMEOUT_BEFORE_GC;
      private boolean reduceMemoryFootprint;
      private NetworkBridgeFilterFactory networkBridgeFilterFactory;
      private boolean doOptimzeMessageStorage = true;
      private int maxDestinations = -1;
      private boolean useTopicSubscriptionInflightStats = true;
      private boolean advancedNetworkStatisticsEnabled = false; // [AMQ-9437]
      private boolean advancedMessageStatisticsEnabled = false; // [AMQ-8463]
  
      /*
       * percentage of in-flight messages above which optimize message store is disabled
       */
      private int optimizeMessageStoreInFlightLimit = 10;
      private boolean persistJMSRedelivered = false;
      private int sendFailIfNoSpace = -1;
      private long sendFailIfNoSpaceAfterTimeout = -1;
  
      private MessageInterceptorStrategy messageInterceptorStrategy = null;
  
      public void configure(Broker broker,Queue queue) {
          baseConfiguration(broker,queue);
          if (dispatchPolicy != null) {
              queue.setDispatchPolicy(dispatchPolicy);
          }
          queue.setDeadLetterStrategy(getDeadLetterStrategy());
          queue.setMessageGroupMapFactory(getMessageGroupMapFactory());
          if (memoryLimit > 0) {
              queue.getMemoryUsage().setLimit(memoryLimit);
          }
          if (pendingQueuePolicy != null) {
              PendingMessageCursor messages = pendingQueuePolicy.getQueuePendingMessageCursor(broker,queue);
              queue.setMessages(messages);
          }
  
          queue.setUseConsumerPriority(isUseConsumerPriority());
          queue.setStrictOrderDispatch(isStrictOrderDispatch());
          queue.setOptimizedDispatch(isOptimizedDispatch());
          queue.setLazyDispatch(isLazyDispatch());
          queue.setTimeBeforeDispatchStarts(getTimeBeforeDispatchStarts());
          queue.setConsumersBeforeDispatchStarts(getConsumersBeforeDispatchStarts());
          queue.setAllConsumersExclusiveByDefault(isAllConsumersExclusiveByDefault());
          queue.setPersistJMSRedelivered(isPersistJMSRedelivered());
          queue.setMessageInterceptorStrategy(getMessageInterceptorStrategy());
      }
  
      public void update(Queue queue) {
          update(queue, null);
      }
  
      /**
       * Update a queue with this policy.  Only apply properties that
       * match the includedProperties list.  Not all properties are eligible
       * to be updated.
       *
       * If includedProperties is null then all of the properties will be set as
       * isUpdate will return true
       * @param queue
       * @param includedProperties
       */
      public void update(Queue queue, Set<String> includedProperties) {
          baseUpdate(queue, includedProperties);
          if (isUpdate("memoryLimit", includedProperties) && memoryLimit > 0) {
              queue.getMemoryUsage().setLimit(memoryLimit);
          }
          if (isUpdate("useConsumerPriority", includedProperties)) {
              queue.setUseConsumerPriority(isUseConsumerPriority());
          }
          if (isUpdate("strictOrderDispatch", includedProperties)) {
              queue.setStrictOrderDispatch(isStrictOrderDispatch());
          }
          if (isUpdate("optimizedDispatch", includedProperties)) {
              queue.setOptimizedDispatch(isOptimizedDispatch());
          }
          if (isUpdate("lazyDispatch", includedProperties)) {
              queue.setLazyDispatch(isLazyDispatch());
          }
          if (isUpdate("timeBeforeDispatchStarts", includedProperties)) {
              queue.setTimeBeforeDispatchStarts(getTimeBeforeDispatchStarts());
          }
          if (isUpdate("consumersBeforeDispatchStarts", includedProperties)) {
              queue.setConsumersBeforeDispatchStarts(getConsumersBeforeDispatchStarts());
          }
          if (isUpdate("allConsumersExclusiveByDefault", includedProperties)) {
              queue.setAllConsumersExclusiveByDefault(isAllConsumersExclusiveByDefault());
          }
          if (isUpdate("persistJMSRedelivered", includedProperties)) {
              queue.setPersistJMSRedelivered(isPersistJMSRedelivered());
          }
      }
  
      public void configure(Broker broker,Topic topic) {
          baseConfiguration(broker,topic);
          if (dispatchPolicy != null) {
              topic.setDispatchPolicy(dispatchPolicy);
          }
          topic.setDeadLetterStrategy(getDeadLetterStrategy());
          if (subscriptionRecoveryPolicy != null) {
              SubscriptionRecoveryPolicy srp = subscriptionRecoveryPolicy.copy();
              srp.setBroker(broker);
              topic.setSubscriptionRecoveryPolicy(srp);
          }
          if (memoryLimit > 0) {
              topic.getMemoryUsage().setLimit(memoryLimit);
          }
          topic.setLazyDispatch(isLazyDispatch());
          topic.setMessageInterceptorStrategy(getMessageInterceptorStrategy());
      }
  
      public void update(Topic topic) {
          update(topic, null);
      }
  
      //If includedProperties is null then all of the properties will be set as
      //isUpdate will return true
      public void update(Topic topic, Set<String> includedProperties) {
          baseUpdate(topic, includedProperties);
          if (isUpdate("memoryLimit", includedProperties) && memoryLimit > 0) {
              topic.getMemoryUsage().setLimit(memoryLimit);
          }
          if (isUpdate("lazyDispatch", includedProperties)) {
              topic.setLazyDispatch(isLazyDispatch());
          }
      }
  
      // attributes that can change on the fly
      public void baseUpdate(BaseDestination destination) {
          baseUpdate(destination, null);
      }
  
      // attributes that can change on the fly
      //If includedProperties is null then all of the properties will be set as
      //isUpdate will return true
      public void baseUpdate(BaseDestination destination, Set<String> includedProperties) {
          if (isUpdate("producerFlowControl", includedProperties)) {
              destination.setProducerFlowControl(isProducerFlowControl());
          }
          if (isUpdate("alwaysRetroactive", includedProperties)) {
              destination.setAlwaysRetroactive(isAlwaysRetroactive());
          }
          if (isUpdate("blockedProducerWarningInterval", includedProperties)) {
              destination.setBlockedProducerWarningInterval(getBlockedProducerWarningInterval());
          }
          if (isUpdate("maxPageSize", includedProperties)) {
              destination.setMaxPageSize(getMaxPageSize());
          }
          if (isUpdate("maxBrowsePageSize", includedProperties)) {
              destination.setMaxBrowsePageSize(getMaxBrowsePageSize());
          }
          if (isUpdate("minimumMessageSize", includedProperties)) {
              destination.setMinimumMessageSize((int) getMinimumMessageSize());
          }
          if (isUpdate("maxExpirePageSize", includedProperties)) {
              destination.setMaxExpirePageSize(getMaxExpirePageSize());
          }
          if (isUpdate("cursorMemoryHighWaterMark", includedProperties)) {
              destination.setCursorMemoryHighWaterMark(getCursorMemoryHighWaterMark());
          }
          if (isUpdate("storeUsageHighWaterMark", includedProperties)) {
              destination.setStoreUsageHighWaterMark(getStoreUsageHighWaterMark());
          }
          if (isUpdate("gcInactiveDestinations", includedProperties)) {
              destination.setGcIfInactive(isGcInactiveDestinations());
          }
          if (isUpdate("gcWithNetworkConsumers", includedProperties)) {
              destination.setGcWithNetworkConsumers(isGcWithNetworkConsumers());
          }
          if (isUpdate("inactiveTimeoutBeforeGc", includedProperties)) {
              destination.setInactiveTimeoutBeforeGC(getInactiveTimeoutBeforeGC());
          }
          if (isUpdate("reduceMemoryFootprint", includedProperties)) {
              destination.setReduceMemoryFootprint(isReduceMemoryFootprint());
          }
          if (isUpdate("doOptimizeMessageStore", includedProperties)) {
              destination.setDoOptimzeMessageStorage(isDoOptimzeMessageStorage());
          }
          if (isUpdate("optimizeMessageStoreInFlightLimit", includedProperties)) {
              destination.setOptimizeMessageStoreInFlightLimit(getOptimizeMessageStoreInFlightLimit());
          }
          if (isUpdate("advisoryForConsumed", includedProperties)) {
              destination.setAdvisoryForConsumed(isAdvisoryForConsumed());
          }
          if (isUpdate("advisoryForDispatched", includedProperties)) {
              destination.setAdvisoryForDispatched(isAdvisoryForDispatched());
          }
          if (isUpdate("advisoryForDelivery", includedProperties)) {
              destination.setAdvisoryForDelivery(isAdvisoryForDelivery());
          }
          if (isUpdate("advisoryForDiscardingMessages", includedProperties)) {
              destination.setAdvisoryForDiscardingMessages(isAdvisoryForDiscardingMessages());
          }
          if (isUpdate("advisoryForSlowConsumers", includedProperties)) {
              destination.setAdvisoryForSlowConsumers(isAdvisoryForSlowConsumers());
          }
          if (isUpdate("advisoryForFastProducers", includedProperties)) {
              destination.setAdvisoryForFastProducers(isAdvisoryForFastProducers());
          }
          if (isUpdate("advisoryWhenFull", includedProperties)) {
              destination.setAdvisoryWhenFull(isAdvisoryWhenFull());
          }
          if (isUpdate("includeBodyForAdvisory", includedProperties)) {
              destination.setIncludeBodyForAdvisory(isIncludeBodyForAdvisory());
          }
          if (isUpdate("sendAdvisoryIfNoConsumers", includedProperties)) {
              destination.setSendAdvisoryIfNoConsumers(isSendAdvisoryIfNoConsumers());
          }
          if (isUpdate("sendDuplicateFromStoreToDLQ", includedProperties)) {
              destination.setSendDuplicateFromStoreToDLQ(isSendDuplicateFromStoreToDLQ());
          }
          if (isUpdate("advancedNetworkStatisticsEnabled", includedProperties)) {
              destination.setAdvancedNetworkStatisticsEnabled(isAdvancedNetworkStatisticsEnabled());
          }
          if (isUpdate("advancedMessageStatisticsEnabled", includedProperties)) {
              destination.setAdvancedMessageStatisticsEnabled(isAdvancedMessageStatisticsEnabled());
          }
      }
  
      public void baseConfiguration(Broker broker, BaseDestination destination) {
          baseUpdate(destination);
          destination.setEnableAudit(isEnableAudit());
          destination.setMaxAuditDepth(getMaxQueueAuditDepth());
          destination.setMaxProducersToAudit(getMaxProducersToAudit());
          destination.setUseCache(isUseCache());
          destination.setExpireMessagesPeriod(getExpireMessagesPeriod());
          SlowConsumerStrategy scs = getSlowConsumerStrategy();
          if (scs != null) {
              scs.setBrokerService(broker);
              scs.addDestination(destination);
          }
          destination.setSlowConsumerStrategy(scs);
          destination.setPrioritizedMessages(isPrioritizedMessages());
          if (sendFailIfNoSpace != -1) {
              destination.getSystemUsage().setSendFailIfNoSpace(isSendFailIfNoSpace());
          }
          if (sendFailIfNoSpaceAfterTimeout != -1) {
              destination.getSystemUsage().setSendFailIfNoSpaceAfterTimeout(getSendFailIfNoSpaceAfterTimeout());
          }
      }
  
      public void configure(Broker broker, SystemUsage memoryManager, TopicSubscription subscription) {
          configurePrefetch(subscription);
          subscription.setUsePrefetchExtension(isUsePrefetchExtension());
          subscription.setCursorMemoryHighWaterMark(getCursorMemoryHighWaterMark());
          subscription.setUseTopicSubscriptionInflightStats(isUseTopicSubscriptionInflightStats());
          if (pendingMessageLimitStrategy != null) {
              int value = pendingMessageLimitStrategy.getMaximumPendingMessageLimit(subscription);
              int consumerLimit = subscription.getInfo().getMaximumPendingMessageLimit();
              if (consumerLimit > 0) {
                  if (value < 0 || consumerLimit < value) {
                      value = consumerLimit;
                  }
              }
              if (value >= 0) {
                  LOG.debug("Setting the maximumPendingMessages size to: {} for consumer: {}", value, subscription.getInfo().getConsumerId());
                  subscription.setMaximumPendingMessages(value);
              }
          }
          if (messageEvictionStrategy != null) {
              subscription.setMessageEvictionStrategy(messageEvictionStrategy);
          }
          if (pendingSubscriberPolicy != null) {
              String name = subscription.getContext().getClientId() + "_" + subscription.getConsumerInfo().getConsumerId();
              int maxBatchSize = subscription.getConsumerInfo().getPrefetchSize();
              subscription.setMatched(pendingSubscriberPolicy.getSubscriberPendingMessageCursor(broker,name, maxBatchSize,subscription));
          }
          if (enableAudit) {
              subscription.setEnableAudit(enableAudit);
              subscription.setMaxProducersToAudit(maxProducersToAudit);
              subscription.setMaxAuditDepth(maxAuditDepth);
          }
      }
  
      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());
      }
  
      public void configure(Broker broker, SystemUsage memoryManager, QueueBrowserSubscription sub) {
          configurePrefetch(sub);
          sub.setCursorMemoryHighWaterMark(getCursorMemoryHighWaterMark());
          sub.setUsePrefetchExtension(isUsePrefetchExtension());
  
          // TODO
          // We currently need an infinite audit because of the way that browser dispatch
          // is done.  We should refactor the browsers to better handle message dispatch so
          // we can remove this and perform a more efficient dispatch.
          sub.setMaxProducersToAudit(Integer.MAX_VALUE);
          sub.setMaxAuditDepth(Short.MAX_VALUE);
  
          // part solution - dispatching to browsers needs to be restricted
          sub.setMaxMessages(getMaxBrowsePageSize());
      }
  
      public void configure(Broker broker, SystemUsage memoryManager, QueueSubscription sub) {
          configurePrefetch(sub);
          sub.setCursorMemoryHighWaterMark(getCursorMemoryHighWaterMark());
          sub.setUsePrefetchExtension(isUsePrefetchExtension());
          sub.setMaxProducersToAudit(getMaxProducersToAudit());
      }
  
      public void configurePrefetch(Subscription subscription) {
  
          final int currentPrefetch = subscription.getConsumerInfo().getPrefetchSize();
          if (subscription instanceof QueueBrowserSubscription) {
              if (currentPrefetch == ActiveMQPrefetchPolicy.DEFAULT_QUEUE_BROWSER_PREFETCH) {
                  ((QueueBrowserSubscription) subscription).setPrefetchSize(getQueueBrowserPrefetch());
              }
          } else if (subscription instanceof QueueSubscription) {
              if (currentPrefetch == ActiveMQPrefetchPolicy.DEFAULT_QUEUE_PREFETCH) {
                  ((QueueSubscription) subscription).setPrefetchSize(getQueuePrefetch());
              }
          } else if (subscription instanceof DurableTopicSubscription) {
              if (currentPrefetch == ActiveMQPrefetchPolicy.DEFAULT_DURABLE_TOPIC_PREFETCH ||
                      subscription.getConsumerInfo().getPrefetchSize() == ActiveMQPrefetchPolicy.DEFAULT_OPTIMIZE_DURABLE_TOPIC_PREFETCH) {
                  ((DurableTopicSubscription)subscription).setPrefetchSize(getDurableTopicPrefetch());
              }
          } else if (subscription instanceof TopicSubscription) {
              if (currentPrefetch == ActiveMQPrefetchPolicy.DEFAULT_TOPIC_PREFETCH) {
                  ((TopicSubscription) subscription).setPrefetchSize(getTopicPrefetch());
              }
          }
          if (currentPrefetch != 0 && subscription.getPrefetchSize() == 0) {
              // tell the sub so that it can issue a pull request
              subscription.updateConsumerPrefetch(0);
          }
      }
  
      private boolean isUpdate(String property, Set<String> includedProperties) {
          return includedProperties == null || includedProperties.contains(property);
      }
      // Properties
      // -------------------------------------------------------------------------
      public DispatchPolicy getDispatchPolicy() {
          return dispatchPolicy;
      }
  
      public void setDispatchPolicy(DispatchPolicy policy) {
          this.dispatchPolicy = policy;
      }
  
      public SubscriptionRecoveryPolicy getSubscriptionRecoveryPolicy() {
          return subscriptionRecoveryPolicy;
      }
  
      public void setSubscriptionRecoveryPolicy(SubscriptionRecoveryPolicy subscriptionRecoveryPolicy) {
          this.subscriptionRecoveryPolicy = subscriptionRecoveryPolicy;
      }
  
      public boolean isSendAdvisoryIfNoConsumers() {
          return sendAdvisoryIfNoConsumers;
      }
  
      /**
       * Sends an advisory message if a non-persistent message is sent and there
       * are no active consumers
       */
      public void setSendAdvisoryIfNoConsumers(boolean sendAdvisoryIfNoConsumers) {
          this.sendAdvisoryIfNoConsumers = sendAdvisoryIfNoConsumers;
      }
  
      public boolean isSendDuplicateFromStoreToDLQ() {
          return sendDuplicateFromStoreToDLQ;
      }
  
      /**
       * Sends a copy of message to DLQ if a duplicate messages are paged-in from
       * the messages store
       */
      public void setSendDuplicateFromStoreToDLQ(boolean sendDuplicateFromStoreToDLQ) {
          this.sendDuplicateFromStoreToDLQ = sendDuplicateFromStoreToDLQ;
      }
  
      public DeadLetterStrategy getDeadLetterStrategy() {
          return deadLetterStrategy;
      }
  
      /**
       * Sets the policy used to determine which dead letter queue destination
       * should be used
       */
      public void setDeadLetterStrategy(DeadLetterStrategy deadLetterStrategy) {
          this.deadLetterStrategy = deadLetterStrategy;
      }
  
      public PendingMessageLimitStrategy getPendingMessageLimitStrategy() {
          return pendingMessageLimitStrategy;
      }
  
      /**
       * Sets the strategy to calculate the maximum number of messages that are
       * allowed to be pending on consumers (in addition to their prefetch sizes).
       * Once the limit is reached, non-durable topics can then start discarding
       * old messages. This allows us to keep dispatching messages to slow
       * consumers while not blocking fast consumers and discarding the messages
       * oldest first.
       */
      public void setPendingMessageLimitStrategy(PendingMessageLimitStrategy pendingMessageLimitStrategy) {
          this.pendingMessageLimitStrategy = pendingMessageLimitStrategy;
      }
  
      public MessageEvictionStrategy getMessageEvictionStrategy() {
          return messageEvictionStrategy;
      }
  
      /**
       * Sets the eviction strategy used to decide which message to evict when the
       * slow consumer needs to discard messages
       */
      public void setMessageEvictionStrategy(MessageEvictionStrategy messageEvictionStrategy) {
          this.messageEvictionStrategy = messageEvictionStrategy;
      }
  
      public long getMemoryLimit() {
          return memoryLimit;
      }
  
      /**
       * When set using Xbean, values of the form "20 Mb", "1024kb", and "1g" can be used
       * @org.apache.xbean.Property propertyEditor="org.apache.activemq.util.MemoryPropertyEditor"
       */
      public void setMemoryLimit(long memoryLimit) {
          this.memoryLimit = memoryLimit;
      }
  
      public MessageGroupMapFactory getMessageGroupMapFactory() {
          if (messageGroupMapFactory == null) {
              try {
              messageGroupMapFactory = GroupFactoryFinder.createMessageGroupMapFactory(getMessageGroupMapFactoryType());
              }catch(Exception e){
                  LOG.error("Failed to create message group Factory ",e);
              }
          }
          return messageGroupMapFactory;
      }
  
      /**
       * Sets the factory used to create new instances of {MessageGroupMap} used
       * to implement the <a
       * href="http://activemq.apache.org/message-groups.html">Message Groups</a>
       * functionality.
       */
      public void setMessageGroupMapFactory(MessageGroupMapFactory messageGroupMapFactory) {
          this.messageGroupMapFactory = messageGroupMapFactory;
      }
  
  
      public String getMessageGroupMapFactoryType() {
          return messageGroupMapFactoryType;
      }
  
      public void setMessageGroupMapFactoryType(String messageGroupMapFactoryType) {
          this.messageGroupMapFactoryType = messageGroupMapFactoryType;
      }
  
  
      /**
       * @return the pendingDurableSubscriberPolicy
       */
      public PendingDurableSubscriberMessageStoragePolicy getPendingDurableSubscriberPolicy() {
          return this.pendingDurableSubscriberPolicy;
      }
  
      /**
       * @param pendingDurableSubscriberPolicy the pendingDurableSubscriberPolicy
       *                to set
       */
      public void setPendingDurableSubscriberPolicy(PendingDurableSubscriberMessageStoragePolicy pendingDurableSubscriberPolicy) {
          this.pendingDurableSubscriberPolicy = pendingDurableSubscriberPolicy;
      }
  
      /**
       * @return the pendingQueuePolicy
       */
      public PendingQueueMessageStoragePolicy getPendingQueuePolicy() {
          return this.pendingQueuePolicy;
      }
  
      /**
       * @param pendingQueuePolicy the pendingQueuePolicy to set
       */
      public void setPendingQueuePolicy(PendingQueueMessageStoragePolicy pendingQueuePolicy) {
          this.pendingQueuePolicy = pendingQueuePolicy;
      }
  
      /**
       * @return the pendingSubscriberPolicy
       */
      public PendingSubscriberMessageStoragePolicy getPendingSubscriberPolicy() {
          return this.pendingSubscriberPolicy;
      }
  
      /**
       * @param pendingSubscriberPolicy the pendingSubscriberPolicy to set
       */
      public void setPendingSubscriberPolicy(PendingSubscriberMessageStoragePolicy pendingSubscriberPolicy) {
          this.pendingSubscriberPolicy = pendingSubscriberPolicy;
      }
  
      /**
       * @return true if producer flow control enabled
       */
      public boolean isProducerFlowControl() {
          return producerFlowControl;
      }
  
      /**
       * @param producerFlowControl
       */
      public void setProducerFlowControl(boolean producerFlowControl) {
          this.producerFlowControl = producerFlowControl;
      }
  
      /**
       * @return true if topic is always retroactive
       */
      public boolean isAlwaysRetroactive() {
          return alwaysRetroactive;
      }
  
      /**
       * @param alwaysRetroactive
       */
      public void setAlwaysRetroactive(boolean alwaysRetroactive) {
          this.alwaysRetroactive = alwaysRetroactive;
      }
  
  
      /**
       * Set's the interval at which warnings about producers being blocked by
       * resource usage will be triggered. Values of 0 or less will disable
       * warnings
       *
       * @param blockedProducerWarningInterval the interval at which warning about
       *            blocked producers will be triggered.
       */
      public void setBlockedProducerWarningInterval(long blockedProducerWarningInterval) {
          this.blockedProducerWarningInterval = blockedProducerWarningInterval;
      }
  
      /**
       *
       * @return the interval at which warning about blocked producers will be
       *         triggered.
       */
      public long getBlockedProducerWarningInterval() {
          return blockedProducerWarningInterval;
      }
  
      /**
       * @return the maxProducersToAudit
       */
      public int getMaxProducersToAudit() {
          return maxProducersToAudit;
      }
  
      /**
       * @param maxProducersToAudit the maxProducersToAudit to set
       */
      public void setMaxProducersToAudit(int maxProducersToAudit) {
          this.maxProducersToAudit = maxProducersToAudit;
      }
  
      /**
       * @return the maxAuditDepth
       */
      public int getMaxAuditDepth() {
          return maxAuditDepth;
      }
  
      /**
       * @param maxAuditDepth the maxAuditDepth to set
       */
      public void setMaxAuditDepth(int maxAuditDepth) {
          this.maxAuditDepth = maxAuditDepth;
      }
  
      /**
       * @return the enableAudit
       */
      public boolean isEnableAudit() {
          return enableAudit;
      }
  
      /**
       * @param enableAudit the enableAudit to set
       */
      public void setEnableAudit(boolean enableAudit) {
          this.enableAudit = enableAudit;
      }
  
      public int getMaxQueueAuditDepth() {
          return maxQueueAuditDepth;
      }
  
      public void setMaxQueueAuditDepth(int maxQueueAuditDepth) {
          this.maxQueueAuditDepth = maxQueueAuditDepth;
      }
  
      public boolean isOptimizedDispatch() {
          return optimizedDispatch;
      }
  
      public void setOptimizedDispatch(boolean optimizedDispatch) {
          this.optimizedDispatch = optimizedDispatch;
      }
  
      public int getMaxPageSize() {
          return maxPageSize;
      }
  
      public void setMaxPageSize(int maxPageSize) {
          this.maxPageSize = maxPageSize;
      }
  
      public int getMaxBrowsePageSize() {
          return maxBrowsePageSize;
      }
  
      public void setMaxBrowsePageSize(int maxPageSize) {
          this.maxBrowsePageSize = maxPageSize;
      }
  
      public boolean isUseCache() {
          return useCache;
      }
  
      public void setUseCache(boolean useCache) {
          this.useCache = useCache;
      }
  
      public long getMinimumMessageSize() {
          return minimumMessageSize;
      }
  
      public void setMinimumMessageSize(long minimumMessageSize) {
          this.minimumMessageSize = minimumMessageSize;
      }
  
      public boolean isUseConsumerPriority() {
          return useConsumerPriority;
      }
  
      public void setUseConsumerPriority(boolean useConsumerPriority) {
          this.useConsumerPriority = useConsumerPriority;
      }
  
      public boolean isStrictOrderDispatch() {
          return strictOrderDispatch;
      }
  
      public void setStrictOrderDispatch(boolean strictOrderDispatch) {
          this.strictOrderDispatch = strictOrderDispatch;
      }
  
      public boolean isLazyDispatch() {
          return lazyDispatch;
      }
  
      public void setLazyDispatch(boolean lazyDispatch) {
          this.lazyDispatch = lazyDispatch;
      }
  
      public int getTimeBeforeDispatchStarts() {
          return timeBeforeDispatchStarts;
      }
  
      public void setTimeBeforeDispatchStarts(int timeBeforeDispatchStarts) {
          this.timeBeforeDispatchStarts = timeBeforeDispatchStarts;
      }
  
      public int getConsumersBeforeDispatchStarts() {
          return consumersBeforeDispatchStarts;
      }
  
      public void setConsumersBeforeDispatchStarts(int consumersBeforeDispatchStarts) {
          this.consumersBeforeDispatchStarts = consumersBeforeDispatchStarts;
      }
  
      /**
       * @return the advisoryForSlowConsumers
       */
      public boolean isAdvisoryForSlowConsumers() {
          return advisoryForSlowConsumers;
      }
  
      /**
       * @param advisoryForSlowConsumers the advisoryForSlowConsumers to set
       */
      public void setAdvisoryForSlowConsumers(boolean advisoryForSlowConsumers) {
          this.advisoryForSlowConsumers = advisoryForSlowConsumers;
      }
  
      /**
       * @return the advisoryForDiscardingMessages
       */
      public boolean isAdvisoryForDiscardingMessages() {
          return advisoryForDiscardingMessages;
      }
  
      /**
       * @param advisoryForDiscardingMessages the advisoryForDiscardingMessages to set
       */
      public void setAdvisoryForDiscardingMessages(
              boolean advisoryForDiscardingMessages) {
          this.advisoryForDiscardingMessages = advisoryForDiscardingMessages;
      }
  
      /**
       * @return the advisoryWhenFull
       */
      public boolean isAdvisoryWhenFull() {
          return advisoryWhenFull;
      }
  
      /**
       * @param advisoryWhenFull the advisoryWhenFull to set
       */
      public void setAdvisoryWhenFull(boolean advisoryWhenFull) {
          this.advisoryWhenFull = advisoryWhenFull;
      }
  
      /**
       * @return the advisoryForDelivery
       */
      public boolean isAdvisoryForDelivery() {
          return advisoryForDelivery;
      }
  
      /**
       * @param advisoryForDelivery the advisoryForDelivery to set
       */
      public void setAdvisoryForDelivery(boolean advisoryForDelivery) {
          this.advisoryForDelivery = advisoryForDelivery;
      }
  
      /**
       * @return the advisoryForConsumed
       */
      public boolean isAdvisoryForConsumed() {
          return advisoryForConsumed;
      }
  
      /**
       * @param advisoryForConsumed the advisoryForConsumed to set
       */
      public void setAdvisoryForConsumed(boolean advisoryForConsumed) {
          this.advisoryForConsumed = advisoryForConsumed;
      }
  
      public boolean isAdvisoryForDispatched() {
          return advisoryForDispatched;
      }
  
      public void setAdvisoryForDispatched(boolean advisoryForDispatched) {
          this.advisoryForDispatched = advisoryForDispatched;
      }
  
      /**
       * @return the advisdoryForFastProducers
       */
      public boolean isAdvisoryForFastProducers() {
          return advisoryForFastProducers;
      }
  
      /**
       * @param advisoryForFastProducers the advisdoryForFastProducers to set
       */
      public void setAdvisoryForFastProducers(boolean advisoryForFastProducers) {
          this.advisoryForFastProducers = advisoryForFastProducers;
      }
  
      /**
       * Returns true if the original message body should be included when applicable
       * for advisory messages
       *
       * @return
       */
      public boolean isIncludeBodyForAdvisory() {
          return includeBodyForAdvisory;
      }
  
      /**
       * Sets if the original message body should be included when applicable
       * for advisory messages
       *
       * @param includeBodyForAdvisory
       */
      public void setIncludeBodyForAdvisory(boolean includeBodyForAdvisory) {
          this.includeBodyForAdvisory = includeBodyForAdvisory;
      }
  
      public void setMaxExpirePageSize(int maxExpirePageSize) {
          this.maxExpirePageSize = maxExpirePageSize;
      }
  
      public int getMaxExpirePageSize() {
          return maxExpirePageSize;
      }
  
      public void setExpireMessagesPeriod(long expireMessagesPeriod) {
          this.expireMessagesPeriod = expireMessagesPeriod;
      }
  
      public long getExpireMessagesPeriod() {
          return expireMessagesPeriod;
      }
  
      /**
       * Get the queuePrefetch
       * @return the queuePrefetch
       */
      public int getQueuePrefetch() {
          return this.queuePrefetch;
      }
  
      /**
       * Set the queuePrefetch
       * @param queuePrefetch the queuePrefetch to set
       */
      public void setQueuePrefetch(int queuePrefetch) {
          this.queuePrefetch = queuePrefetch;
      }
  
      /**
       * Get the queueBrowserPrefetch
       * @return the queueBrowserPrefetch
       */
      public int getQueueBrowserPrefetch() {
          return this.queueBrowserPrefetch;
      }
  
      /**
       * Set the queueBrowserPrefetch
       * @param queueBrowserPrefetch the queueBrowserPrefetch to set
       */
      public void setQueueBrowserPrefetch(int queueBrowserPrefetch) {
          this.queueBrowserPrefetch = queueBrowserPrefetch;
      }
  
      /**
       * Get the topicPrefetch
       * @return the topicPrefetch
       */
      public int getTopicPrefetch() {
          return this.topicPrefetch;
      }
  
      /**
       * Set the topicPrefetch
       * @param topicPrefetch the topicPrefetch to set
       */
      public void setTopicPrefetch(int topicPrefetch) {
          this.topicPrefetch = topicPrefetch;
      }
  
      /**
       * Get the durableTopicPrefetch
       * @return the durableTopicPrefetch
       */
      public int getDurableTopicPrefetch() {
          return this.durableTopicPrefetch;
      }
  
      /**
       * Set the durableTopicPrefetch
       * @param durableTopicPrefetch the durableTopicPrefetch to set
       */
      public void setDurableTopicPrefetch(int durableTopicPrefetch) {
          this.durableTopicPrefetch = durableTopicPrefetch;
      }
  
      public boolean isUsePrefetchExtension() {
          return this.usePrefetchExtension;
      }
  
      public void setUsePrefetchExtension(boolean usePrefetchExtension) {
          this.usePrefetchExtension = usePrefetchExtension;
      }
  
      public int getCursorMemoryHighWaterMark() {
          return this.cursorMemoryHighWaterMark;
      }
  
      public void setCursorMemoryHighWaterMark(int cursorMemoryHighWaterMark) {
          this.cursorMemoryHighWaterMark = cursorMemoryHighWaterMark;
      }
  
      public void setStoreUsageHighWaterMark(int storeUsageHighWaterMark) {
          this.storeUsageHighWaterMark = storeUsageHighWaterMark;
      }
  
      public int getStoreUsageHighWaterMark() {
          return storeUsageHighWaterMark;
      }
  
      public void setSlowConsumerStrategy(SlowConsumerStrategy slowConsumerStrategy) {
          this.slowConsumerStrategy = slowConsumerStrategy;
      }
  
      public SlowConsumerStrategy getSlowConsumerStrategy() {
          return this.slowConsumerStrategy;
      }
  
  
      public boolean isPrioritizedMessages() {
          return this.prioritizedMessages;
      }
  
      public void setPrioritizedMessages(boolean prioritizedMessages) {
          this.prioritizedMessages = prioritizedMessages;
      }
  
      public void setAllConsumersExclusiveByDefault(boolean allConsumersExclusiveByDefault) {
          this.allConsumersExclusiveByDefault = allConsumersExclusiveByDefault;
      }
  
      public boolean isAllConsumersExclusiveByDefault() {
          return allConsumersExclusiveByDefault;
      }
  
      public boolean isGcInactiveDestinations() {
          return this.gcInactiveDestinations;
      }
  
      public void setGcInactiveDestinations(boolean gcInactiveDestinations) {
          this.gcInactiveDestinations = gcInactiveDestinations;
      }
  
      /**
       * @return the amount of time spent inactive before GC of the destination kicks in.
       *
       * @deprecated use {@link #getInactiveTimeoutBeforeGC} instead.
       */
      @Deprecated
      public long getInactiveTimoutBeforeGC() {
          return getInactiveTimeoutBeforeGC();
      }
  
      /**
       * Sets the amount of time a destination is inactive before it is marked for GC
       *
       * @param inactiveTimoutBeforeGC
       *        time in milliseconds to configure as the inactive timeout.
       *
       * @deprecated use {@link #setInactiveTimeoutBeforeGC} instead.
       */
      @Deprecated
      public void setInactiveTimoutBeforeGC(long inactiveTimoutBeforeGC) {
          setInactiveTimeoutBeforeGC(inactiveTimoutBeforeGC);
      }
  
      /**
       * @return the amount of time spent inactive before GC of the destination kicks in.
       */
      public long getInactiveTimeoutBeforeGC() {
          return this.inactiveTimeoutBeforeGC;
      }
  
      /**
       * Sets the amount of time a destination is inactive before it is marked for GC
       *
       * @param inactiveTimeoutBeforeGC
       *        time in milliseconds to configure as the inactive timeout.
       */
      public void setInactiveTimeoutBeforeGC(long inactiveTimeoutBeforeGC) {
          this.inactiveTimeoutBeforeGC = inactiveTimeoutBeforeGC;
      }
  
      public void setGcWithNetworkConsumers(boolean gcWithNetworkConsumers) {
          this.gcWithNetworkConsumers = gcWithNetworkConsumers;
      }
  
      public boolean isGcWithNetworkConsumers() {
          return gcWithNetworkConsumers;
      }
  
      public boolean isReduceMemoryFootprint() {
          return reduceMemoryFootprint;
      }
  
      public void setReduceMemoryFootprint(boolean reduceMemoryFootprint) {
          this.reduceMemoryFootprint = reduceMemoryFootprint;
      }
  
      public void setNetworkBridgeFilterFactory(NetworkBridgeFilterFactory networkBridgeFilterFactory) {
          this.networkBridgeFilterFactory = networkBridgeFilterFactory;
      }
  
      public NetworkBridgeFilterFactory getNetworkBridgeFilterFactory() {
          return networkBridgeFilterFactory;
      }
  
      public boolean isDoOptimzeMessageStorage() {
          return doOptimzeMessageStorage;
      }
  
      public void setDoOptimzeMessageStorage(boolean doOptimzeMessageStorage) {
          this.doOptimzeMessageStorage = doOptimzeMessageStorage;
      }
  
      public int getOptimizeMessageStoreInFlightLimit() {
          return optimizeMessageStoreInFlightLimit;
      }
  
      public void setOptimizeMessageStoreInFlightLimit(int optimizeMessageStoreInFlightLimit) {
          this.optimizeMessageStoreInFlightLimit = optimizeMessageStoreInFlightLimit;
      }
  
      public void setPersistJMSRedelivered(boolean val) {
          this.persistJMSRedelivered = val;
      }
  
      public boolean isPersistJMSRedelivered() {
          return persistJMSRedelivered;
      }
  
      public int getMaxDestinations() {
          return maxDestinations;
      }
  
      /**
       * Sets the maximum number of destinations that can be created
       *
       * @param maxDestinations
       *            maximum number of destinations
       */
      public void setMaxDestinations(int maxDestinations) {
          this.maxDestinations = maxDestinations;
      }
  
      @Override
      public String toString() {
          return "PolicyEntry [" + destination + "]";
      }
  
      public void setSendFailIfNoSpace(boolean val) {
          if (val) {
              this.sendFailIfNoSpace = 1;
          } else {
              this.sendFailIfNoSpace = 0;
          }
      }
  
      public boolean isSendFailIfNoSpace() {
          return sendFailIfNoSpace == 1;
      }
  
      public void setSendFailIfNoSpaceAfterTimeout(long sendFailIfNoSpaceAfterTimeout) {
          this.sendFailIfNoSpaceAfterTimeout = sendFailIfNoSpaceAfterTimeout;
      }
  
      public long getSendFailIfNoSpaceAfterTimeout() {
          return this.sendFailIfNoSpaceAfterTimeout;
      }
  
      public boolean isUseTopicSubscriptionInflightStats() {
          return useTopicSubscriptionInflightStats;
      }
  
      public void setUseTopicSubscriptionInflightStats(boolean useTopicSubscriptionInflightStats) {
          this.useTopicSubscriptionInflightStats = useTopicSubscriptionInflightStats;
      }
  
      public void setMessageInterceptorStrategy(MessageInterceptorStrategy messageInterceptorStrategy) {
          this.messageInterceptorStrategy = messageInterceptorStrategy;
      }
  
      public MessageInterceptorStrategy getMessageInterceptorStrategy() {
          return this.messageInterceptorStrategy;
      } 
  
      public boolean isAdvancedNetworkStatisticsEnabled() {
          return this.advancedNetworkStatisticsEnabled;
      }
  
      public void setAdvancedNetworkStatisticsEnabled(boolean advancedNetworkStatisticsEnabled) {
          this.advancedNetworkStatisticsEnabled = advancedNetworkStatisticsEnabled;
      }
  
      public boolean isAdvancedMessageStatisticsEnabled() {
          return this.advancedMessageStatisticsEnabled;
      }
  
      public void setAdvancedMessageStatisticsEnabled(boolean advancedMessageStatisticsEnabled) {
          this.advancedMessageStatisticsEnabled = advancedMessageStatisticsEnabled;
      }
  }
  