You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2019/08/08 18:37:32 UTC

[activemq-artemis] branch master updated: ARTEMIS-2449 limit size of producer details

This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/master by this push:
     new 9d44c40  ARTEMIS-2449 limit size of producer details
     new 3ed455c  This closes #2790
9d44c40 is described below

commit 9d44c40037cf299e77e19993a5dbd422fcff16e9
Author: Justin Bertram <jb...@apache.org>
AuthorDate: Thu Aug 8 11:06:07 2019 -0500

    ARTEMIS-2449 limit size of producer details
    
    The core server session tracks details about producers like what
    addresses have had messages sent to them, the most recent message ID
    sent to each address, and the number of messages sent to each address.
    This information is made available to users via the
    listProducersInfoAsJSON method on the various management interfaces
    (JMX, web console, etc.). However, in situations where a server session
    is long lived (e.g. in a pool) and is used to send to many different
    addresses (e.g. randomly named temporary JMS queues) this info can
    accumulate to a problematic degree. Therefore, we should limit the
    amount of producer details saved by the session.
---
 .../artemis/utils/collections/MaxSizeMap.java      | 34 ++++++++++++++++++++++
 .../core/server/impl/ServerSessionImpl.java        |  3 +-
 .../jms/client/TemporaryDestinationTest.java       | 20 +++++++++++++
 3 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/collections/MaxSizeMap.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/collections/MaxSizeMap.java
new file mode 100644
index 0000000..0c78638
--- /dev/null
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/collections/MaxSizeMap.java
@@ -0,0 +1,34 @@
+/**
+ * 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.utils.collections;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class MaxSizeMap<K, V> extends LinkedHashMap<K, V> {
+   private final int maxSize;
+
+   public MaxSizeMap(int maxSize) {
+      this.maxSize = maxSize;
+   }
+
+   @Override
+   protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+      return size() > maxSize;
+   }
+}
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
index c442e71..9044302 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
@@ -95,6 +95,7 @@ import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
 import org.apache.activemq.artemis.utils.CompositeAddress;
 import org.apache.activemq.artemis.utils.JsonLoader;
 import org.apache.activemq.artemis.utils.PrefixUtil;
+import org.apache.activemq.artemis.utils.collections.MaxSizeMap;
 import org.apache.activemq.artemis.utils.collections.TypedProperties;
 import org.jboss.logging.Logger;
 
@@ -175,7 +176,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
    private final OperationContext context;
 
    // Session's usage should be by definition single threaded, hence it's not needed to use a concurrentHashMap here
-   protected final Map<SimpleString, Pair<Object, AtomicLong>> targetAddressInfos = new HashMap<>();
+   protected final Map<SimpleString, Pair<Object, AtomicLong>> targetAddressInfos = new MaxSizeMap<>(100);
 
    private final long creationTime = System.currentTimeMillis();
 
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/TemporaryDestinationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/TemporaryDestinationTest.java
index 260b1f5..01cde63 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/TemporaryDestinationTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/TemporaryDestinationTest.java
@@ -247,6 +247,26 @@ public class TemporaryDestinationTest extends JMSTestBase {
    }
 
    @Test
+   public void testForTempQueueTargetInfosSizeLimit() throws Exception {
+      try {
+         conn = createConnection();
+         Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         for (int i = 0; i < 200; i++) {
+            TemporaryQueue temporaryQueue = s.createTemporaryQueue();
+            MessageProducer producer = s.createProducer(temporaryQueue);
+            producer.send(s.createMessage());
+         }
+         for (ServerSession serverSession : server.getSessions()) {
+            assertTrue(((ServerSessionImpl)serverSession).cloneTargetAddresses().size() <= 100);
+         }
+      } finally {
+         if (conn != null) {
+            conn.close();
+         }
+      }
+   }
+
+   @Test
    public void testForSecurityCacheLeak() throws Exception {
       server.getSecurityStore().setSecurityEnabled(true);
       ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager();