diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java deleted file mode 100644 index 407a714a9d..0000000000 --- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java +++ /dev/null @@ -1,237 +0,0 @@ -package org.apache.helix.monitoring.mbeans.dynamicMBeans; - -/* - * 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. - */ - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.AttributeNotFoundException; -import javax.management.DynamicMBean; -import javax.management.JMException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanConstructorInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanNotificationInfo; -import javax.management.MBeanOperationInfo; -import javax.management.ObjectName; - -import org.apache.helix.SystemPropertyKeys; -import org.apache.helix.monitoring.SensorNameProvider; -import org.apache.helix.monitoring.mbeans.MBeanRegistrar; -import org.apache.helix.util.HelixUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Dynamic MBean provider that reporting DynamicMetric attributes - */ -public abstract class DynamicMBeanProvider implements DynamicMBean, SensorNameProvider { - protected final Logger _logger = LoggerFactory.getLogger(getClass()); - protected static final long DEFAULT_RESET_INTERVAL_MS = 60 * 60 * 1000; // Reset time every hour - private static final String SENSOR_NAME_TAG = "SensorName"; - private static final String DEFAULT_DESCRIPTION = - "Information on the management interface of the MBean"; - - // Attribute name to the DynamicMetric object mapping - private Map _attributeMap = new HashMap<>(); - private ObjectName _objectName = null; - private MBeanInfo _mBeanInfo; - - /** - * Instantiates a new Dynamic MBean provider. - * @param dynamicMetrics Dynamic Metrics that are exposed by this provider - * @param description the MBean description - * @param domain the MBean domain name - * @param keyValuePairs the MBean object name components - */ - protected synchronized boolean doRegister(Collection> dynamicMetrics, - String description, String domain, String... keyValuePairs) throws JMException { - return doRegister(dynamicMetrics, description, - MBeanRegistrar.buildObjectName(domain, keyValuePairs)); - } - - /** - * Instantiates a new Dynamic MBean provider. - * @param dynamicMetrics Dynamic Metrics that are exposed by this provider - * @param description the MBean description - * @param objectName the proposed MBean ObjectName - */ - protected synchronized boolean doRegister(Collection> dynamicMetrics, - String description, ObjectName objectName) throws JMException { - if (_objectName != null) { - _logger.debug("Mbean {} has already been registered. Ignore register request.", - objectName.getCanonicalName()); - return false; - } - updateAttributesInfo(dynamicMetrics, description); - _objectName = MBeanRegistrar.register(this, objectName); - return true; - } - - protected synchronized boolean doRegister(Collection> dynamicMetrics, - ObjectName objectName) throws JMException { - return doRegister(dynamicMetrics, null, objectName); - } - - /** - * Updates the Dynamic MBean provider with new metric list. - * If the pass-in metrics collection is empty, the original attributes will be removed. - * - * @param description description of the MBean - * @param dynamicMetrics the DynamicMetrics. Empty collection will remove the metric attributes. - */ - protected void updateAttributesInfo(Collection> dynamicMetrics, - String description) { - if (dynamicMetrics == null) { - _logger.warn("Cannot update attributes info because dynamicMetrics is null."); - return; - } - - List attributeInfoList = new ArrayList<>(); - // Use a new attribute map to avoid concurrency issue. - Map newAttributeMap = new HashMap<>(); - - // Get all attributes that can be emitted by the dynamicMetrics. - for (DynamicMetric dynamicMetric : dynamicMetrics) { - for (MBeanAttributeInfo attributeInfo : dynamicMetric.getAttributeInfos()) { - // Info list to create MBean info - attributeInfoList.add(attributeInfo); - // Attribute mapping for getting attribute value when getAttribute() is called - newAttributeMap.put(attributeInfo.getName(), dynamicMetric); - } - } - - // SensorName - attributeInfoList.add(new MBeanAttributeInfo(SENSOR_NAME_TAG, String.class.getName(), - "The name of the metric sensor", true, false, false)); - - MBeanConstructorInfo constructorInfo = new MBeanConstructorInfo( - String.format("Default %s Constructor", getClass().getSimpleName()), - getClass().getConstructors()[0]); - - MBeanAttributeInfo[] attributesInfo = new MBeanAttributeInfo[attributeInfoList.size()]; - attributesInfo = attributeInfoList.toArray(attributesInfo); - - if (description == null) { - description = DEFAULT_DESCRIPTION; - } - - _mBeanInfo = new MBeanInfo(getClass().getName(), description, attributesInfo, - new MBeanConstructorInfo[]{constructorInfo}, new MBeanOperationInfo[0], - new MBeanNotificationInfo[0]); - - // Update _attributeMap reference. - _attributeMap = newAttributeMap; - } - - /** - * Call doRegister() to finish registration MBean and the attributes. - */ - public abstract DynamicMBeanProvider register() throws JMException; - - /** - * Unregister the MBean and clean up object name record. - * Note that all the metric data is kept even after unregister. - */ - public synchronized void unregister() { - MBeanRegistrar.unregister(_objectName); - _objectName = null; - } - - @Override - public Object getAttribute(String attribute) throws AttributeNotFoundException { - if (SENSOR_NAME_TAG.equals(attribute)) { - return getSensorName(); - } - - DynamicMetric metric = _attributeMap.get(attribute); - if (metric == null) { - throw new AttributeNotFoundException("Attribute[" + attribute + "] is not found."); - } - - return metric.getAttributeValue(attribute); - } - - @Override - public AttributeList getAttributes(String[] attributes) { - AttributeList attributeList = new AttributeList(); - for (String attributeName : attributes) { - try { - Object value = getAttribute(attributeName); - attributeList.add(new Attribute(attributeName, value)); - } catch (AttributeNotFoundException ex) { - _logger.error("Failed to get attribute: " + attributeName, ex); - } - } - return attributeList; - } - - @Override - public MBeanInfo getMBeanInfo() { - return _mBeanInfo; - } - - @Override - public void setAttribute(Attribute attribute) { - // All MBeans are readonly - return; - } - - @Override - public AttributeList setAttributes(AttributeList attributes) { - // All MBeans are readonly - return null; - } - - @Override - public Object invoke(String actionName, Object[] params, String[] signature) { - // No operation supported - return null; - } - - /** - * NOTE: This method is not thread-safe nor atomic. - * Increment the value of a given SimpleDynamicMetric by 1. - */ - protected void incrementSimpleDynamicMetric(SimpleDynamicMetric metric) { - incrementSimpleDynamicMetric(metric, 1); - } - - /** - * NOTE: This method is not thread-safe nor atomic. - * Increment the value of a given SimpleDynamicMetric with input value. - */ - protected void incrementSimpleDynamicMetric(SimpleDynamicMetric metric, long value) { - metric.updateValue(metric.getValue() + value); - } - - /** - * Return the interval length for the underlying reservoir used by the MBean metric configured - * in the system env variables. If not found, use default value. - */ - protected Long getResetIntervalInMs() { - return HelixUtil.getSystemPropertyAsLong(SystemPropertyKeys.HELIX_MONITOR_TIME_WINDOW_LENGTH_MS, - DEFAULT_RESET_INTERVAL_MS); - } -} diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java deleted file mode 100644 index 2b0f1db3cc..0000000000 --- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.apache.helix.monitoring.mbeans.dynamicMBeans; - -/* - * 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. - */ - -/** - * The dynamic metric that accept and emits same type of monitor data - * - * @param the type of the metric value - */ -public class SimpleDynamicMetric extends DynamicMetric { - protected final String _metricName; - - /** - * Instantiates a new Simple dynamic metric. - * - * @param metricName the metric name - * @param metricObject the metric object - */ - public SimpleDynamicMetric(String metricName, T metricObject) { - super(metricName, metricObject); - _metricName = metricName; - } - - @Override - public T getAttributeValue(String attributeName) { - if (!attributeName.equals(_metricName)) { - return null; - } - return getMetricObject(); - } - - /** - * @return current metric value - */ - public T getValue() { - return getMetricObject(); - } - - @Override - public void updateValue(T metricObject) { - setMetricObject(metricObject); - } -} diff --git a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java index 8174326a8f..7071c80525 100644 --- a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java +++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java @@ -22,23 +22,19 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.DynamicMBean; -import javax.management.InvalidAttributeValueException; import javax.management.JMException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanConstructorInfo; -import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanNotificationInfo; import javax.management.MBeanOperationInfo; import javax.management.ObjectName; -import javax.management.ReflectionException; import org.apache.helix.monitoring.SensorNameProvider; import org.apache.helix.monitoring.mbeans.MBeanRegistrar; @@ -54,13 +50,12 @@ public abstract class DynamicMBeanProvider implements DynamicMBean, SensorNamePr protected static final long DEFAULT_RESET_INTERVAL_MS = 60 * 60 * 1000; // Reset time every hour private static final String HELIX_MONITOR_TIME_WINDOW_LENGTH_MS = "helix.monitor.slidingTimeWindow.ms"; - - private static String SENSOR_NAME_TAG = "SensorName"; - private static String DEFAULT_DESCRIPTION = + private static final String SENSOR_NAME_TAG = "SensorName"; + private static final String DEFAULT_DESCRIPTION = "Information on the management interface of the MBean"; // Attribute name to the DynamicMetric object mapping - private final Map _attributeMap = new HashMap<>(); + private Map _attributeMap = new HashMap<>(); private ObjectName _objectName = null; private MBeanInfo _mBeanInfo; @@ -90,7 +85,7 @@ protected synchronized boolean doRegister(Collection> dynami objectName.getCanonicalName()); return false; } - updateAttributtInfos(dynamicMetrics, description); + updateAttributesInfo(dynamicMetrics, description); _objectName = MBeanRegistrar.register(this, objectName); return true; } @@ -101,26 +96,30 @@ protected synchronized boolean doRegister(Collection> dynami } /** - * Update the Dynamic MBean provider with new metric list. + * Updates the Dynamic MBean provider with new metric list. + * If the pass-in metrics collection is empty, the original attributes will be removed. + * * @param description description of the MBean - * @param dynamicMetrics the DynamicMetrics + * @param dynamicMetrics the DynamicMetrics. Empty collection will remove the metric attributes. */ - private void updateAttributtInfos(Collection> dynamicMetrics, + protected void updateAttributesInfo(Collection> dynamicMetrics, String description) { - _attributeMap.clear(); + if (dynamicMetrics == null) { + _logger.warn("Cannot update attributes info because dynamicMetrics is null."); + return; + } - // get all attributes that can be emit by the dynamicMetrics. List attributeInfoList = new ArrayList<>(); - if (dynamicMetrics != null) { - for (DynamicMetric dynamicMetric : dynamicMetrics) { - Iterator iter = dynamicMetric.getAttributeInfos().iterator(); - while (iter.hasNext()) { - MBeanAttributeInfo attributeInfo = iter.next(); - // Info list to create MBean info - attributeInfoList.add(attributeInfo); - // Attribute mapping for getting attribute value when getAttribute() is called - _attributeMap.put(attributeInfo.getName(), dynamicMetric); - } + // Use a new attribute map to avoid concurrency issue. + Map newAttributeMap = new HashMap<>(); + + // Get all attributes that can be emitted by the dynamicMetrics. + for (DynamicMetric dynamicMetric : dynamicMetrics) { + for (MBeanAttributeInfo attributeInfo : dynamicMetric.getAttributeInfos()) { + // Info list to create MBean info + attributeInfoList.add(attributeInfo); + // Attribute mapping for getting attribute value when getAttribute() is called + newAttributeMap.put(attributeInfo.getName(), dynamicMetric); } } @@ -132,16 +131,19 @@ private void updateAttributtInfos(Collection> dynamicMetrics String.format("Default %s Constructor", getClass().getSimpleName()), getClass().getConstructors()[0]); - MBeanAttributeInfo[] attributeInfos = new MBeanAttributeInfo[attributeInfoList.size()]; - attributeInfos = attributeInfoList.toArray(attributeInfos); + MBeanAttributeInfo[] attributesInfo = new MBeanAttributeInfo[attributeInfoList.size()]; + attributesInfo = attributeInfoList.toArray(attributesInfo); if (description == null) { description = DEFAULT_DESCRIPTION; } - _mBeanInfo = new MBeanInfo(getClass().getName(), description, attributeInfos, + _mBeanInfo = new MBeanInfo(getClass().getName(), description, attributesInfo, new MBeanConstructorInfo[]{constructorInfo}, new MBeanOperationInfo[0], new MBeanNotificationInfo[0]); + + // Update _attributeMap reference. + _attributeMap = newAttributeMap; } /** @@ -159,17 +161,17 @@ public synchronized void unregister() { } @Override - public Object getAttribute(String attribute) - throws AttributeNotFoundException, MBeanException, ReflectionException { + public Object getAttribute(String attribute) throws AttributeNotFoundException { if (SENSOR_NAME_TAG.equals(attribute)) { return getSensorName(); } - if (!_attributeMap.containsKey(attribute)) { - return null; + DynamicMetric metric = _attributeMap.get(attribute); + if (metric == null) { + throw new AttributeNotFoundException("Attribute[" + attribute + "] is not found."); } - return _attributeMap.get(attribute).getAttributeValue(attribute); + return metric.getAttributeValue(attribute); } @Override @@ -179,7 +181,7 @@ public AttributeList getAttributes(String[] attributes) { try { Object value = getAttribute(attributeName); attributeList.add(new Attribute(attributeName, value)); - } catch (AttributeNotFoundException | MBeanException | ReflectionException ex) { + } catch (AttributeNotFoundException ex) { _logger.error("Failed to get attribute: " + attributeName, ex); } } @@ -192,9 +194,7 @@ public MBeanInfo getMBeanInfo() { } @Override - public void setAttribute(Attribute attribute) - throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, - ReflectionException { + public void setAttribute(Attribute attribute) { // All MBeans are readonly return; } @@ -206,8 +206,7 @@ public AttributeList setAttributes(AttributeList attributes) { } @Override - public Object invoke(String actionName, Object[] params, String[] signature) - throws MBeanException, ReflectionException { + public Object invoke(String actionName, Object[] params, String[] signature) { // No operation supported return null; } diff --git a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java index 1be6a21423..2b0f1db3cc 100644 --- a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java +++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java @@ -25,7 +25,7 @@ * @param the type of the metric value */ public class SimpleDynamicMetric extends DynamicMetric { - private final String _metricName; + protected final String _metricName; /** * Instantiates a new Simple dynamic metric.