From 0b155cf5eaa64022c1d8e3df678b9ee17453991b Mon Sep 17 00:00:00 2001 From: Justin Bertram Date: Wed, 18 Mar 2020 20:48:34 -0500 Subject: [PATCH] ARTEMIS-2666 mngmnt for duplicate ID cache --- .../activemq/artemis/logs/AuditLogger.java | 17 +++++++++ .../api/core/management/AddressControl.java | 6 +++ .../management/impl/AddressControlImpl.java | 38 +++++++++++++++++++ .../management/AddressControlTest.java | 36 ++++++++++++++++++ .../AddressControlUsingCoreTest.java | 10 +++++ 5 files changed, 107 insertions(+) diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java index 28ea864422..773c631a9a 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java @@ -2324,4 +2324,21 @@ public interface AuditLogger extends BasicLogger { @LogMessage(level = Logger.Level.INFO) @Message(id = 601508, value = "User {0} is getting group first key on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT) void getGroupFirstKey(String user, Object source, Object... args); + + static void getCurrentDuplicateIdCacheSize(Object source) { + LOGGER.getCurrentDuplicateIdCacheSize(getCaller(), source); + } + + @LogMessage(level = Logger.Level.INFO) + @Message(id = 601509, value = "User {0} is getting currentDuplicateIdCacheSize property on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT) + void getCurrentDuplicateIdCacheSize(String user, Object source, Object... args); + + + static void clearDuplicateIdCache(Object source) { + LOGGER.clearDuplicateIdCache(getCaller(), source); + } + + @LogMessage(level = Logger.Level.INFO) + @Message(id = 601510, value = "User {0} is clearing duplicate ID cache on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT) + void clearDuplicateIdCache(String user, Object source, Object... args); } diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/AddressControl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/AddressControl.java index 0eaf3e1f5d..e367685d21 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/AddressControl.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/AddressControl.java @@ -165,4 +165,10 @@ public interface AddressControl { @Attribute(desc = "whether this address is used for a retroactive address") boolean isRetroactiveResource(); + @Attribute(desc = "the size of the duplicate ID cache for this address") + long getCurrentDuplicateIdCacheSize(); + + @Attribute(desc = "clear the duplicate ID cache for this address both from memory and from the journal") + boolean clearDuplicateIdCache() throws Exception; + } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/AddressControlImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/AddressControlImpl.java index 5332c01169..c3c0a74a58 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/AddressControlImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/AddressControlImpl.java @@ -35,11 +35,14 @@ import org.apache.activemq.artemis.core.paging.PagingStore; import org.apache.activemq.artemis.core.persistence.StorageManager; import org.apache.activemq.artemis.core.postoffice.Binding; import org.apache.activemq.artemis.core.postoffice.Bindings; +import org.apache.activemq.artemis.core.postoffice.DuplicateIDCache; import org.apache.activemq.artemis.core.postoffice.QueueBinding; +import org.apache.activemq.artemis.core.postoffice.impl.PostOfficeImpl; import org.apache.activemq.artemis.core.security.CheckType; import org.apache.activemq.artemis.core.security.Role; import org.apache.activemq.artemis.core.security.SecurityStore; import org.apache.activemq.artemis.core.server.ActiveMQServer; +import org.apache.activemq.artemis.core.server.ActiveMQServerLogger; import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.artemis.core.server.management.ManagementService; import org.apache.activemq.artemis.core.settings.HierarchicalRepository; @@ -427,6 +430,41 @@ public class AddressControlImpl extends AbstractControl implements AddressContro return ResourceNames.isRetroactiveResource(server.getInternalNamingPrefix(), addressInfo.getName()); } + @Override + public long getCurrentDuplicateIdCacheSize() { + if (AuditLogger.isEnabled()) { + AuditLogger.getCurrentDuplicateIdCacheSize(this.addressInfo); + } + DuplicateIDCache cache = ((PostOfficeImpl)server.getPostOffice()).getDuplicateIDCaches().get(addressInfo.getName()); + try { + if (cache != null) { + return cache.getMap().size(); + } + } catch (Exception e) { + ActiveMQServerLogger.LOGGER.debug("Failed to get duplicate ID cache size", e); + } + + return 0; + } + + @Override + public boolean clearDuplicateIdCache() { + if (AuditLogger.isEnabled()) { + AuditLogger.clearDuplicateIdCache(this.addressInfo); + } + DuplicateIDCache cache = ((PostOfficeImpl)server.getPostOffice()).getDuplicateIDCaches().get(addressInfo.getName()); + try { + if (cache != null) { + cache.clear(); + return true; + } + } catch (Exception e) { + ActiveMQServerLogger.LOGGER.debug("Failed to clear duplicate ID cache", e); + } + + return false; + } + // Package protected --------------------------------------------- // Protected ----------------------------------------------------- diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlTest.java index e23cbe8823..d07cc0b318 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlTest.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.UUID; import org.apache.activemq.artemis.api.core.JsonUtil; import org.apache.activemq.artemis.api.core.Message; @@ -432,6 +433,41 @@ public class AddressControlTest extends ManagementTestBase { assertEquals("myValue2", message.getStringProperty("myProp2")); } + @Test + public void testGetCurrentDuplicateIdCacheSize() throws Exception { + internalDuplicateIdTest(false); + } + + @Test + public void testClearDuplicateIdCache() throws Exception { + internalDuplicateIdTest(true); + } + + private void internalDuplicateIdTest(boolean clear) throws Exception { + server.getConfiguration().setPersistIDCache(false); + SimpleString address = RandomUtil.randomSimpleString(); + session.createAddress(address, RoutingType.ANYCAST, false); + + AddressControl addressControl = createManagementControl(address); + Assert.assertEquals(0, addressControl.getQueueNames().length); + session.createQueue(address, RoutingType.ANYCAST, address); + Assert.assertEquals(1, addressControl.getQueueNames().length); + Map headers = new HashMap<>(); + headers.put(Message.HDR_DUPLICATE_DETECTION_ID.toString(), UUID.randomUUID().toString()); + addressControl.sendMessage(headers, Message.BYTES_TYPE, Base64.encodeBytes("test".getBytes()), false, null, null); + addressControl.sendMessage(headers, Message.BYTES_TYPE, Base64.encodeBytes("test".getBytes()), false, null, null); + headers.clear(); + headers.put(Message.HDR_DUPLICATE_DETECTION_ID.toString(), UUID.randomUUID().toString()); + addressControl.sendMessage(headers, Message.BYTES_TYPE, Base64.encodeBytes("test".getBytes()), false, null, null); + + Wait.assertTrue(() -> addressControl.getCurrentDuplicateIdCacheSize() == 2); + + if (clear) { + assertTrue(addressControl.clearDuplicateIdCache()); + Wait.assertTrue(() -> addressControl.getCurrentDuplicateIdCacheSize() == 0); + } + } + // Package protected --------------------------------------------- // Protected ----------------------------------------------------- diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlUsingCoreTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlUsingCoreTest.java index c76f4d735a..31355fde5e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlUsingCoreTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/AddressControlUsingCoreTest.java @@ -138,6 +138,16 @@ public class AddressControlUsingCoreTest extends AddressControlTest { return (boolean) proxy.retrieveAttributeValue("retroactiveResource"); } + @Override + public long getCurrentDuplicateIdCacheSize() { + return (long) proxy.retrieveAttributeValue("currentDuplicateIdCacheSize"); + } + + @Override + public boolean clearDuplicateIdCache() throws Exception { + return (boolean) proxy.invokeOperation("clearDuplicateIdCache"); + } + @Override public String sendMessage(Map headers, int type,