You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2016/10/18 18:57:36 UTC
[06/42] incubator-geode git commit: Move Admin API to internal
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatAlertsAggregator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatAlertsAggregator.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatAlertsAggregator.java
new file mode 100644
index 0000000..8edce21
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatAlertsAggregator.java
@@ -0,0 +1,124 @@
+/*
+ * 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.geode.internal.admin.api.jmx.impl;
+
+import org.apache.geode.internal.admin.GemFireVM;
+import org.apache.geode.internal.admin.StatAlert;
+import org.apache.geode.internal.admin.StatAlertDefinition;
+
+/**
+ * This interface represents an Aggregator entity and resides in JMXAgent.
+ * Responsibilities are as follows:
+ * <ol>
+ * <li> set AlertsManager in the newly joined members
+ * <li> create/update/remove alert
+ * <li> manage refresh interval
+ * <li> process notification from members
+ * <li> Aggregate stats & make available for clients thro' JMXAgent
+ * </ol>
+ *
+ */
+public interface StatAlertsAggregator {
+
+ /**
+ * This method can be used to get an alert definition.
+ *
+ * @param alertDefinition
+ * StatAlertDefinition to retrieve
+ * @return StatAlertDefinition
+ */
+ public StatAlertDefinition getAlertDefinition(
+ StatAlertDefinition alertDefinition);
+
+ /**
+ * This method can be used to retrieve all available stat alert definitions.
+ *
+ * @return An array of all available StatAlertDefinition objects
+ */
+ public StatAlertDefinition[] getAllStatAlertDefinitions();
+
+ /**
+ * This method can be used to update alert definition for the Stat mentioned.
+ * This method should update the collection maintained at the aggregator and
+ * should notify members for the newly added alert definitions.
+ * <p>
+ * A new alert definition will be created if matching one not found.
+ *
+ * @param alertDefinition
+ * alertDefinition to be updated
+ */
+ public void updateAlertDefinition(StatAlertDefinition alertDefinition);
+
+ /**
+ * This method can be used to remove alert definition for the Stat mentioned.
+ * <p>
+ * This method should update the collection maintained at the aggregator and
+ * should notify members for the newly added alert definitions.
+ *
+ * @param defId
+ * id of the alert definition to be removed
+ */
+ public void removeAlertDefinition(Integer defId);
+
+ /**
+ * Convenience method to check whether an alert definition is created.
+ *
+ * @param alert
+ * alert definition to check whether already created
+ * @return true if the alert definition is already created, false otherwise
+ */
+ public boolean isAlertDefinitionCreated(StatAlertDefinition alert);
+
+ /**
+ * This method can be used to set the AlertManager for the newly joined member
+ * VM.
+ *
+ * @param memberVM
+ * Member VM to set AlertsManager for
+ */
+ public void setAlertsManager(GemFireVM memberVM);
+
+ /**
+ * Returns the refresh interval for the Stats in seconds.
+ *
+ * @return refresh interval for the Stats(in seconds)
+ */
+ public int getRefreshIntervalForStatAlerts();
+
+ /**
+ * This method is used to set the refresh interval for the Stats Alerts in
+ * seconds
+ *
+ * @param refreshInterval
+ * refresh interval for the Stats(in seconds)
+ */
+ public void setRefreshIntervalForStatAlerts(int refreshInterval);
+
+ /**
+ * This method can be used to process the notifications sent by the member(s).
+ * Actual aggregation of stats can occur here. The array contains alert
+ * objects with alert def. ID & value. AlertHelper class can be used to
+ * retrieve the corresponding alert definition.
+ *
+ * @param alerts
+ * array of Alert class(contains alert def. ID & value)
+ * @param remoteVM
+ */
+ public void processNotifications(StatAlert[] alerts, GemFireVM remoteVM);
+
+ public void processSystemwideNotifications();
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticAttributeInfo.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticAttributeInfo.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticAttributeInfo.java
new file mode 100755
index 0000000..987dd25
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticAttributeInfo.java
@@ -0,0 +1,78 @@
+/*
+ * 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.geode.internal.admin.api.jmx.impl;
+
+import org.apache.geode.internal.admin.api.Statistic;
+import org.apache.geode.internal.Assert;
+
+import javax.management.Descriptor;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+
+/**
+ * Subclass of AttributeInfo with {@link Statistic}
+ * added for use as the {@link
+ * javax.management.modelmbean.ModelMBeanAttributeInfo} descriptor's
+ * <i>targetObject</i> value.
+ *
+ * @since GemFire 3.5
+ *
+ */
+class StatisticAttributeInfo extends org.apache.commons.modeler.AttributeInfo {
+ private static final long serialVersionUID = 28022387514935560L;
+
+ private Statistic stat;
+
+ public StatisticAttributeInfo() {
+ super();
+ }
+
+ public Statistic getStat() {
+ return this.stat;
+ }
+ public void setStat(Statistic stat) {
+ //System.out.println(">> stat = " + stat);
+ Assert.assertTrue(stat != null, "Attempting to set stat to null");
+ this.stat = stat;
+ }
+
+ @Override
+ public ModelMBeanAttributeInfo createAttributeInfo() {
+ Descriptor desc = new DescriptorSupport(
+ new String[] {
+ "name=" + this.displayName,
+ "descriptorType=attribute",
+ "currencyTimeLimit=-1", // always stale
+ "displayName=" + this.displayName,
+ "getMethod=getValue" });
+
+ Assert.assertTrue(this.stat != null, "Stat target object is null!");
+ desc.setField("targetObject", this.stat);
+
+ ModelMBeanAttributeInfo info = new ModelMBeanAttributeInfo(
+ this.displayName, // name
+ this.type, // type
+ this.description, // description
+ this.readable, // isReadable
+ this.writeable, // isWritable
+ this.is, // isIs
+ desc);
+
+ return info;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticResourceJmxImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticResourceJmxImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticResourceJmxImpl.java
new file mode 100755
index 0000000..ddd0cb7
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/StatisticResourceJmxImpl.java
@@ -0,0 +1,360 @@
+/*
+ * 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.geode.internal.admin.api.jmx.impl;
+
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.CancelException;
+import org.apache.geode.SystemFailure;
+import org.apache.geode.internal.admin.api.AdminException;
+import org.apache.geode.internal.admin.api.OperationCancelledException;
+import org.apache.geode.internal.admin.api.Statistic;
+import org.apache.geode.internal.admin.StatResource;
+import org.apache.geode.internal.admin.api.impl.StatisticResourceImpl;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+import org.apache.geode.internal.logging.LogService;
+
+/**
+ * Provides MBean support for the monitoring of a statistic resource.
+ *
+ * @since GemFire 3.5
+ *
+ */
+public class StatisticResourceJmxImpl
+extends StatisticResourceImpl
+implements javax.management.NotificationListener, ManagedResource {
+
+ private static final Logger logger = LogService.getLogger();
+
+ /**
+ * Interval in seconds between refreshes. Values less than one results in no
+ * refreshing .
+ */
+ private int refreshInterval = 0;
+
+ /** The JMX object name of this managed resource */
+ private ObjectName objectName;
+
+ /** A flag to indicate if time is inited. MBeanUtil lookup is costly */
+ private boolean timerInited = false;
+
+ // -------------------------------------------------------------------------
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Constructor for the StatisticResource object
+ *
+ * @param statResource the admin StatResource to manage/monitor
+ * @param member the SystemMember owning this resource
+ * @exception AdminException
+ * if unable to create this StatisticResource for administration
+ */
+ public StatisticResourceJmxImpl(StatResource statResource,
+ SystemMemberJmx member)
+ throws AdminException {
+ super(statResource, member);
+ initializeMBean();
+ }
+
+ /** Create and register the MBean to manage this resource */
+ private void initializeMBean()
+ throws AdminException {
+ this.mbeanName = new StringBuffer("GemFire.Statistic:")
+ .append("source=").append(MBeanUtil.makeCompliantMBeanNameProperty(this.member.getId()))
+ .append(",type=").append(MBeanUtil.makeCompliantMBeanNameProperty(getType()))
+ .append(",name=").append(MBeanUtil.makeCompliantMBeanNameProperty(getName()))
+ .append(",uid=").append(getUniqueId()).toString();
+
+ this.objectName =
+ MBeanUtil.createMBean(this,
+ addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
+
+ // Refresh Interval
+ AdminDistributedSystemJmxImpl sysJmx = (AdminDistributedSystemJmxImpl)this.member.getDistributedSystem();
+ if (sysJmx.getRefreshInterval()>0)
+ this.refreshInterval = sysJmx.getRefreshInterval();
+ }
+
+ // -------------------------------------------------------------------------
+ // MBean attributes - accessors/mutators
+ // -------------------------------------------------------------------------
+
+ /**
+ * Gets the interval in seconds between statistics refreshes
+ *
+ * @return the current refresh interval in seconds
+ */
+ public int getRefreshInterval() {
+ return this.refreshInterval;
+ }
+
+ /**
+ * Sets interval in seconds between statistic refreshes; zero or less turns
+ * off auto refreshing. Manual refreshing has no effect on when the next
+ * scheduled refresh will occur.
+ *
+ * @param refreshInterval the new refresh interval in seconds
+ */
+ private void _setRefreshInterval(int refreshInterval) {
+ boolean isRegistered = MBeanUtil.isRefreshNotificationRegistered(this,
+ RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS);
+
+ if (isRegistered && (getRefreshInterval() == refreshInterval))
+ return;
+
+ try {
+ MBeanUtil.registerRefreshNotification(
+ this, // NotificationListener
+ getMBeanName(), // User Data as MBean Name
+ RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS,
+ refreshInterval); // int
+
+ this.refreshInterval = refreshInterval;
+ timerInited = true;
+ } catch (RuntimeException e) {
+ logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
+ this.refreshInterval = 0; // zero out to avoid more exceptions
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+ this.refreshInterval = 0; // zero out to avoid more exceptions
+ }
+ }
+
+ /**
+ * RefreshInterval is now set only through the AdminDistributedSystem property
+ * refreshInterval. Attempt to set refreshInterval on StatisticResourceJmx
+ * MBean would result in an OperationNotSupportedException
+ * Auto-refresh is enabled on demand when a call to getStatistics is made
+ *
+ * @param refreshInterval
+ * the new refresh interval in seconds
+ * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
+ */
+ @Deprecated
+ public void setRefreshInterval(int refreshInterval)
+ throws OperationNotSupportedException {
+ throw new OperationNotSupportedException(
+ LocalizedStrings.MANAGED_RESOURCE_REFRESH_INTERVAL_CANT_BE_SET_DIRECTLY.toLocalizedString());
+ }
+
+ // -------------------------------------------------------------------------
+ // JMX Notification listener
+ // -------------------------------------------------------------------------
+
+ /**
+ * Handles notification to refresh. Reacts by refreshing the values of this
+ * SystemMember's ConfigurationParamaters. Any other notification is ignored.
+ * Given notification is handled only if there is any JMX client connected to
+ * the system.
+ * <p>
+ * TODO: investigate use of NotificationFilter instead of explicit check...
+ *
+ * @param notification
+ * the JMX notification being received
+ * @param hb
+ * handback object is unused
+ */
+ public void handleNotification(Notification notification, Object hb) {
+ AdminDistributedSystemJmxImpl adminDSJmx =
+ (AdminDistributedSystemJmxImpl) this.member.getDistributedSystem();
+
+ String typeStatResourceStats =
+ RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS.getType();
+
+ if (typeStatResourceStats.equals(notification.getType()) &&
+ getMBeanName().equals(notification.getUserData()) &&
+ !adminDSJmx.isRmiClientCountZero()) {
+ try {
+ refresh();
+
+ } catch (AdminException e) {
+ logger.warn(e.getMessage(), e);
+ } catch (OperationCancelledException e) {
+ // underlying resource is no longer reachable by remote admin
+ logger.warn(e.getMessage(), e);
+ _setRefreshInterval(0);
+ } catch (CancelException e) {
+ // shutting down - okay to ignore
+ } catch (java.lang.RuntimeException e) {
+ logger.debug(e.getMessage(), e); // dead in water, print, and then ignore
+ _setRefreshInterval(0); // zero out to avoid more exceptions
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (java.lang.Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+ this.refreshInterval = 0; // zero out to avoid more exceptions
+ }
+ }
+ }
+
+ // -------------------------------------------------------------------------
+ // Create MBean attributes for each Statistic
+ // -------------------------------------------------------------------------
+
+ /**
+ * Add MBean attribute definitions for each Statistic.
+ *
+ * @param managed the mbean definition to add attributes to
+ * @return a new instance of ManagedBean copied from <code>managed</code> but
+ * with the new attributes added
+ */
+ ManagedBean addDynamicAttributes(ManagedBean managed)
+ throws AdminException {
+ if (managed == null) {
+ throw new IllegalArgumentException(LocalizedStrings.StatisticResourceJmxImpl_MANAGEDBEAN_IS_NULL.toLocalizedString());
+ }
+
+ refresh(); // to get the stats...
+
+ // need to create a new instance of ManagedBean to clean the "slate"...
+ ManagedBean newManagedBean = new DynamicManagedBean(managed);
+ for (int i = 0; i < this.statistics.length; i++) {
+ StatisticAttributeInfo attrInfo = new StatisticAttributeInfo();
+
+ attrInfo.setName(this.statistics[i].getName());
+ attrInfo.setDisplayName(this.statistics[i].getName());
+ attrInfo.setDescription(this.statistics[i].getDescription());
+ attrInfo.setType("java.lang.Number");
+
+ attrInfo.setIs(false);
+ attrInfo.setReadable(true);
+ attrInfo.setWriteable(false);
+
+ attrInfo.setStat(this.statistics[i]);
+
+ newManagedBean.addAttribute(attrInfo);
+ }
+ return newManagedBean;
+ }
+
+ public Statistic[] getStatistics() {
+ if (!timerInited) {
+ // 1st call to getStatistics would trigger
+ // the auto-refresh if an interval is set
+ if (this.refreshInterval>0) {
+ this._setRefreshInterval(this.refreshInterval);
+ }
+ }
+
+ if (this.statistics == null) {
+ try {
+ this.refresh();
+ }
+ catch (AdminException e) {
+ this.statistics = new Statistic[0];
+ }
+ }
+
+ return this.statistics;
+ }
+
+ // -------------------------------------------------------------------------
+ // ManagedResource implementation
+ // -------------------------------------------------------------------------
+
+ /** The name of the MBean that will manage this resource */
+ private String mbeanName;
+
+ /** The ModelMBean that is configured to manage this resource */
+ private ModelMBean modelMBean;
+
+ public String getMBeanName() {
+ return this.mbeanName;
+ }
+
+ public ModelMBean getModelMBean() {
+ return this.modelMBean;
+ }
+ public void setModelMBean(ModelMBean modelMBean) {
+ this.modelMBean = modelMBean;
+ }
+
+ public ObjectName getObjectName() {
+ return this.objectName;
+ }
+
+ public ManagedResourceType getManagedResourceType() {
+ return ManagedResourceType.STATISTIC_RESOURCE;
+ }
+
+ public void cleanupResource() {
+ this.modelMBean = null;
+ this.member = null;
+ this.statistics = null;
+ this.statResource = null;
+ }
+
+ /**
+ * Checks equality of the given object with <code>this</code> based on the
+ * type (Class) and the MBean Name returned by <code>getMBeanName()</code>
+ * methods.
+ *
+ * @param obj
+ * object to check equality with
+ * @return true if the given object is if the same type and its MBean Name is
+ * same as <code>this</code> object's MBean Name, false otherwise
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof StatisticResourceJmxImpl) ) {
+ return false;
+ }
+
+ StatisticResourceJmxImpl other = (StatisticResourceJmxImpl) obj;
+
+ return this.getMBeanName().equals(other.getMBeanName());
+ }
+
+ /**
+ * Returns hash code for <code>this</code> object which is based on the MBean
+ * Name generated.
+ *
+ * @return hash code for <code>this</code> object
+ */
+ @Override
+ public int hashCode() {
+ return this.getMBeanName().hashCode();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberBridgeServerJmxImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberBridgeServerJmxImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberBridgeServerJmxImpl.java
new file mode 100644
index 0000000..3e16605
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberBridgeServerJmxImpl.java
@@ -0,0 +1,135 @@
+/*
+ * 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.geode.internal.admin.api.jmx.impl;
+
+import org.apache.geode.internal.admin.api.AdminException;
+import org.apache.geode.internal.admin.api.SystemMemberBridgeServer;
+import org.apache.geode.internal.admin.api.impl.SystemMemberBridgeServerImpl;
+import org.apache.geode.internal.admin.api.impl.SystemMemberCacheImpl;
+import org.apache.geode.internal.admin.AdminBridgeServer;
+import org.apache.geode.internal.admin.GemFireVM;
+
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+/**
+ * MBean representation of a {@link
+ * SystemMemberBridgeServer}.
+ *
+ * @since GemFire 4.0
+ */
+public class SystemMemberBridgeServerJmxImpl
+ extends SystemMemberBridgeServerImpl implements ManagedResource {
+
+ /** The object name of this managed resource */
+ private ObjectName objectName;
+
+ /** The name of the MBean that will manage this resource */
+ private String mbeanName;
+
+ /** The ModelMBean that is configured to manage this resource */
+ private ModelMBean modelMBean;
+
+ ////////////////////// Constructors //////////////////////
+
+ /**
+ * Creates a new <code>SystemMemberBridgeServerJmxImpl</code> that
+ * serves the contents of the given cache.
+ */
+ SystemMemberBridgeServerJmxImpl(SystemMemberCacheImpl cache,
+ AdminBridgeServer bridgeInfo)
+ throws AdminException {
+
+ super(cache, bridgeInfo);
+ initializeMBean(cache);
+ }
+
+ ////////////////////// Instance Methods //////////////////////
+
+ /**
+ * Creates and registers the MBean to manage this resource
+ */
+ private void initializeMBean(SystemMemberCacheImpl cache)
+ throws AdminException {
+
+ GemFireVM vm = cache.getVM();
+ this.mbeanName = new StringBuffer("GemFire.Cache:")
+ .append("name=")
+ .append(MBeanUtil.makeCompliantMBeanNameProperty(cache.getName()))
+ .append(",id=")
+ .append(this.getBridgeId())
+ .append(",owner=")
+ .append(MBeanUtil.makeCompliantMBeanNameProperty(vm.getId().toString()))
+ .append(",type=CacheServer").toString();
+
+ this.objectName = MBeanUtil.createMBean(this);
+ }
+
+ public String getMBeanName() {
+ return this.mbeanName;
+ }
+
+ public ModelMBean getModelMBean() {
+ return this.modelMBean;
+ }
+ public void setModelMBean(ModelMBean modelMBean) {
+ this.modelMBean = modelMBean;
+ }
+
+ public ObjectName getObjectName() {
+ return this.objectName;
+ }
+
+ public ManagedResourceType getManagedResourceType() {
+ return ManagedResourceType.SYSTEM_MEMBER_CACHE_SERVER;
+ }
+
+ public void cleanupResource() {}
+
+ /**
+ * Checks equality of the given object with <code>this</code> based on the
+ * type (Class) and the MBean Name returned by <code>getMBeanName()</code>
+ * methods.
+ *
+ * @param obj
+ * object to check equality with
+ * @return true if the given object is if the same type and its MBean Name is
+ * same as <code>this</code> object's MBean Name, false otherwise
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof SystemMemberBridgeServerJmxImpl) ) {
+ return false;
+ }
+
+ SystemMemberBridgeServerJmxImpl other =
+ (SystemMemberBridgeServerJmxImpl) obj;
+
+ return this.getMBeanName().equals(other.getMBeanName());
+ }
+
+ /**
+ * Returns hash code for <code>this</code> object which is based on the MBean
+ * Name generated.
+ *
+ * @return hash code for <code>this</code> object
+ */
+ @Override
+ public int hashCode() {
+ return this.getMBeanName().hashCode();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberCacheJmxImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberCacheJmxImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberCacheJmxImpl.java
new file mode 100644
index 0000000..8426ff1
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberCacheJmxImpl.java
@@ -0,0 +1,474 @@
+/*
+ * 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.geode.internal.admin.api.jmx.impl;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Level;
+
+import org.apache.geode.SystemFailure;
+import org.apache.geode.internal.admin.api.AdminException;
+import org.apache.geode.internal.admin.api.SystemMemberCache;
+import org.apache.geode.internal.admin.api.SystemMemberCacheServer;
+import org.apache.geode.internal.admin.api.SystemMemberRegion;
+import org.apache.geode.internal.admin.api.impl.SystemMemberBridgeServerImpl;
+import org.apache.geode.cache.Region;
+import org.apache.geode.internal.admin.AdminBridgeServer;
+import org.apache.geode.internal.admin.GemFireVM;
+import org.apache.geode.internal.admin.api.impl.SystemMemberCacheImpl;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+
+/**
+ * MBean representation of {@link SystemMemberCache}.
+ *
+ * @since GemFire 3.5
+ */
+public class SystemMemberCacheJmxImpl
+extends SystemMemberCacheImpl
+implements ManagedResource {
+
+ /** The object name of this managed resource */
+ private ObjectName objectName;
+
+ /** collection to collect all the resources created for this member */
+ private Map<String, SystemMemberRegionJmxImpl> managedRegionResourcesMap = new HashMap<String, SystemMemberRegionJmxImpl>();
+ private Map<Number, SystemMemberBridgeServerJmxImpl> managedCacheServerResourcesMap = new HashMap<Number, SystemMemberBridgeServerJmxImpl>();
+
+ // -------------------------------------------------------------------------
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Constructs an instance of SystemMemberCacheJmxImpl.
+ *
+ * @param vm
+ * The vm owning the cache this object will manage
+ */
+ public SystemMemberCacheJmxImpl(GemFireVM vm)
+ throws AdminException {
+ super(vm);
+ initializeMBean();
+ }
+
+ /** Create and register the MBean to manage this resource */
+ private void initializeMBean()
+ throws AdminException {
+ this.mbeanName = new StringBuffer("GemFire.Cache:")
+ .append("name=")
+ .append(MBeanUtil.makeCompliantMBeanNameProperty(getName()))
+ .append(",id=")
+ .append(getId())
+ .append(",owner=")
+ .append(MBeanUtil.makeCompliantMBeanNameProperty(vm.getId().toString()))
+ .append(",type=Cache").toString();
+
+ this.objectName =
+ MBeanUtil.createMBean(this,
+ addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
+ }
+
+ // -------------------------------------------------------------------------
+ // Template methods overriden from superclass...
+ // -------------------------------------------------------------------------
+
+ /**
+ * Override createSystemMemberRegion by instantiating
+ * SystemMemberRegionJmxImpl. This instance is also added to the
+ * managedResources collection.
+ *
+ * @param r
+ * reference to Region instance for which this JMX resource is to be
+ * created
+ * @return SystemMemberRegionJmxImpl - JMX Implementation of
+ * SystemMemberRegion
+ * @throws AdminException
+ * if constructing SystemMemberRegionJmxImpl instance fails
+ */
+ @Override
+ protected SystemMemberRegion createSystemMemberRegion(Region r)
+ throws AdminException {
+ SystemMemberRegionJmxImpl managedSystemMemberRegion = null;
+ boolean needsRefresh = false;
+ synchronized (this.managedRegionResourcesMap) {
+ /*
+ * Ensuring that a single instance of System Member Region is created
+ * per Region.
+ */
+ SystemMemberRegionJmxImpl managedResource = managedRegionResourcesMap.get(r.getFullPath());
+ if (managedResource != null) {
+ managedSystemMemberRegion = managedResource;
+ } else {
+ managedSystemMemberRegion = new SystemMemberRegionJmxImpl(this, r);
+ managedRegionResourcesMap.put(r.getFullPath(), managedSystemMemberRegion);
+ needsRefresh = true;
+ }
+ }
+ if (needsRefresh) {
+ managedSystemMemberRegion.refresh();
+ }
+ return managedSystemMemberRegion;
+ }
+
+ /**
+ * Creates a SystemMemberBridgeServerJmxImpl instance. This instance is also
+ * added to the managedResources collection.
+ *
+ * @param bridge
+ * reference to AdminBridgeServer for which this JMX resource is to
+ * be created
+ * @return SystemMemberBridgeServerJmxImpl - JMX Implementation of
+ * SystemMemberBridgeServerImpl
+ * @throws AdminException
+ * if constructing SystemMemberBridgeServerJmxImpl instance fails
+ */
+ @Override
+ protected SystemMemberBridgeServerImpl
+ createSystemMemberBridgeServer(AdminBridgeServer bridge)
+ throws AdminException {
+ SystemMemberBridgeServerJmxImpl managedSystemMemberBridgeServer = null;
+ synchronized (this.managedCacheServerResourcesMap) {
+ /*
+ * Ensuring that a single instance of SystemMember BridgeServer is
+ * created per AdminBridgeServer.
+ */
+ SystemMemberBridgeServerJmxImpl managedCacheServerResource = managedCacheServerResourcesMap.get(bridge.getId());
+ if (managedCacheServerResource != null) {
+ managedSystemMemberBridgeServer = managedCacheServerResource;
+ } else {
+ managedSystemMemberBridgeServer = new SystemMemberBridgeServerJmxImpl(this, bridge);
+ managedCacheServerResourcesMap.put(bridge.getId(), managedSystemMemberBridgeServer);
+ }
+ }
+ return managedSystemMemberBridgeServer;
+ }
+
+ // -------------------------------------------------------------------------
+ // Create MBean attributes for each Statistic
+ // -------------------------------------------------------------------------
+
+ /**
+ * Add MBean attribute definitions for each Statistic.
+ *
+ * @param managed the mbean definition to add attributes to
+ * @return a new instance of ManagedBean copied from <code>managed</code> but
+ * with the new attributes added
+ */
+ ManagedBean addDynamicAttributes(ManagedBean managed)
+ throws AdminException {
+ if (managed == null) {
+ throw new IllegalArgumentException(LocalizedStrings.SystemMemberCacheJmxImpl_MANAGEDBEAN_IS_NULL.toLocalizedString());
+ }
+
+ refresh(); // to get the stats...
+
+ // need to create a new instance of ManagedBean to clean the "slate"...
+ ManagedBean newManagedBean = new DynamicManagedBean(managed);
+ for (int i = 0; i < this.statistics.length; i++) {
+ StatisticAttributeInfo attrInfo = new StatisticAttributeInfo();
+
+ attrInfo.setName(this.statistics[i].getName());
+ attrInfo.setDisplayName(this.statistics[i].getName());
+ attrInfo.setDescription(this.statistics[i].getDescription());
+ attrInfo.setType("java.lang.Number");
+
+ attrInfo.setIs(false);
+ attrInfo.setReadable(true);
+ attrInfo.setWriteable(false);
+
+ attrInfo.setStat(this.statistics[i]);
+
+ newManagedBean.addAttribute(attrInfo);
+ }
+
+ return newManagedBean;
+ }
+
+ // -------------------------------------------------------------------------
+ // MBean Operations
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the ObjectName of the Region for the specified path.
+ *
+ * @throws AdminException
+ * If no region with path <code>path</code> exists
+ */
+ public ObjectName manageRegion(String path)
+ throws AdminException, MalformedObjectNameException {
+ try {
+ SystemMemberRegionJmxImpl region = null;
+
+ try {
+ region = (SystemMemberRegionJmxImpl) getRegion(path);
+
+ } catch (AdminException e) {
+ MBeanUtil.logStackTrace(Level.WARN, e);
+ throw e;
+ }
+
+ if (region == null) {
+ throw new AdminException(LocalizedStrings.SystemMemberCacheJmxImpl_THIS_CACHE_DOES_NOT_CONTAIN_REGION_0.toLocalizedString(path));
+
+ } else {
+ return ObjectName.getInstance(region.getMBeanName());
+ }
+ } catch (RuntimeException e) {
+ MBeanUtil.logStackTrace(Level.WARN, e);
+ throw e;
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ MBeanUtil.logStackTrace(Level.ERROR, e);
+ throw e;
+ }
+ }
+
+ /**
+ * Creates a new cache server MBean and returns its
+ * <code>ObjectName</code>.
+ *
+ * @since GemFire 5.7
+ */
+ public ObjectName manageCacheServer()
+ throws AdminException, MalformedObjectNameException {
+
+ try {
+ SystemMemberBridgeServerJmxImpl bridge =
+ (SystemMemberBridgeServerJmxImpl) addCacheServer();
+ return ObjectName.getInstance(bridge.getMBeanName());
+ } catch (AdminException e) {
+ MBeanUtil.logStackTrace(Level.WARN, e);
+ throw e;
+ } catch (RuntimeException e) {
+ MBeanUtil.logStackTrace(Level.WARN, e);
+ throw e;
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ MBeanUtil.logStackTrace(Level.ERROR, e);
+ throw e;
+ }
+ }
+
+ /**
+ * Returns the MBean <code>ObjectName</code>s for all cache servers
+ * that serve this cache to clients.
+ *
+ * @since GemFire 4.0
+ */
+ public ObjectName[] manageCacheServers()
+ throws AdminException, MalformedObjectNameException {
+
+ try {
+ SystemMemberCacheServer[] bridges = getCacheServers();
+ ObjectName[] names = new ObjectName[bridges.length];
+ for (int i = 0; i < bridges.length; i++) {
+ SystemMemberBridgeServerJmxImpl bridge =
+ (SystemMemberBridgeServerJmxImpl) bridges[i];
+ names[i] = ObjectName.getInstance(bridge.getMBeanName());
+ }
+
+ return names;
+ } catch (AdminException e) {
+ MBeanUtil.logStackTrace(Level.WARN, e);
+ throw e;
+ } catch (RuntimeException e) {
+ MBeanUtil.logStackTrace(Level.WARN, e);
+ throw e;
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ MBeanUtil.logStackTrace(Level.ERROR, e);
+ throw e;
+ }
+ }
+
+ /**
+ * Returns the MBean <code>ObjectName</code>s for all bridge servers
+ * that serve this cache.
+ *
+ * @since GemFire 4.0
+ * @deprecated as of 5.7
+ */
+ @Deprecated
+ public ObjectName[] manageBridgeServers()
+ throws AdminException, MalformedObjectNameException {
+ return manageCacheServers();
+ }
+
+ // -------------------------------------------------------------------------
+ // ManagedResource implementation
+ // -------------------------------------------------------------------------
+
+ /** The name of the MBean that will manage this resource */
+ private String mbeanName;
+
+ /** The ModelMBean that is configured to manage this resource */
+ private ModelMBean modelMBean;
+
+ public String getMBeanName() {
+ return this.mbeanName;
+ }
+
+ public ModelMBean getModelMBean() {
+ return this.modelMBean;
+ }
+ public void setModelMBean(ModelMBean modelMBean) {
+ this.modelMBean = modelMBean;
+ }
+
+ public ObjectName getObjectName() {
+ return this.objectName;
+ }
+
+ public ManagedResourceType getManagedResourceType() {
+ return ManagedResourceType.SYSTEM_MEMBER_CACHE;
+ }
+
+
+ /**
+ * Un-registers all the statistics & cache managed resource created for this
+ * member. After un-registering the resource MBean instances, clears
+ * this.memberResources collection.
+ *
+ * Creates ConfigurationParameterJmxImpl, StatisticResourceJmxImpl and
+ * SystemMemberCacheJmxImpl. But cleans up only StatisticResourceJmxImpl and
+ * SystemMemberCacheJmxImpl which are of type ManagedResource.
+ */
+ public void cleanupResource() {
+ synchronized (this.managedRegionResourcesMap) {
+ Collection<SystemMemberRegionJmxImpl> values = managedRegionResourcesMap.values();
+
+ for (SystemMemberRegionJmxImpl systemMemberRegionJmxImpl : values) {
+ MBeanUtil.unregisterMBean(systemMemberRegionJmxImpl);
+ }
+
+ this.managedRegionResourcesMap.clear();
+ }
+
+ synchronized (this.managedCacheServerResourcesMap) {
+ Collection<SystemMemberBridgeServerJmxImpl> values = managedCacheServerResourcesMap.values();
+
+ for (SystemMemberBridgeServerJmxImpl SystemMemberBridgeServerJmxImpl : values) {
+ MBeanUtil.unregisterMBean(SystemMemberBridgeServerJmxImpl);
+ }
+
+ this.managedCacheServerResourcesMap.clear();
+ }
+ }
+
+ /**
+ * Cleans up managed resources created for the region that was (created and)
+ * destroyed in a cache represented by this Managed Resource.
+ *
+ * @param regionPath
+ * path of the region that got destroyed
+ * @return a managed resource related to this region path
+ */
+ public ManagedResource cleanupRegionResources(String regionPath) {
+ ManagedResource cleaned = null;
+
+ synchronized (this.managedRegionResourcesMap) {
+ Set<Entry<String, SystemMemberRegionJmxImpl>> entries = managedRegionResourcesMap.entrySet();
+ for (Iterator<Entry<String, SystemMemberRegionJmxImpl>> it = entries.iterator(); it.hasNext();) {
+ Entry<String, SystemMemberRegionJmxImpl> entry = it.next();
+ SystemMemberRegionJmxImpl managedResource = entry.getValue();
+ ObjectName objName = managedResource.getObjectName();
+
+ String pathProp = objName.getKeyProperty("path");
+ if (pathProp != null && pathProp.equals(regionPath)) {
+ cleaned = managedResource;
+ it.remove();
+
+ break;
+ }
+ }
+ }
+
+ return cleaned;
+ }
+
+ /**
+ * Checks equality of the given object with <code>this</code> based on the
+ * type (Class) and the MBean Name returned by <code>getMBeanName()</code>
+ * methods.
+ *
+ * @param obj
+ * object to check equality with
+ * @return true if the given object is if the same type and its MBean Name is
+ * same as <code>this</code> object's MBean Name, false otherwise
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof SystemMemberCacheJmxImpl) ) {
+ return false;
+ }
+
+ SystemMemberCacheJmxImpl other = (SystemMemberCacheJmxImpl) obj;
+
+ return this.getMBeanName().equals(other.getMBeanName());
+ }
+
+ /**
+ * Returns hash code for <code>this</code> object which is based on the MBean
+ * Name generated.
+ *
+ * @return hash code for <code>this</code> object
+ */
+ @Override
+ public int hashCode() {
+ return this.getMBeanName().hashCode();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmx.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmx.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmx.java
new file mode 100644
index 0000000..afd6c7d
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmx.java
@@ -0,0 +1,501 @@
+/*
+ * 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.geode.internal.admin.api.jmx.impl;
+
+import org.apache.geode.SystemFailure;
+import org.apache.geode.cache.Operation;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.internal.admin.ClientMembershipMessage;
+import org.apache.geode.internal.admin.api.AdminException;
+import org.apache.geode.internal.admin.api.ConfigurationParameter;
+import org.apache.geode.internal.admin.api.OperationCancelledException;
+import org.apache.geode.internal.admin.api.StatisticResource;
+import org.apache.geode.internal.admin.api.SystemMember;
+import org.apache.geode.internal.admin.api.SystemMemberCache;
+import org.apache.geode.internal.admin.api.SystemMemberCacheEvent;
+import org.apache.geode.internal.admin.api.SystemMemberRegionEvent;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.logging.log4j.LocalizedMessage;
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Logger;
+
+import javax.management.*;
+import javax.naming.OperationNotSupportedException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Defines methods that all <code>SystemMember</code> MBeans should
+ * implement.
+ *
+ * @since GemFire 4.0
+ */
+public interface SystemMemberJmx
+ extends SystemMember, NotificationListener {
+ /**
+ * Notification type for indicating a cache got created on a member of this
+ * distributed system.
+ */
+ public static final String NOTIF_CACHE_CREATED =
+ DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.created";
+ /**
+ * Notification type for indicating a cache is closed on a member of this
+ * distributed system.
+ */
+ public static final String NOTIF_CACHE_CLOSED =
+ DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.closed";
+ /**
+ * Notification type for indicating a region is created in a cache on a member
+ * of this distributed system.
+ */
+ public static final String NOTIF_REGION_CREATED =
+ DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.region.created";
+ /**
+ * Notification type for indicating a region was removed from a cache on a
+ * member of this distributed system.
+ */
+ public static final String NOTIF_REGION_LOST =
+ DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.region.lost";
+
+ /** Notification type for indicating client joined */
+ public static final String NOTIF_CLIENT_JOINED =
+ DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.client.joined";
+
+ /** Notification type for indicating client left */
+ public static final String NOTIF_CLIENT_LEFT =
+ DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.client.left";
+
+ /** Notification type for indicating client crashed */
+ public static final String NOTIF_CLIENT_CRASHED =
+ DistributionConfig.GEMFIRE_PREFIX + "distributedsystem.cache.client.crashed";
+
+ /**
+ * Gets the interval in seconds between config refreshes
+ *
+ * @return the current refresh interval in seconds
+ */
+ public int getRefreshInterval();
+
+ /**
+ * RefreshInterval is now set only through the AdminDistributedSystem property
+ * refreshInterval. Attempt to set refreshInterval on SystemMemberJmx MBean
+ * would result in an OperationNotSupportedException Auto-refresh is enabled
+ * on demand when a call to refreshConfig is made
+ *
+ * @param refreshInterval
+ * the new refresh interval in seconds
+ * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
+ */
+ @Deprecated
+ public void setRefreshInterval(int refreshInterval) throws OperationNotSupportedException;
+
+ /**
+ * Sets the refresh interval field.
+ * Sets interval in seconds between config refreshes; zero or less turns
+ * off auto refreshing. Manual refreshing has no effect on when the next
+ * scheduled refresh will occur.
+ */
+ public void _setRefreshInterval(int refreshInterval);
+
+ /**
+ * Gets this member's cache.
+ *
+ * @return <code>ObjectName</code> for this member's cache
+ *
+ * @throws AdminException
+ * If this system member does not host a cache
+ */
+ public ObjectName manageCache()
+ throws AdminException, MalformedObjectNameException;
+
+ /**
+ * Gets all active StatisticResources for this manager.
+ *
+ * @return array of ObjectName instances
+ */
+ public ObjectName[] manageStats()
+ throws AdminException, MalformedObjectNameException;
+
+ /**
+ * Gets the active StatisticResources for this manager, based on the
+ * typeName as the key
+ *
+ * @return ObjectName of StatisticResourceJMX instance
+ */
+ public ObjectName[] manageStat(String statisticsTypeName)
+ throws AdminException, MalformedObjectNameException;
+
+ /**
+ * Handles notification to refresh. Reacts by refreshing the values of this
+ * GemFireManager's ConfigurationParamaters. Any other notification is
+ * ignored.
+ *
+ * @param notification the JMX notification being received
+ * @param hb handback object is unused
+ */
+ public void handleNotification(Notification notification, Object hb);
+
+ /**
+ * Add MBean attribute definitions for each ConfigurationParameter.
+ *
+ * @param managed the mbean definition to add attributes to
+ * @return a new instance of ManagedBean copied from <code>managed</code> but
+ * with the new attributes added
+ */
+ public ManagedBean addDynamicAttributes(ManagedBean managed)
+ throws AdminException;
+
+
+ /**
+ * Implementation should handle creation of cache by extracting the details
+ * from the given event object.
+ *
+ * @param event
+ * event object corresponding to the creation of the cache
+ */
+ public void handleCacheCreate(SystemMemberCacheEvent event);
+
+ /**
+ * Implementation should handle closure of cache by extracting the details
+ * from the given event object.
+ *
+ * @param event
+ * event object corresponding to the closure of the cache
+ */
+ public void handleCacheClose(SystemMemberCacheEvent event);
+
+ /**
+ * Implementation should handle creation of region by extracting the details
+ * from the given event object.
+ *
+ * @param event
+ * event object corresponding to the creation of a region
+ */
+ public void handleRegionCreate(SystemMemberRegionEvent event);
+
+ /**
+ * Implementation should handle loss of region by extracting the details
+ * from the given event object.
+ *
+ * @param event
+ * event object corresponding to the loss of a region
+ */
+ public void handleRegionLoss(SystemMemberRegionEvent event);
+
+ /**
+ * Implementation should handle client membership changes.
+ *
+ * @param clientId
+ * id of the client for whom membership change happened
+ * @param eventType
+ * membership change type; one of
+ * {@link ClientMembershipMessage#JOINED},
+ * {@link ClientMembershipMessage#LEFT},
+ * {@link ClientMembershipMessage#CRASHED}
+ */
+ public void handleClientMembership(String clientId, int eventType);
+
+ ////////////////////// Inner Classess //////////////////////
+
+ /**
+ * A helper class that provides implementation of the
+ * <code>SystemMemberJmx</code> interface as static methods.
+ */
+ public static class Helper {
+ private static final Logger logger = LogService.getLogger();
+
+ private static AtomicInteger notificationSequenceNumber = new AtomicInteger();
+
+ public static int setAndReturnRefreshInterval(SystemMemberJmx member,
+ int refreshInterval) {
+ int ret = refreshInterval;
+
+ try {
+ MBeanUtil.registerRefreshNotification(
+ member, // NotificationListener
+ ((ManagedResource)member).getMBeanName(), // User Data
+ RefreshNotificationType.SYSTEM_MEMBER_CONFIG,
+ refreshInterval); // int
+
+ } catch (RuntimeException e) {
+ logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
+ ret = 0; // zero out to avoid more exceptions
+
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+ ret = 0; // zero out to avoid more exceptions
+ }
+
+ return ret;
+ }
+
+ public static ObjectName manageCache(SystemMemberJmx member)
+ throws AdminException, MalformedObjectNameException {
+ boolean IthrewIt = false;
+ try {
+ SystemMemberCache cache = member.getCache();
+ if (cache == null) {
+ IthrewIt = true;
+ throw new AdminException(LocalizedStrings.SystemMemberJmx_THIS_SYSTEM_MEMBER_DOES_NOT_HAVE_A_CACHE.toLocalizedString());
+ }
+// Assert.assertTrue(cache != null); (cannot be null)
+ SystemMemberCacheJmxImpl cacheJmx = (SystemMemberCacheJmxImpl) cache;
+ return ObjectName.getInstance(cacheJmx.getMBeanName());
+ } catch (AdminException e) {
+ if (!IthrewIt) {
+ logger.warn(e.getMessage(), e);
+ }
+ throw e;
+ } catch (RuntimeException e) {
+ logger.warn(e.getMessage(), e);
+ throw e;
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ logger.error(e.getMessage(), e);
+ throw e;
+ }
+ }
+
+ public static ObjectName[] manageStats(SystemMemberJmx member)
+ throws AdminException, MalformedObjectNameException {
+ try {
+ StatisticResource[] stats = member.getStats();
+ ObjectName[] onames = new ObjectName[stats.length];
+ for (int i = 0; i < stats.length; i++) {
+ StatisticResourceJmxImpl stat =
+ (StatisticResourceJmxImpl) stats[i];
+ onames[i] = ObjectName.getInstance(stat.getMBeanName());
+ }
+ return onames;
+ } catch (AdminException e) {
+ logger.warn(e.getMessage(), e);
+ throw e;
+ } catch (RuntimeException e) {
+ logger.warn(e.getMessage(), e);
+ throw e;
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ logger.error(e.getMessage(), e);
+ throw e;
+ }
+ }
+
+ public static ObjectName[] manageStat(SystemMemberJmx member, String statisticsTypeName)
+ throws AdminException, MalformedObjectNameException {
+ try {
+ StatisticResource[] stats = member.getStat(statisticsTypeName);
+ if (stats==null)
+ return null;
+ else {
+ ObjectName[] statNames = new ObjectName[stats.length];
+ for (int i=0; i<stats.length; i++) {
+ StatisticResourceJmxImpl statJMX = (StatisticResourceJmxImpl) stats[i];
+ statNames[i] = ObjectName.getInstance(statJMX.getMBeanName());
+ }
+ return statNames;
+ }
+ } catch (AdminException e) {
+ logger.warn(e.getMessage(), e);
+ throw e;
+ } catch (RuntimeException e) {
+ logger.warn(e.getMessage(), e);
+ throw e;
+ } catch (Error e) {
+ logger.error(e.getMessage(), e);
+ throw e;
+ }
+ }
+
+ public static void handleNotification(SystemMemberJmx member,
+ Notification notification,
+ Object hb) {
+ if (RefreshNotificationType.SYSTEM_MEMBER_CONFIG.
+ getType().equals(notification.getType()) &&
+ ((ManagedResource)member).getMBeanName().
+ equals(notification.getUserData())
+ ) {
+
+ try {
+ member.refreshConfig();
+
+ } catch (AdminException e) {
+ logger.warn(e.getMessage(), e);
+ } catch (OperationCancelledException e) {
+ // underlying resource is no longer reachable by remote admin
+ logger.warn(e.getMessage(), e);
+ member._setRefreshInterval(0);
+
+ } catch (java.lang.RuntimeException e) {
+ logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
+ member._setRefreshInterval(0); // zero out to avoid more exceptions
+
+ } catch (VirtualMachineError err) {
+ SystemFailure.initiateFailure(err);
+ // If this ever returns, rethrow the error. We're poisoned
+ // now, so don't let this thread continue.
+ throw err;
+ } catch (java.lang.Error e) {
+ // Whenever you catch Error or Throwable, you must also
+ // catch VirtualMachineError (see above). However, there is
+ // _still_ a possibility that you are dealing with a cascading
+ // error condition, so you also need to check to see if the JVM
+ // is still usable:
+ SystemFailure.checkFailure();
+ logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+ member._setRefreshInterval(0); // zero out to avoid more exceptions
+ }
+ }
+ }
+
+ public static ManagedBean
+ addDynamicAttributes(SystemMemberJmx member, ManagedBean managed)
+ throws AdminException {
+
+ if (managed == null) {
+ throw new IllegalArgumentException(LocalizedStrings.SystemMemberJmx_MANAGEDBEAN_IS_NULL.toLocalizedString());
+ }
+
+ member.refreshConfig(); // to get the config parms...
+
+ // need to create a new instance of ManagedBean to clean the "slate"...
+ ManagedBean newManagedBean = new DynamicManagedBean(managed);
+ ConfigurationParameter[] params = member.getConfiguration();
+ for (int i = 0; i < params.length; i++) {
+ ConfigurationParameterJmxImpl parm =
+ (ConfigurationParameterJmxImpl) params[i];
+ ConfigAttributeInfo attrInfo = new ConfigAttributeInfo(parm);
+
+ attrInfo.setName(parm.getName());
+ attrInfo.setDisplayName(parm.getName());
+ attrInfo.setDescription(parm.getDescription());
+ attrInfo.setType(parm.getJmxValueType().getName());
+
+ attrInfo.setIs(false);
+ attrInfo.setReadable(true);
+ attrInfo.setWriteable(parm.isModifiable());
+
+ newManagedBean.addAttribute(attrInfo);
+ }
+ return newManagedBean;
+ }
+
+ /**
+ * Returns the next notification sequence number.
+ *
+ * @return the notificationSequenceNumber
+ */
+ /*default*/static int getNextNotificationSequenceNumber() {
+ return notificationSequenceNumber.incrementAndGet();
+ }
+
+ /**
+ * Returns the cache event details extracted from the given
+ * SystemMemberCacheEvent
+ *
+ * @param event
+ * SystemMemberCacheEvent instance
+ * @return the cache event details extracted from the given
+ * SystemMemberCacheEvent
+ */
+ /*default*/static String getCacheEventDetails(SystemMemberCacheEvent event) {
+ String memberId = event.getMemberId();
+ Operation operation = event.getOperation();
+
+ return "CacheEvent[MemberId: "+memberId+", operation: "+operation+"]";
+ }
+
+ /**
+ * Returns the region event details extracted from the given
+ * SystemMemberRegionEvent
+ *
+ * @param event
+ * SystemMemberRegionEvent instance
+ * @return the cache event details extracted from the given
+ * SystemMemberRegionEvent
+ */
+ /*default*/static String getRegionEventDetails(SystemMemberRegionEvent event) {
+ String memberId = event.getMemberId();
+ Operation operation = event.getOperation();
+
+ return "RegionEvent[MemberId: " + memberId + ", operation: " + operation
+ + ", region:" + event.getRegionPath() + "]";
+ }
+
+ /**
+ * Sends the given notification.
+ *
+ * @param notif
+ * notification to send
+ *
+ * @throws NullPointerException
+ * if resource or ModelMBean for resource is null
+ */
+ /*default*/static void sendNotification(ManagedResource resource, Notification notif) {
+ try {
+ if (MBeanUtil.isRegistered(resource.getObjectName())) {
+ resource.getModelMBean().sendNotification(notif);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Sent '{}' notification", notif.getType());
+ }
+ }
+ } catch (RuntimeOperationsException e) {
+ logger.info(LocalizedMessage.create(
+ LocalizedStrings.SystemMemberJmx_FAILED_TO_SEND_0_NOTIFICATION_FOR_1,
+ new Object[] { "'" + notif.getType() + "'",
+ "'" + notif.getMessage() + "'" }),
+ e);
+ } catch (MBeanException e) {
+ logger.info(LocalizedMessage.create(
+ LocalizedStrings.SystemMemberJmx_FAILED_TO_SEND_0_NOTIFICATION_FOR_1,
+ new Object[] { "'" + notif.getType() + "'",
+ "'" + notif.getMessage() + "'" }),
+ e);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmxImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmxImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmxImpl.java
new file mode 100755
index 0000000..0375218
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/SystemMemberJmxImpl.java
@@ -0,0 +1,591 @@
+/*
+ * 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.geode.internal.admin.api.jmx.impl;
+
+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 java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.internal.admin.api.AdminException;
+import org.apache.geode.internal.admin.api.ConfigurationParameter;
+import org.apache.geode.internal.admin.api.StatisticResource;
+import org.apache.geode.internal.admin.api.SystemMemberCache;
+import org.apache.geode.internal.admin.api.SystemMemberCacheEvent;
+import org.apache.geode.internal.admin.api.SystemMemberRegionEvent;
+import org.apache.geode.internal.admin.api.impl.ConfigurationParameterImpl;
+import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
+import org.apache.geode.internal.admin.ApplicationVM;
+import org.apache.geode.internal.admin.ClientMembershipMessage;
+import org.apache.geode.internal.admin.GemFireVM;
+import org.apache.geode.internal.admin.StatResource;
+import org.apache.geode.internal.admin.api.impl.SystemMemberImpl;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+import org.apache.geode.internal.logging.LogService;
+
+/**
+ * Provides MBean support for managing a SystemMember application.
+ * <p>
+ * TODO: refactor to implement SystemMember and delegate to SystemMemberImpl.
+ * Wrap all delegate calls w/ e.printStackTrace() since the HttpAdaptor devours
+ * them
+ *
+ * @since GemFire 3.5
+ *
+ */
+public class SystemMemberJmxImpl
+extends SystemMemberImpl
+implements SystemMemberJmx, javax.management.NotificationListener, ManagedResource {
+
+ private static final Logger logger = LogService.getLogger();
+
+ /**
+ * Interval in seconds between refreshes. Value less than one results in no
+ * refreshing
+ */
+ private int refreshInterval = 0;
+
+ /** The JMX object name of this managed resource */
+ private ObjectName objectName;
+
+ /** Reference to the cache MBean representing a Cache in the Cache VM Member */
+ private SystemMemberCacheJmxImpl managedSystemMemberCache;
+
+ /** collection to collect all the resources created for this member */
+ private Map<StatResource, StatisticResourceJmxImpl> managedStatisticsResourcesMap = new HashMap<StatResource, StatisticResourceJmxImpl>();
+
+
+ // -------------------------------------------------------------------------
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Constructs an instance of SystemMemberJmxImpl.
+ *
+ * @param system the distributed system this SystemMember is a member of
+ * @param application the internal admin application to delegate actual work
+ */
+ public SystemMemberJmxImpl(AdminDistributedSystemJmxImpl system,
+ ApplicationVM application)
+ throws AdminException {
+ super(system, application);
+ initializeMBean();
+ }
+
+ /**
+ * Constructs the instance of SystemMember using the corresponding
+ * InternalDistributedMember instance of a DS member for the given
+ * AdminDistributedSystem.
+ *
+ * @param system
+ * Current AdminDistributedSystem instance
+ * @param member
+ * InternalDistributedMember instance for which a SystemMember
+ * instance is to be constructed.
+ * @throws AdminException
+ * if construction of SystemMember fails
+ *
+ * @since GemFire 6.5
+ */
+ protected SystemMemberJmxImpl(AdminDistributedSystemJmxImpl system,
+ InternalDistributedMember member) throws AdminException {
+ super(system, member);
+ initializeMBean();
+ }
+
+ /** Create and register the MBean to manage this resource */
+ private void initializeMBean()
+ throws AdminException {
+ //initialize Managed Resources for stats & cache first.
+// initializeManagedResources();
+
+ this.mbeanName = new StringBuffer("GemFire.Member:id=")
+ .append(MBeanUtil.makeCompliantMBeanNameProperty(getId()))
+ .append(",type=").append(MBeanUtil.makeCompliantMBeanNameProperty(getType().getName())).toString();
+
+ this.objectName =
+ MBeanUtil.createMBean(this,
+ addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
+
+ // Refresh Interval
+ AdminDistributedSystemJmxImpl sysJmx = (AdminDistributedSystemJmxImpl)system;
+ if (sysJmx.getRefreshInterval() > 0)
+ this.refreshInterval = sysJmx.getRefreshInterval();
+ }
+
+ // -------------------------------------------------------------------------
+ // MBean attributes - accessors/mutators
+ // -------------------------------------------------------------------------
+
+ /**
+ * Gets the interval in seconds between config refreshes
+ *
+ * @return the current refresh interval in seconds
+ */
+ public int getRefreshInterval() {
+ return this.refreshInterval;
+ }
+
+ /**
+ * RefreshInterval is now set only through the AdminDistributedSystem property
+ * refreshInterval. Attempt to set refreshInterval on SystemMemberJmx MBean
+ * would result in an OperationNotSupportedException Auto-refresh is enabled
+ * on demand when a call to refreshConfig is made
+ *
+ * @param refreshInterval
+ * the new refresh interval in seconds
+ * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
+ */
+ @Deprecated
+ public void setRefreshInterval(int refreshInterval)
+ throws OperationNotSupportedException {
+ throw new OperationNotSupportedException(
+ LocalizedStrings.MANAGED_RESOURCE_REFRESH_INTERVAL_CANT_BE_SET_DIRECTLY.toLocalizedString());
+ }
+
+ /**
+ * Sets interval in seconds between member config refreshes; zero or less
+ * turns off auto refreshing. Manual refreshing has no effect on when the next
+ * scheduled refresh will occur.
+ *
+ * @param refreshInterval
+ * the new refresh interval in seconds
+ */
+ public void _setRefreshInterval(int refreshInterval) {
+ boolean isRegistered = MBeanUtil.isRefreshNotificationRegistered(this,
+ RefreshNotificationType.SYSTEM_MEMBER_CONFIG);
+
+ if (isRegistered && (getRefreshInterval() == refreshInterval))
+ return;
+
+ this.refreshInterval = Helper.setAndReturnRefreshInterval(this,
+ refreshInterval);
+ }
+
+ // -------------------------------------------------------------------------
+ // MBean Operations
+ // -------------------------------------------------------------------------
+
+ public void refreshConfig() throws AdminException {
+ // 1st call to refreshConfig would trigger
+ // the auto-refresh if an interval is set
+ if (this.refreshInterval > 0) {
+ this._setRefreshInterval(this.refreshInterval);
+ }
+
+ super.refreshConfig();
+ }
+
+ /**
+ * Initializes Cache & Statistics managed resources.
+ *
+ * @throws AdminException
+ * if initialization of managed resources fails
+ */
+// private void initializeManagedResources() throws AdminException {
+// try {
+// manageCache();
+// } catch (MalformedObjectNameException e) {
+// throw new AdminException(LocalizedStrings.SystemMemberJmxImpl_EXCEPTION_OCCURRED_WHILE_INITIALIZING_0_MBEANS_FOR_1.toLocalizedString(
+// new Object[] {"Cache", getId()}),
+// e);
+// } catch (AdminException ae) {
+// if (LocalizedStrings.SystemMemberJmx_THIS_SYSTEM_MEMBER_DOES_NOT_HAVE_A_CACHE.toLocalizedString().equals(ae.getMessage())) {
+// //ignore this exception for a cache-less peer
+// } else {
+// throw ae;
+// }
+// }
+// try {
+// manageStats();
+// } catch (MalformedObjectNameException e) {
+// throw new AdminException(LocalizedStrings.SystemMemberJmxImpl_EXCEPTION_OCCURRED_WHILE_INITIALIZING_0_MBEANS_FOR_1.toLocalizedString(
+// new Object[] {"Statistics", getId()}),
+// e);
+// }
+// }
+
+ /**
+ * Gets this member's cache.
+ *
+ * @return <code>ObjectName</code> for this member's cache
+ *
+ * @throws AdminException
+ * If this system member does not host a cache
+ */
+ public ObjectName manageCache()
+ throws AdminException, MalformedObjectNameException {
+
+ return Helper.manageCache(this);
+ }
+
+ /**
+ * Gets all active StatisticResources for this manager.
+ *
+ * @return array of ObjectName instances
+ */
+ public ObjectName[] manageStats()
+ throws AdminException, MalformedObjectNameException {
+
+ return Helper.manageStats(this);
+ }
+
+ /**
+ * Gets the active StatisticResources for this manager, based on the
+ * typeName as the key
+ *
+ * @return ObjectName of StatisticResourceJMX instance
+ */
+ public ObjectName[] manageStat(String statisticsTypeName)
+ throws AdminException, MalformedObjectNameException {
+
+ return Helper.manageStat(this, statisticsTypeName);
+ }
+
+ // -------------------------------------------------------------------------
+ // JMX Notification listener
+ // -------------------------------------------------------------------------
+
+ /**
+ * Handles notification to refresh. Reacts by refreshing the values of this
+ * SystemMember's ConfigurationParamaters. Any other notification is ignored.
+ * Given notification is handled only if there is any JMX client connected to
+ * the system.
+ *
+ * @param notification
+ * the JMX notification being received
+ * @param hb
+ * handback object is unused
+ */
+ public void handleNotification(Notification notification, Object hb) {
+ AdminDistributedSystemJmxImpl systemJmx =
+ (AdminDistributedSystemJmxImpl) this.system;
+
+ if (!systemJmx.isRmiClientCountZero()) {
+ Helper.handleNotification(this, notification, hb);
+ }
+ }
+
+ // -------------------------------------------------------------------------
+ // Template methods overriden from superclass...
+ // -------------------------------------------------------------------------
+
+ /**
+ * Template method for creating instance of ConfigurationParameter.
+ * Overridden to return ConfigurationParameterJmxImpl.
+ */
+ @Override
+ protected ConfigurationParameter createConfigurationParameter(String name,
+ String description,
+ Object value,
+ Class type,
+ boolean userModifiable) {
+ return new ConfigurationParameterJmxImpl(
+ name, description, value, type, userModifiable);
+ }
+
+ /**
+ * Override createStatisticResource by instantiating StatisticResourceJmxImpl
+ * if it was not created earlier otherwise returns the same instance.
+ *
+ * @param stat
+ * StatResource reference for which this JMX resource is to be created
+ * @return StatisticResourceJmxImpl - JMX Implementation of StatisticResource
+ * @throws AdminException
+ * if constructing StatisticResourceJmxImpl instance fails
+ */
+ @Override
+ protected StatisticResource createStatisticResource(StatResource stat)
+ throws AdminException {
+ StatisticResourceJmxImpl managedStatisticResource = null;
+
+ synchronized (this.managedStatisticsResourcesMap) {
+ /*
+ * Ensuring that a single instance of Statistic Resource is created per
+ * StatResource.
+ */
+ StatisticResourceJmxImpl statisticResourceJmxImpl = managedStatisticsResourcesMap.get(stat);
+ if (statisticResourceJmxImpl != null) {
+ managedStatisticResource = statisticResourceJmxImpl;
+ } else {
+ managedStatisticResource = new StatisticResourceJmxImpl(stat, this);
+ managedStatisticResource.getStatistics();//inits timer
+ managedStatisticsResourcesMap.put(stat, managedStatisticResource);
+ }
+ }
+ return managedStatisticResource;
+ }
+
+ /**
+ * Override createSystemMemberCache by instantiating SystemMemberCacheJmxImpl
+ * if it was not created earlier.
+ *
+ * @param vm
+ * GemFireVM reference for which this JMX resource is to be created
+ * @return SystemMemberCacheJmxImpl - JMX Implementation of SystemMemberCache
+ * @throws AdminException
+ * if constructing SystemMemberCacheJmxImpl instance fails
+ */
+ @Override
+ protected SystemMemberCache createSystemMemberCache(GemFireVM vm)
+ throws AdminException {
+ if (managedSystemMemberCache == null) {
+ managedSystemMemberCache = new SystemMemberCacheJmxImpl(vm);
+ }
+ return managedSystemMemberCache;
+ }
+
+ // -------------------------------------------------------------------------
+ // Create MBean attributes for each ConfigurationParameter
+ // -------------------------------------------------------------------------
+
+ /**
+ * Add MBean attribute definitions for each ConfigurationParameter.
+ *
+ * @param managed the mbean definition to add attributes to
+ * @return a new instance of ManagedBean copied from <code>managed</code> but
+ * with the new attributes added
+ */
+ public ManagedBean addDynamicAttributes(ManagedBean managed)
+ throws AdminException {
+
+ return Helper.addDynamicAttributes(this, managed);
+ }
+
+ // -------------------------------------------------------------------------
+ // ManagedResource implementation
+ // -------------------------------------------------------------------------
+
+ /** The name of the MBean that will manage this resource */
+ private String mbeanName;
+
+ /** The ModelMBean that is configured to manage this resource */
+ private ModelMBean modelMBean;
+
+ public String getMBeanName() {
+ return this.mbeanName;
+ }
+
+ public ModelMBean getModelMBean() {
+ return this.modelMBean;
+ }
+ public void setModelMBean(ModelMBean modelMBean) {
+ this.modelMBean = modelMBean;
+ }
+
+ public ObjectName getObjectName() {
+ return this.objectName;
+ }
+
+ public ManagedResourceType getManagedResourceType() {
+ return ManagedResourceType.SYSTEM_MEMBER;
+ }
+
+ /**
+ * Un-registers all the statistics & cache managed resource created for this
+ * member. After un-registering the resource MBean instances, clears
+ * managedStatisticsResourcesMap collection.
+ */
+ public void cleanupResource() {
+ synchronized (this.managedStatisticsResourcesMap) {
+ ConfigurationParameter[] names = getConfiguration();
+ if (names != null) {
+ for (int i = 0; i < names.length; i++) {
+ ConfigurationParameter parm = names[i];
+ ((ConfigurationParameterImpl) parm).removeConfigurationParameterListener(this);
+ }
+ }
+ this.parms.clear();
+
+ Collection<StatisticResourceJmxImpl> statisticResources = managedStatisticsResourcesMap.values();
+
+ for (StatisticResourceJmxImpl statisticResource : statisticResources) {
+ MBeanUtil.unregisterMBean(statisticResource);
+ }
+
+ this.managedStatisticsResourcesMap.clear();
+ }
+ MBeanUtil.unregisterMBean(managedSystemMemberCache);
+ }
+
+
+ /**
+ * Cleans up Managed Resources created for the client that was connected to
+ * the server represented by this class.
+ *
+ * @param clientId
+ * id of the client to be removed
+ * @return List of ManagedResources associated with the client of given client
+ * id
+ */
+ /*
+ * This clean up is for the clients. The clients are started with a loner DM.
+ * Hence the clientId is not supposed to contain '/' as per
+ * InternalDistributedMember.toString().
+ */
+ public List<ManagedResource> cleanupBridgeClientResources(String clientId) {
+ List<ManagedResource> returnedResources = new ArrayList<ManagedResource>();
+
+ String compatibleId = "id_"+MBeanUtil.makeCompliantMBeanNameProperty(clientId);
+ synchronized (this.managedStatisticsResourcesMap) {
+ Set<Entry<StatResource, StatisticResourceJmxImpl>> entrySet = this.managedStatisticsResourcesMap.entrySet();
+
+ for (Iterator<Entry<StatResource, StatisticResourceJmxImpl>> it = entrySet.iterator(); it.hasNext();) {
+ Entry<StatResource, StatisticResourceJmxImpl> entry = it.next();
+ StatisticResourceJmxImpl resource = entry.getValue();
+ if (resource.getMBeanName().contains(compatibleId)) {
+ it.remove(); //remove matching entry
+ returnedResources.add(resource);
+ }
+ }
+ }
+ return returnedResources;
+ }
+
+ /**
+ * Implementation handles client membership changes.
+ *
+ * @param clientId
+ * id of the client for whom membership change happened
+ * @param eventType
+ * membership change type; one of
+ * {@link ClientMembershipMessage#JOINED},
+ * {@link ClientMembershipMessage#LEFT},
+ * {@link ClientMembershipMessage#CRASHED}
+ */
+ public void handleClientMembership(String clientId, int eventType) {
+ String notifType = null;
+ List<ManagedResource> cleanedUp = null;
+
+ if (eventType == ClientMembershipMessage.LEFT) {
+ notifType = NOTIF_CLIENT_LEFT;
+ cleanedUp = cleanupBridgeClientResources(clientId);
+ } else if (eventType == ClientMembershipMessage.CRASHED) {
+ notifType = NOTIF_CLIENT_CRASHED;
+ cleanedUp = cleanupBridgeClientResources(clientId);
+ } else if (eventType == ClientMembershipMessage.JOINED) {
+ notifType = NOTIF_CLIENT_JOINED;
+ }
+
+ if (cleanedUp != null) {
+ for (ManagedResource resource : cleanedUp) {
+ MBeanUtil.unregisterMBean(resource);
+ }
+ }
+
+ Helper.sendNotification(this,
+ new Notification(notifType, this.modelMBean,
+ Helper.getNextNotificationSequenceNumber(),
+ clientId));
+ }
+
+ /**
+ * Implementation handles creation of cache by extracting the details from the
+ * given event object and sending the
+ * {@link SystemMemberJmx#NOTIF_CACHE_CREATED} notification to the connected
+ * JMX Clients.
+ *
+ * @param event
+ * event object corresponding to the creation of the cache
+ */
+ public void handleCacheCreate(SystemMemberCacheEvent event) {
+ Helper.sendNotification(this,
+ new Notification(NOTIF_CACHE_CREATED, this.modelMBean,
+ Helper.getNextNotificationSequenceNumber(),
+ Helper.getCacheEventDetails(event)));
+ }
+
+ /**
+ * Implementation handles closure of cache by extracting the details from the
+ * given event object and sending the
+ * {@link SystemMemberJmx#NOTIF_CACHE_CLOSED} notification to the connected
+ * JMX Clients.
+ *
+ * @param event
+ * event object corresponding to the closure of the cache
+ */
+ public void handleCacheClose(SystemMemberCacheEvent event) {
+ Helper.sendNotification(this,
+ new Notification(NOTIF_CACHE_CLOSED, this.modelMBean,
+ Helper.getNextNotificationSequenceNumber(),
+ Helper.getCacheEventDetails(event)));
+ }
+
+ /**
+ * Implementation handles creation of region by extracting the details from
+ * the given event object and sending the
+ * {@link SystemMemberJmx#NOTIF_REGION_CREATED} notification to the connected
+ * JMX Clients. Region Path is set as User Data in Notification.
+ *
+ * @param event
+ * event object corresponding to the creation of a region
+ */
+ public void handleRegionCreate(SystemMemberRegionEvent event) {
+ Notification notification = new Notification(NOTIF_REGION_CREATED, this.modelMBean,
+ Helper.getNextNotificationSequenceNumber(),
+ Helper.getRegionEventDetails(event));
+
+ notification.setUserData(event.getRegionPath());
+
+ Helper.sendNotification(this, notification);
+ }
+
+ /**
+ * Implementation should handle loss of region by extracting the details from
+ * the given event object and sending the
+ * {@link SystemMemberJmx#NOTIF_REGION_LOST} notification to the connected
+ * JMX Clients. Region Path is set as User Data in Notification. Additionally,
+ * it also clears the ManagedResources created for the region that is lost.
+ *
+ * @param event
+ * event object corresponding to the loss of a region
+ */
+ public void handleRegionLoss(SystemMemberRegionEvent event) {
+ SystemMemberCacheJmxImpl cacheResource = this.managedSystemMemberCache;
+
+ if (cacheResource != null) {
+ ManagedResource cleanedUp =
+ cacheResource.cleanupRegionResources(event.getRegionPath());
+
+ if (cleanedUp != null) {
+ MBeanUtil.unregisterMBean(cleanedUp);
+ }
+ }
+
+ Notification notification = new Notification(NOTIF_REGION_LOST, this.modelMBean,
+ Helper.getNextNotificationSequenceNumber(),
+ Helper.getRegionEventDetails(event));
+
+ notification.setUserData(event.getRegionPath());
+
+ Helper.sendNotification(this, notification);
+ }
+}
+