All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.admin.jmx.internal.SystemMemberJmxImpl Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed 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. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.admin.jmx.internal;

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 com.gemstone.gemfire.admin.AdminException;
import com.gemstone.gemfire.admin.ConfigurationParameter;
import com.gemstone.gemfire.admin.StatisticResource;
import com.gemstone.gemfire.admin.SystemMemberCache;
import com.gemstone.gemfire.admin.SystemMemberCacheEvent;
import com.gemstone.gemfire.admin.SystemMemberRegionEvent;
import com.gemstone.gemfire.admin.internal.ConfigurationParameterImpl;
import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
import com.gemstone.gemfire.i18n.LogWriterI18n;
import com.gemstone.gemfire.internal.admin.ApplicationVM;
import com.gemstone.gemfire.internal.admin.ClientMembershipMessage;
import com.gemstone.gemfire.internal.admin.GemFireVM;
import com.gemstone.gemfire.internal.admin.StatResource;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;

/**
 * Provides MBean support for managing a SystemMember application.
 * 

* TODO: refactor to implement SystemMember and delegate to SystemMemberImpl. * Wrap all delegate calls w/ e.printStackTrace() since the HttpAdaptor devours * them * * @author Kirk Lund * @since 3.5 * */ public class SystemMemberJmxImpl extends com.gemstone.gemfire.admin.internal.SystemMemberImpl implements SystemMemberJmx, javax.management.NotificationListener, com.gemstone.gemfire.admin.jmx.internal.ManagedResource { /** * 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 managedStatisticsResourcesMap = new HashMap(); // ------------------------------------------------------------------------- // 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 com.gemstone.gemfire.admin.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 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 com.gemstone.gemfire.admin.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 com.gemstone.gemfire.admin.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 // this.system.getLogWriter().convertToLogWriterI18n().info(LocalizedStrings.SystemMemberJmxImpl_CACHE_INSTANCE_NOT_FOUND_IN_0, getId()); // } 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 ObjectName 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 com.gemstone.gemfire.admin.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 com.gemstone.gemfire.admin.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 managed 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 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 cleanupBridgeClientResources(String clientId) { List returnedResources = new ArrayList(); String compatibleId = "id_"+MBeanUtil.makeCompliantMBeanNameProperty(clientId); synchronized (this.managedStatisticsResourcesMap) { Set> entrySet = this.managedStatisticsResourcesMap.entrySet(); for (Iterator> it = entrySet.iterator(); it.hasNext();) { Entry 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) { LogWriterI18n logWriterI18n = this.getDistributedSystem().getLogWriter().convertToLogWriterI18n(); String notifType = null; List 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(logWriterI18n, 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) { LogWriterI18n logWriterI18n = this.getDistributedSystem().getLogWriter().convertToLogWriterI18n(); Helper.sendNotification(logWriterI18n, 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) { LogWriterI18n logWriterI18n = this.getDistributedSystem().getLogWriter().convertToLogWriterI18n(); Helper.sendNotification(logWriterI18n, 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) { LogWriterI18n logWriterI18n = this.getDistributedSystem().getLogWriter().convertToLogWriterI18n(); Notification notification = new Notification(NOTIF_REGION_CREATED, this.modelMBean, Helper.getNextNotificationSequenceNumber(), Helper.getRegionEventDetails(event)); notification.setUserData(event.getRegionPath()); Helper.sendNotification(logWriterI18n, 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); } } LogWriterI18n logWriterI18n = this.getDistributedSystem().getLogWriter().convertToLogWriterI18n(); Notification notification = new Notification(NOTIF_REGION_LOST, this.modelMBean, Helper.getNextNotificationSequenceNumber(), Helper.getRegionEventDetails(event)); notification.setUserData(event.getRegionPath()); Helper.sendNotification(logWriterI18n, this, notification); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy