diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/MBeanInfoHelper.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/MBeanInfoHelper.java index 900951e77b..289532575e 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/MBeanInfoHelper.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/MBeanInfoHelper.java @@ -23,6 +23,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; import org.apache.activemq.artemis.api.core.management.Attribute; import org.apache.activemq.artemis.api.core.management.Operation; @@ -30,52 +31,76 @@ import org.apache.activemq.artemis.api.core.management.Parameter; public class MBeanInfoHelper { - + private static ConcurrentHashMap attributesInfoCache = new ConcurrentHashMap<>(); + private static ConcurrentHashMap operationsInfoCache = new ConcurrentHashMap<>(); public static MBeanOperationInfo[] getMBeanOperationsInfo(final Class mbeanInterface) { - List operations = new ArrayList<>(); + if (operationsInfoCache.containsKey(mbeanInterface)) { + return operationsInfoCache.get(mbeanInterface); + } else { + List operations = new ArrayList<>(); - for (Method method : mbeanInterface.getMethods()) { - if (!MBeanInfoHelper.isGetterMethod(method) && !MBeanInfoHelper.isSetterMethod(method) && - !MBeanInfoHelper.isIsBooleanMethod(method)) { - operations.add(MBeanInfoHelper.getOperationInfo(method)); + for (Method method : mbeanInterface.getMethods()) { + if (!MBeanInfoHelper.isGetterMethod(method) && !MBeanInfoHelper.isSetterMethod(method) && + !MBeanInfoHelper.isIsBooleanMethod(method)) { + operations.add(MBeanInfoHelper.getOperationInfo(method)); + } } + MBeanOperationInfo[] result = operations.toArray(new MBeanOperationInfo[operations.size()]); + operationsInfoCache.put(mbeanInterface, result); + return result; } - - return operations.toArray(new MBeanOperationInfo[operations.size()]); } public static MBeanAttributeInfo[] getMBeanAttributesInfo(final Class mbeanInterface) { - List tempAttributes = new ArrayList<>(); - List finalAttributes = new ArrayList<>(); - List alreadyAdded = new ArrayList<>(); + if (attributesInfoCache.containsKey(mbeanInterface)) { + return attributesInfoCache.get(mbeanInterface); + } else { + List tempAttributes = new ArrayList<>(); + List finalAttributes = new ArrayList<>(); + List alreadyAdded = new ArrayList<>(); - for (Method method : mbeanInterface.getMethods()) { - if (MBeanInfoHelper.isGetterMethod(method) || MBeanInfoHelper.isSetterMethod(method) || - MBeanInfoHelper.isIsBooleanMethod(method)) { - tempAttributes.add(MBeanInfoHelper.getAttributeInfo(method)); - } - } - - // since getters and setters will each have an MBeanAttributeInfo we need to de-duplicate - for (MBeanAttributeInfo info1 : tempAttributes) { - MBeanAttributeInfo infoToCopy = info1; - for (MBeanAttributeInfo info2 : tempAttributes) { - if (info1.getName().equals(info2.getName()) && !info1.equals(info2)) { - infoToCopy = new MBeanAttributeInfo(info1.getName(), info1.getType().equals("void") ? info2.getType() : info1.getType(), info1.getDescription(), (info1.isReadable() || info2.isReadable()), (info1.isWritable() || info2.isWritable()), (info1.isIs() || info2.isIs())); + for (Method method : mbeanInterface.getMethods()) { + if (MBeanInfoHelper.isGetterMethod(method) || MBeanInfoHelper.isSetterMethod(method) || + MBeanInfoHelper.isIsBooleanMethod(method)) { + tempAttributes.add(MBeanInfoHelper.getAttributeInfo(method)); } } - if (!alreadyAdded.contains(infoToCopy.getName())) { - finalAttributes.add(infoToCopy); - alreadyAdded.add(infoToCopy.getName()); - } - } - return finalAttributes.toArray(new MBeanAttributeInfo[finalAttributes.size()]); + // since getters and setters will each have an MBeanAttributeInfo we need to de-duplicate + for (MBeanAttributeInfo info1 : tempAttributes) { + MBeanAttributeInfo infoToCopy = info1; + for (MBeanAttributeInfo info2 : tempAttributes) { + if (info1.getName().equals(info2.getName()) && !info1.equals(info2)) { + infoToCopy = new MBeanAttributeInfo(info1.getName(), info1.getType().equals("void") ? info2.getType() : info1.getType(), info1.getDescription(), (info1.isReadable() || info2.isReadable()), (info1.isWritable() || info2.isWritable()), (info1.isIs() || info2.isIs())); + } + } + if (!alreadyAdded.contains(infoToCopy.getName())) { + finalAttributes.add(infoToCopy); + alreadyAdded.add(infoToCopy.getName()); + } + } + MBeanAttributeInfo[] result = finalAttributes.toArray(new MBeanAttributeInfo[finalAttributes.size()]); + attributesInfoCache.put(mbeanInterface, result); + return result; + } } + public static int getAttributesInfoCacheSize() { + return attributesInfoCache.size(); + } + public static int getOperationsInfoCacheSize() { + return operationsInfoCache.size(); + } + public static void clearAttributesInfoCache() { + attributesInfoCache.clear(); + } + + public static void clearOperationsInfoCache() { + operationsInfoCache.clear(); + } private static boolean isGetterMethod(final Method method) { if (!method.getName().equals("get") && method.getName().startsWith("get") && diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/management/impl/MBeanInfoHelperTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/management/impl/MBeanInfoHelperTest.java new file mode 100644 index 0000000000..113a827f91 --- /dev/null +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/management/impl/MBeanInfoHelperTest.java @@ -0,0 +1,46 @@ +/** + * 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.core.management.impl; + +import org.apache.activemq.artemis.api.core.management.AddressControl; +import org.apache.activemq.artemis.api.core.management.QueueControl; +import org.junit.Assert; +import org.junit.Test; + +public class MBeanInfoHelperTest extends Assert { + + @Test + public void testOperationsInfosCache() { + MBeanInfoHelper.clearOperationsInfoCache(); + for (int i = 0; i < 10; i++) { + MBeanInfoHelper.getMBeanOperationsInfo(QueueControl.class); + MBeanInfoHelper.getMBeanOperationsInfo(AddressControl.class); + } + assertEquals(2, MBeanInfoHelper.getOperationsInfoCacheSize()); + } + + @Test + public void testAttributesInfosCache() { + MBeanInfoHelper.clearAttributesInfoCache(); + for (int i = 0; i < 10; i++) { + MBeanInfoHelper.getMBeanAttributesInfo(QueueControl.class); + MBeanInfoHelper.getMBeanAttributesInfo(AddressControl.class); + } + assertEquals(2, MBeanInfoHelper.getAttributesInfoCacheSize()); + } +}