Repository: deltaspike Updated Branches: refs/heads/master 234ab7370 -> 40d24ab50
DELTASPIKE-1185 Allow customization (name, description) of JMX managed methods' parameters Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/40d24ab5 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/40d24ab5 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/40d24ab5 Branch: refs/heads/master Commit: 40d24ab50ad1660390d9b06bc5c6ac5cabd84329 Parents: 234ab73 Author: Xavier Dury <[email protected]> Authored: Wed Jul 20 15:49:27 2016 +0200 Committer: Xavier Dury <[email protected]> Committed: Fri Jul 22 10:04:07 2016 +0200 ---------------------------------------------------------------------- .../deltaspike/core/api/jmx/JmxParameter.java | 45 ++++++++++ .../deltaspike/core/util/ParameterUtil.java | 76 +++++++++++++++++ .../deltaspike/core/util/ParameterUtilTest.java | 46 +++++++++++ .../core/impl/jmx/DynamicMBeanWrapper.java | 86 +++++++++++++++----- .../deltaspike/test/core/impl/jmx/MyMBean.java | 3 +- .../core/impl/jmx/SimpleRegistrationTest.java | 4 + 6 files changed, 237 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40d24ab5/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxParameter.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxParameter.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxParameter.java new file mode 100644 index 0000000..83fc30c --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxParameter.java @@ -0,0 +1,45 @@ +/* + * 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.deltaspike.core.api.jmx; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Describes a parameter of a JMX operation. + */ +@Retention(RUNTIME) +@Target(PARAMETER) +@Documented +public @interface JmxParameter +{ + /** + * @return the description of the parameter. + */ + String description() default ""; + + /** + * @return the name of the parameter. + */ + String name() default ""; +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40d24ab5/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterUtil.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterUtil.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterUtil.java new file mode 100644 index 0000000..2346cc5 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterUtil.java @@ -0,0 +1,76 @@ +/* + * 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.deltaspike.core.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import javax.enterprise.inject.Typed; + +@Typed() +public abstract class ParameterUtil +{ + private static boolean parameterSupported = true; + private static Class<?> parameterClass; + private static Method getNameMethod; + private static Method getParametersMethod; + + static + { + try + { + parameterClass = Class.forName("java.lang.reflect.Parameter"); + getNameMethod = parameterClass.getMethod("getName"); + getParametersMethod = Method.class.getMethod("getParameters"); + } + catch (Exception e) + { + parameterSupported = false; + parameterClass = null; + getNameMethod = null; + getParametersMethod = null; + } + } + + public static boolean isParameterSupported() + { + return parameterSupported; + } + + public static String getName(Method method, int parameterIndex) + { + if (!isParameterSupported() || method == null) + { + return null; + } + try + { + Object[] parameters = (Object[]) getParametersMethod.invoke(method); + return (String) getNameMethod.invoke(parameters[parameterIndex]); + } + catch (IllegalAccessException e) + { + } + catch (InvocationTargetException e) + { + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40d24ab5/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/ParameterUtilTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/ParameterUtilTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/ParameterUtilTest.java new file mode 100644 index 0000000..b0d55c6 --- /dev/null +++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/ParameterUtilTest.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.deltaspike.core.util; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Method; + +public class ParameterUtilTest +{ + @Before + public void isEnabled() + { + Assume.assumeTrue(ParameterUtil.isParameterSupported()); + } + + @Test + public void shouldReturnNameOrNull() throws Exception + { + Method method = getClass().getDeclaredMethod("someMethod", String.class); + String parameterName = ParameterUtil.getName(method, 0); + Assert.assertTrue(parameterName.equals("arg0") || parameterName.equals("firstParameter")); + } + + public void someMethod(String firstParameter) {} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40d24ab5/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java index 1ff1365..09166d5 100644 --- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java +++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java @@ -18,14 +18,19 @@ */ package org.apache.deltaspike.core.impl.jmx; -import org.apache.deltaspike.core.api.config.ConfigResolver; -import org.apache.deltaspike.core.api.jmx.JmxBroadcaster; -import org.apache.deltaspike.core.api.jmx.JmxManaged; -import org.apache.deltaspike.core.api.jmx.MBean; -import org.apache.deltaspike.core.api.jmx.NotificationInfo; -import org.apache.deltaspike.core.api.provider.BeanManagerProvider; -import org.apache.deltaspike.core.api.provider.BeanProvider; -import org.apache.deltaspike.core.util.ExceptionUtils; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; @@ -41,22 +46,21 @@ import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanNotificationInfo; import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.ReflectionException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; + +import org.apache.deltaspike.core.api.config.ConfigResolver; +import org.apache.deltaspike.core.api.jmx.JmxBroadcaster; +import org.apache.deltaspike.core.api.jmx.JmxManaged; +import org.apache.deltaspike.core.api.jmx.JmxParameter; +import org.apache.deltaspike.core.api.jmx.MBean; +import org.apache.deltaspike.core.api.jmx.NotificationInfo; +import org.apache.deltaspike.core.api.provider.BeanManagerProvider; +import org.apache.deltaspike.core.api.provider.BeanProvider; +import org.apache.deltaspike.core.util.ExceptionUtils; +import org.apache.deltaspike.core.util.ParameterUtil; /** * This class is the MBean implementation of a CDI bean. @@ -134,8 +138,46 @@ public class DynamicMBeanWrapper extends NotificationBroadcasterSupport implemen operations.put(method.getName(), method); String operationDescr = getDescription(annotation.description(), method.getName()); + + Annotation[][] parametersAnnotations = method.getParameterAnnotations(); + Class<?>[] parameterTypes = method.getParameterTypes(); + MBeanParameterInfo[] parameterInfos = new MBeanParameterInfo[parameterTypes.length]; + for (int i = 0; i < parametersAnnotations.length; i++) + { + String parameterDescription = null; + String parameterName = "p" + (i + 1); + String java8ParameterName = ParameterUtil.getName(method, i); + if (java8ParameterName != null) + { + parameterName = java8ParameterName; + } + for (int j = 0; j < parametersAnnotations[i].length; j++) + { + if (parametersAnnotations[i][j] instanceof JmxParameter) + { + JmxParameter jmxParameter = (JmxParameter) parametersAnnotations[i][j]; + if (!"".equals(jmxParameter.name())) + { + parameterName = jmxParameter.name(); + } + if (!"".equals(jmxParameter.description())) + { + parameterDescription = jmxParameter.description(); + } + } + } + parameterInfos[i] = new MBeanParameterInfo(parameterName, + parameterTypes[i].getName(), + parameterDescription + ); + } - operationInfos.add(new MBeanOperationInfo(operationDescr, method)); + operationInfos.add(new MBeanOperationInfo(method.getName(), + operationDescr, + parameterInfos, + method.getReturnType().getName(), + MBeanOperationInfo.UNKNOWN + )); } Class<?> clazz = annotatedMBean; http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40d24ab5/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java index 7bf2112..a48f858 100644 --- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java +++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java @@ -20,6 +20,7 @@ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.core.api.jmx.JmxBroadcaster; import org.apache.deltaspike.core.api.jmx.JmxManaged; +import org.apache.deltaspike.core.api.jmx.JmxParameter; import org.apache.deltaspike.core.api.jmx.MBean; import javax.enterprise.context.ApplicationScoped; @@ -52,7 +53,7 @@ public class MyMBean } @JmxManaged(description = "multiply counter") - public int multiply(final int n) + public int multiply(@JmxParameter(name = "multiplier", description = "the multiplier") final int n) { return counter * n; } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40d24ab5/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java index db4005a..c999d4f 100644 --- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java +++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java @@ -63,5 +63,9 @@ public abstract class SimpleRegistrationTest { myMBean.broadcast(); assertEquals(1, notifications.size()); assertEquals(10L, notifications.iterator().next().getSequenceNumber()); + + MBeanParameterInfo parameterInfo = server.getMBeanInfo(on).getOperations()[0].getSignature()[0]; + assertEquals("multiplier", parameterInfo.getName()); + assertEquals("the multiplier", parameterInfo.getDescription()); } }
