http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MemberInfoWithStatsMBean.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MemberInfoWithStatsMBean.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MemberInfoWithStatsMBean.java deleted file mode 100644 index ac75f38..0000000 --- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MemberInfoWithStatsMBean.java +++ /dev/null @@ -1,1352 +0,0 @@ -/* - * 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.admin.jmx.internal; - -import static org.apache.geode.distributed.ConfigurationProperties.*; - -import org.apache.geode.admin.*; -import org.apache.geode.admin.jmx.Agent; -import org.apache.geode.cache.InterestPolicy; -import org.apache.geode.cache.SubscriptionAttributes; -import org.apache.geode.distributed.internal.DistributionConfig; -import org.apache.geode.internal.GemFireVersion; -import org.apache.geode.internal.admin.remote.ClientHealthStats; -import org.apache.geode.internal.i18n.LocalizedStrings; -import org.apache.geode.internal.logging.LogService; -import org.apache.geode.internal.logging.log4j.LocalizedMessage; -import mx4j.AbstractDynamicMBean; -import org.apache.logging.log4j.Logger; - -import javax.management.*; -import java.net.InetAddress; -import java.text.MessageFormat; -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; - -/** - * This class uses the JMX Attributes/Operations that use (return/throw) - * GemFire types. This is the single MBean accessible with ObjectName string - * {@link MemberInfoWithStatsMBean#MBEAN_NAME}}. This MBean can be used to - * retrieve the all member details as plain java types. - * - * This MBean also acts as a Notification Hub for all the Notifications that are - * defined for Admin Distributed System. - * - * - * @since GemFire 6.5 - */ -public class MemberInfoWithStatsMBean extends AbstractDynamicMBean - implements NotificationEmitter { - private static final Logger logger = LogService.getLogger(); - - /* constants defining max no of attributes/operations/notifications */ - private static final int MAX_ATTRIBUTES_COUNT = 3; - private static final int MAX_OPERATIONS_COUNT = 3; - private static final int MAX_NOTIFICATIONS_COUNT = 9; - - private static final String NOT_AVAILABLE_STR = "N/A"; - private static final String NOT_AVAILABLE = null; - private static final Number NOT_AVAILABLE_NUMBER = null; - - /* String constant used for a region that is used on admin side just as a root - * for rootRegions defined on the member */ - private static final String PLACE_HOLDER_ROOT_REGION = "/Root/"; - - /* String that are used to form QueryExp/ObjectName for querying MBeanServer */ - private static final String REGION_QUERY_EXPRESSION = "*GemFire.Cache*:*,owner={0},type=Region"; - private static final String STATS_QUERY_EXPRESSION = "*GemFire.Statistic*:*,source={0},name={1}"; - - /** mbean name string for this MBean */ - /*default*/static final String MBEAN_NAME = "GemFire:type=MemberInfoWithStatsMBean"; - - /** ObjectName handle for this MBean */ - private ObjectName objectName; - - /** version of the GemFire Enterprise system that is running */ - private String version; - private int refreshInterval; - private String id; - - private Agent agent; - private AdminDistributedSystemJmxImpl adminDSJmx; - - private NotificationForwarder forwarder; - private boolean isInitialized;//needs synchronization? - - /** - * Default Constructor - * - * @param agent Admin Agent instance - * @throws OperationsException if ObjectName can't be formed for this MBean - * @throws MBeanRegistrationException - * @throws AdminException - */ - MemberInfoWithStatsMBean(Agent agent) throws OperationsException, MBeanRegistrationException, AdminException { - this.agent = agent; - this.objectName = ObjectName.getInstance(MBEAN_NAME); - this.version = GemFireVersion.getGemFireVersion(); - this.refreshInterval = -1; - this.id = NOT_AVAILABLE_STR; - this.forwarder = new NotificationForwarder(agent.getMBeanServer()); - } - - /** - * Returns attributes defined for this MBean as an array of - * MBeanAttributeInfo objects. - * - * @return attributes defined as an array of MBeanAttributeInfo objects. - */ - @Override - protected MBeanAttributeInfo[] createMBeanAttributeInfo() { - MBeanAttributeInfo[] attributesInfo = new MBeanAttributeInfo[MAX_ATTRIBUTES_COUNT]; - - /* First letter in attribute name has to be 'V' so that getVersion is - * called. With 'v' it looks for getversion, same for others */ - attributesInfo[0] = new MBeanAttributeInfo("Version", - String.class.getName(), - "GemFire Enterprise Version", - true, /*readable*/ - false, /*writable*/ - false);/*has getter with name like 'is****'*/ - - attributesInfo[1] = new MBeanAttributeInfo("RefreshInterval", - String.class.getName(), - "The interval (in seconds) between auto-polling for updating member & statistics resources. If this is '-1', it means the this MBean has not yet been initialized. First call to getMembers operation will initialize this MBean.", - true, /*readable*/ - false, /*writable*/ - false);/*has getter with name like 'is****'*/ - - attributesInfo[2] = new MBeanAttributeInfo("Id", - String.class.getName(), - "Identifier of the GemFire Enterprise. If this is 'N/A', it means the this MBean has not yet been initialized. First call to getMembers operation will initialize this MBean.", - true, /*readable*/ - false, /*writable*/ - false);/*has getter with name like 'is****'*/ - - - return attributesInfo; - } - - /** - * Returns operations defined for this MBean as an array of - * MBeanOperationInfo objects. - * - * @return operations defined as an array of MBeanOperationInfo objects. - */ - @Override - protected MBeanOperationInfo[] createMBeanOperationInfo() { - MBeanOperationInfo[] operationsInfo = new MBeanOperationInfo[MAX_OPERATIONS_COUNT]; - - operationsInfo[0] = new MBeanOperationInfo("getMembers", - "Returns ids as strings for all the members - Application Peers & Cache Servers.", - new MBeanParameterInfo[] {}, - String[].class.getName(), - MBeanOperationInfo.ACTION_INFO); - - MBeanParameterInfo[] getMemberDetailsArgs = new MBeanParameterInfo[1]; - getMemberDetailsArgs[0] = new MBeanParameterInfo("memberId", String.class.getName(), "Id of the member for all the details are to be retrieved."); - operationsInfo[1] = new MBeanOperationInfo("getMemberDetails", - "Returns details for a given member", - getMemberDetailsArgs, - Map.class.getName(), - MBeanOperationInfo.ACTION_INFO); - - /* For retrieving ObjectNames of existing Region MBeans, MBeanServerConnection.queryMBeans(), could be called */ - MBeanParameterInfo[] getRegionSnapArgs = new MBeanParameterInfo[1]; - getRegionSnapArgs[0] = new MBeanParameterInfo("memberId", String.class.getName(), "Id of the member on which we want to discover all the region MBean."); - operationsInfo[2] = new MBeanOperationInfo("getRegions", - "Returns a java.util.Map of details of regions on a member", - getRegionSnapArgs, - Map.class.getName(), - MBeanOperationInfo.ACTION_INFO); - - - return operationsInfo; - } - - /** - * Returns notifications defined for this MBean as an array of - * MBeanNotificationInfo objects. - * - * @return notification definitions as an array of MBeanNotificationInfo - * objects. - */ - @Override - protected MBeanNotificationInfo[] createMBeanNotificationInfo() { - MBeanNotificationInfo[] notificationsInfo = new MBeanNotificationInfo[MAX_NOTIFICATIONS_COUNT]; - - String[] notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_MEMBER_JOINED}; - notificationsInfo[0] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A GemFire manager, cache, or other member has joined this distributed system."); - - notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_MEMBER_LEFT}; - notificationsInfo[1] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A GemFire manager, cache, or other member has left the distributed system."); - - notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_MEMBER_CRASHED}; - notificationsInfo[2] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A member of this distributed system has crashed instead of leaving cleanly."); - - notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_ALERT}; - notificationsInfo[3] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A member of this distributed system has generated an alert."); - - notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_ADMIN_SYSTEM_DISCONNECT}; - notificationsInfo[4] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A GemFire manager, cache, or other member has joined this distributed system."); - - notificationTypes = new String[] {SystemMemberJmx.NOTIF_CACHE_CREATED}; - notificationsInfo[5] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A cache got created on a member of this distributed system."); - - notificationTypes = new String[] {SystemMemberJmx.NOTIF_CACHE_CLOSED}; - notificationsInfo[6] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A cache is closed on a member of this distributed system."); - - notificationTypes = new String[] {SystemMemberJmx.NOTIF_REGION_CREATED}; - notificationsInfo[7] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A region is created in a cache on a member of this distributed system."); - - notificationTypes = new String[] {SystemMemberJmx.NOTIF_REGION_LOST}; - notificationsInfo[8] = new MBeanNotificationInfo(notificationTypes, - Notification.class.getName(), - "A region was removed from a cache on a member of this distributed system."); - -// String[] notificationTypes5 = new String[] {AdminDistributedSystemJmxImpl.NOTIF_STAT_ALERT}; -// notificationsInfo[9] = new MBeanNotificationInfo(notificationTypes5, -// Notification.class.getName(), -// "An alert based on statistic(s) has been raised."); - - return notificationsInfo; - } - - /** - * - * @return ObjectName of this MBean - */ - /*default*/ ObjectName getObjectName() { - return objectName; - } - - /** - * Returns the version of the GemFire Enterprise instance as a string. - * - * @return GemFire Enterprise version string derived from {@link GemFireVersion} - */ - /* getter for attribute - Version */ - public String getVersion() { - return version; - } - - /** - * @return the refreshInterval - */ - public int getRefreshInterval() { - return refreshInterval; - } - - /** - * @return the id - */ - public String getId() { - return id; - } - - /** - * Connects the Admin Agent in the DS - * - * @return AdminDistributedSystem MBean ObjectName - * @throws OperationsException - * if connection to the DS fails - * @throws AdminException - * if connection to the DS fails - */ - private ObjectName connectToSystem() throws OperationsException, AdminException { - ObjectName adminDsObjName = agent.connectToSystem(); - - AdminDistributedSystem adminDS = agent.getDistributedSystem(); - if (adminDSJmx == null && adminDS instanceof AdminDistributedSystemJmxImpl) {//instanceof checks for null - adminDSJmx = (AdminDistributedSystemJmxImpl) adminDS; - refreshInterval = adminDSJmx.getRefreshInterval(); - id = adminDSJmx.getId(); - forwarder.registerNotificationListener(adminDSJmx.getObjectName()); - } - - return adminDsObjName; - } - - /** - * - * @param memberId - * @return SystemMemberJmx instance for given memberId - * @throws AdminException - */ - private SystemMemberJmx findMember(String memberId) throws AdminException { - SystemMemberJmx foundMember = null; - - if (agent.isConnected()) { - SystemMember[] members = adminDSJmx.getSystemMemberApplications(); - for (SystemMember app : members) { - if (app.getId().equals(memberId)) { - foundMember = (SystemMemberJmx) app; - break; - } - } - - if (foundMember == null) { - members = adminDSJmx.getCacheVms(); - for (SystemMember cacheVm : members) { - if (cacheVm.getId().equals(memberId)) { - foundMember = (SystemMemberJmx) cacheVm; - break; - } - } - } - } - - return foundMember; - } - - /** - * Return ObjectNames for all the Member MBeans in the DS. - * - * @return Array of ObjectNames of all Member MBeans - * @throws OperationsException - * if (1)agent could not connect in the DS OR - * (2)Notification Listener could not be registered for the Admin - * DS MBean OR - * (3)fails to retrieve information from Admin DS - */ - public String[] getMembers() throws OperationsException { - String[] members = new String[0]; - - try { - if (!isInitialized) { - initializeAll(); //initialize if not yet - } - - if (adminDSJmx != null) { - CacheVm[] cacheVms = adminDSJmx.getCacheVms(); - SystemMember[] appVms = adminDSJmx.getSystemMemberApplications(); - - List<String> membersList = new ArrayList<String>(); - if (cacheVms != null && cacheVms.length !=0) { - for (SystemMember cacheVm : cacheVms) { - membersList.add(cacheVm.getId()); - } - } - if (appVms != null && appVms.length !=0) { - for (SystemMember appVm : appVms) { - membersList.add(appVm.getId()); - } - } - members = new String[membersList.size()]; - members = membersList.toArray(members); - } - } catch (AdminException e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0, "getMembers"), e); - throw new OperationsException(e.getMessage()); - } catch (Exception e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0, "getMembers"), e); - throw new OperationsException(e.getMessage()); - } - - return members; - } - - /** - * Returns information including ObjectNames for all regions on a member with - * given member id. - * - * @param memberId - * member identifier as a String - * @return Map of details of all regions on a member with given id - * @throws OperationsException - * if fails to retrieve the regions information - */ - public Map<String, Map<String, ?>> getRegions(String memberId) throws OperationsException { - Map<String, Map<String, ?>> regionsInfo = new LinkedHashMap<String, Map<String, ?>>(); - - if (memberId != null) { - try { - SystemMemberJmx foundMember = findMember(memberId); - if (foundMember != null) { - SystemMemberCacheJmxImpl cache = (SystemMemberCacheJmxImpl) foundMember.getCache(); - if (cache != null) { - Map<String, ObjectName> existingRegionMbeans = getExistingRegionMbeansFullPaths(memberId); - //TODO: this is in-efficient - //Can a region.create JMX notification be used? - regionsInfo = getAllRegionsDetails(cache, existingRegionMbeans); - existingRegionMbeans.clear(); - } - } - } catch (AdminException e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, new Object[]{"getRegions", memberId}), e); - throw new OperationsException(e.getMessage()); - } catch (Exception e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, new Object[]{"getRegions", memberId}), e); - throw new OperationsException(e.getMessage()); - } - } - - return regionsInfo; - } - - /* **************************************************************************/ - /* ************* INITIALIZE THE ENTIRE ADMIN DS AT A TIME *******************/ - /* **************************************************************************/ - /** - * Initializes all the possible MBeans for all the members. - * - */ - private void initializeAll() throws OperationsException { - try { - connectToSystem(); - if (adminDSJmx != null) { - //Members are already inited after connectToSystem. Now init Cache, Region & Stats MBeans - SystemMember[] cacheVms = adminDSJmx.getCacheVms(); - for (int i = 0; i < cacheVms.length; i++) { - try { - initializeCacheRegionsAndStats((SystemMemberJmx)cacheVms[i]); - } catch (AdminException e) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING_0_CONTINUING, - cacheVms[i].getId()), e); - } - } - SystemMember[] appVms = adminDSJmx.getSystemMemberApplications(); - for (int i = 0; i < appVms.length; i++) { - try { - initializeCacheRegionsAndStats((SystemMemberJmx)appVms[i]); - } catch (AdminException e) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING_0_CONTINUING, - appVms[i].getId()), e); - } - } - } - } catch (AdminException e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING), e); - throw new OperationsException(e.getMessage()); - } catch (Exception e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING), e); - throw new OperationsException(e.getMessage()); - } - - isInitialized = true; - } - - /** - * Initializes Cache, Regions & Statistics Types MBeans for the given Member. - * - * @param memberJmx - * Member Mbean instance - * @throws OperationsException - * if fails to initialize required MBeans - * @throws AdminException - * if fails to initialize required MBeans - */ - private void initializeCacheRegionsAndStats(SystemMemberJmx memberJmx) - throws OperationsException, AdminException { - if (memberJmx != null) { - SystemMemberCacheJmxImpl cache = (SystemMemberCacheJmxImpl) memberJmx.getCache(); - if (cache != null) { - RegionSubRegionSnapshot regionSnapshot = cache.getRegionSnapshot(); - initializeRegionSubRegions(cache, regionSnapshot); - } - initStats(memberJmx); - } - } - - /** - * Initializes statistics for a member with the given mbean. - * - * @param memberJmx - * Member Mbean instance - * @throws AdminException - * if fails to initialize required statistic MBeans - */ - private void initStats(SystemMemberJmx memberJmx) throws AdminException { - StatisticResource[] statResources = memberJmx.getStats(); - for (StatisticResource statResource : statResources) { - statResource.getStatistics(); - } - } - - /** - * Initializes all regions & its subregions using the Cache MBean and the - * RegionSubRegionSnapshot for this cache MBean. - * - * @param cache - * Cache MBean resource - * @param regionSnapshot - * RegionSubRegionSnapshot instance for the cache - * @throws MalformedObjectNameException - * if fails to initialize the region MBean - * @throws AdminException - * if fails to initialize the region MBean - */ - @SuppressWarnings("rawtypes") - private void initializeRegionSubRegions(SystemMemberCacheJmxImpl cache, - RegionSubRegionSnapshot regionSnapshot) - throws MalformedObjectNameException, - AdminException { - String fullPath = regionSnapshot.getFullPath(); - if (!fullPath.equals(PLACE_HOLDER_ROOT_REGION)) { - fullPath = fullPath.substring(PLACE_HOLDER_ROOT_REGION.length()-1); - - cache.manageRegion(fullPath); - } - - Set subRegionSnapshots = regionSnapshot.getSubRegionSnapshots(); - - for (Iterator iterator = subRegionSnapshots.iterator(); iterator.hasNext();) { - RegionSubRegionSnapshot subRegion = (RegionSubRegionSnapshot) iterator.next(); - try { - initializeRegionSubRegions(cache, subRegion); - } catch (AdminException e) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING_0_CONTINUING, subRegion.getFullPath()), e); - } - } - } - - - /* **************************************************************************/ - /* ********************** EVERYTHING HYPERIC NEEDS **************************/ - /* **************************************************************************/ - - /* constants defined that could be used simply retrieve needed info from Map */ - private static final String TYPE_NAME_CACHESERVER = "Cache Server"; - private static final String TYPE_NAME_APPLICATION = "Application Peer"; - /* - * NOTE - - * (My Understanding about the followings - abhishek) - * 1. CacheVM - a VM started using Cache Server Launcher. This is considered - * to be a dedicated cache VM because there is only GemFire Cache code - * running here. - * 2. ApplicationVM - a VM started with a written code using APIs and we can - * not guarantee that there will be ONLY GemFire code running in this VM. - * 3. Cache Server - Responsible for serving requests from the clients. There - * could be multiple of these per Cache and hence per VM - one of 1 or 2 above. - * These could be specified by <cache-server> (or deprecated <bridge-server>) - * element(s) in the cache-xml file or using an API Cache.addCacheServer(). - */ - -// private static final String VERSION = "gemfire.version.string"; -// private static final String MEMBER_COUNT = "gemfire.membercount.int"; -// private static final String GATEWAYHUB_COUNT = "gemfire.gatewayhubcount.int"; -// private static final String CLIENT_COUNT = "gemfire.clientcount.int"; - - private static final String MEMBER_ID = DistributionConfig.GEMFIRE_PREFIX + "member.id.string"; - private static final String MEMBER_NAME = DistributionConfig.GEMFIRE_PREFIX + "member.name.string"; - private static final String MEMBER_HOST = DistributionConfig.GEMFIRE_PREFIX + "member.host.string"; - private static final String MEMBER_PORT = DistributionConfig.GEMFIRE_PREFIX + "member.port.int"; - private static final String MEMBER_UPTIME = DistributionConfig.GEMFIRE_PREFIX + "member.uptime.long"; - private static final String MEMBER_CLIENTS = DistributionConfig.GEMFIRE_PREFIX + "member.clients.map"; - private static final String MEMBER_REGIONS = DistributionConfig.GEMFIRE_PREFIX + "member.regions.map"; - private static final String MEMBER_TYPE = DistributionConfig.GEMFIRE_PREFIX + "member.type.string"; - private static final String IS_SERVER = DistributionConfig.GEMFIRE_PREFIX + "member.isserver.boolean"; - private static final String IS_GATEWAY = DistributionConfig.GEMFIRE_PREFIX + "member.isgateway.boolean"; - - private static final String MEMBER_STATSAMPLING_ENABLED = DistributionConfig.GEMFIRE_PREFIX + "member.config.statsamplingenabled.boolean"; - private static final String MEMBER_TIME_STATS_ENABLED = DistributionConfig.GEMFIRE_PREFIX + "member.config.timestatsenabled.boolean"; - - private static final String STATS_PROCESSCPUTIME = DistributionConfig.GEMFIRE_PREFIX + "member.stat.processcputime.long"; - private static final String STATS_CPUS = DistributionConfig.GEMFIRE_PREFIX + "member.stat.cpus.int"; - private static final String STATS_USEDMEMORY = DistributionConfig.GEMFIRE_PREFIX + "member.stat.usedmemory.long"; - private static final String STATS_MAXMEMORY = DistributionConfig.GEMFIRE_PREFIX + "member.stat.maxmemory.long"; - private static final String STATS_GETS = DistributionConfig.GEMFIRE_PREFIX + "member.stat.gets.int"; - private static final String STATS_GETTIME = DistributionConfig.GEMFIRE_PREFIX + "member.stat.gettime.long"; - private static final String STATS_PUTS = DistributionConfig.GEMFIRE_PREFIX + "member.stat.puts.int"; - private static final String STATS_PUTTIME = DistributionConfig.GEMFIRE_PREFIX + "member.stat.puttime.long"; - - private static final String REGION_NAME = DistributionConfig.GEMFIRE_PREFIX + "region.name.string"; - private static final String REGION_PATH = DistributionConfig.GEMFIRE_PREFIX + "region.path.string"; - private static final String REGION_SCOPE = DistributionConfig.GEMFIRE_PREFIX + "region.scope.string"; - private static final String REGION_DATAPOLICY = DistributionConfig.GEMFIRE_PREFIX + "region.datapolicy.string"; - private static final String REGION_INTERESTPOLICY = DistributionConfig.GEMFIRE_PREFIX + "region.interestpolicy.string"; - private static final String REGION_ENTRYCOUNT = DistributionConfig.GEMFIRE_PREFIX + "region.entrycount.int"; - private static final String REGION_DISKATTRS = DistributionConfig.GEMFIRE_PREFIX + "region.diskattrs.string"; - - private static final String CLIENT_ID = DistributionConfig.GEMFIRE_PREFIX + "client.id.string"; - private static final String CLIENT_NAME = DistributionConfig.GEMFIRE_PREFIX + "client.name.string"; - private static final String CLIENT_HOST = DistributionConfig.GEMFIRE_PREFIX + "client.host.string"; - private static final String CLIENT_QUEUESIZE = DistributionConfig.GEMFIRE_PREFIX + "client.queuesize.int"; - private static final String CLIENT_STATS_GETS = DistributionConfig.GEMFIRE_PREFIX + "client.stats.gets.int"; - private static final String CLIENT_STATS_PUTS = DistributionConfig.GEMFIRE_PREFIX + "client.stats.puts.int"; - private static final String CLIENT_STATS_CACHEMISSES = DistributionConfig.GEMFIRE_PREFIX + "client.stats.cachemisses.int"; - private static final String CLIENT_STATS_CPUUSAGE = DistributionConfig.GEMFIRE_PREFIX + "client.stats.cpuusage.long"; - private static final String CLIENT_STATS_CPUS = DistributionConfig.GEMFIRE_PREFIX + "client.stats.cpus.int"; - private static final String CLIENT_STATS_UPDATETIME = DistributionConfig.GEMFIRE_PREFIX + "client.stats.updatetime.long"; - private static final String CLIENT_STATS_THREADS = DistributionConfig.GEMFIRE_PREFIX + "client.stats.threads.int"; - - /** - * - * @param memberId - * @return All the required details for a member with given memberId - * @throws OperationsException - */ - public Map<String, Object> getMemberDetails(String memberId) - throws OperationsException { - Map<String, Object> allDetails = new TreeMap<String, Object>(); - - if (memberId != null) { - try { - SystemMemberJmx member = findMember(memberId); - if (member != null) { - SystemMemberCacheJmxImpl cache = (SystemMemberCacheJmxImpl) member.getCache(); - GemFireMemberStatus snapshot = cache.getSnapshot(); - boolean isServer = snapshot.getIsServer(); - boolean isGatewayHub = snapshot.getIsGatewayHub(); - - //1. Member info - allDetails.put(MEMBER_ID, member.getId()); - allDetails.put(MEMBER_NAME, member.getName()); - String host = member.getHost();//from of GemFireVM.getHost - InetAddress hostAddr = member.getHostAddress(); - //possibility of null host address - if (hostAddr != null) { - host = hostAddr.getHostName(); - } - allDetails.put(MEMBER_HOST, host); - allDetails.put(MEMBER_UPTIME, snapshot.getUpTime()); - allDetails.put(IS_SERVER, isServer); - allDetails.put(IS_GATEWAY, isGatewayHub); - - String memberType = ""; - if (member instanceof CacheServerJmxImpl) { - memberType = TYPE_NAME_CACHESERVER; - } else {//Mark it of Application type if neither a gateway hub nor a server - memberType = TYPE_NAME_APPLICATION; - } -// if (isGatewayHub) { -// memberType = TYPE_NAME_GATEWAYHUB; -// } else if (isServer) { -// memberType = TYPE_NAME_CACHESERVER; -// } else {//Mark it of Application type if neither a gateway nor a server -// memberType = TYPE_NAME_APPLICATION; -// } - allDetails.put(MEMBER_TYPE, memberType); - - //2. Region info - Map<String, ObjectName> existingRegionMbeans = getExistingRegionMbeansFullPaths(memberId); - allDetails.put(MEMBER_REGIONS, getAllRegionsDetails(cache, existingRegionMbeans)); - existingRegionMbeans.clear(); - - //3. Clients info - allDetails.put(MEMBER_CLIENTS, getClientDetails(snapshot)); - - boolean statSamplingEnabled = true; - //assuming will never return as per current implementation - ConfigurationParameter[] configParams = member.getConfiguration(); - for (ConfigurationParameter configParam : configParams) { - if (STATISTIC_SAMPLING_ENABLED.equals(configParam.getName())) { - allDetails.put(MEMBER_STATSAMPLING_ENABLED, configParam.getValue()); - statSamplingEnabled = Boolean.parseBoolean(""+configParam.getValue()); - } else if (ENABLE_TIME_STATISTICS.equals(configParam.getName())) { - allDetails.put(MEMBER_TIME_STATS_ENABLED, configParam.getValue()); - } - } - - //5. Stats info - allDetails.putAll(getRequiredStats(member, statSamplingEnabled)); - - SystemMemberCacheServer[] cacheServers = cache.getCacheServers(); - //attempt refreshing the cache info once - if (cacheServers.length == 0) { - cache.refresh(); - cacheServers = cache.getCacheServers(); - } - Integer memberCacheServerPort = Integer.valueOf(0); - if (cacheServers.length != 0) { - /* - * Taking the first cache server port. - * We don't recommend multiple cache severs for a cache. - */ - memberCacheServerPort = Integer.valueOf(cacheServers[0].getPort()); - } - allDetails.put(MEMBER_PORT, memberCacheServerPort); - } - - } catch (AdminException e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, - new Object[] {"getMemberDetails", memberId}), e); - throw new OperationsException(e.getMessage()); - } catch (Exception e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, - new Object[] {"getMemberDetails", memberId}), e); - throw new OperationsException(e.getMessage()); - } - } - - return allDetails; - } - - /** - * - * @param snapshot - * @return Map of client details - */ - @SuppressWarnings("rawtypes") - private Map<String, Map<String, ?>> getClientDetails(GemFireMemberStatus snapshot) { - Map<String, Map<String, ?>> clientsInfo = - new LinkedHashMap<String, Map<String, ?>>(); - - Set connectedClients = snapshot.getConnectedClients(); - if (!connectedClients.isEmpty()) { - Map clientHealthStatsMap = snapshot.getClientHealthStats(); - - for (Iterator iterator = connectedClients.iterator(); iterator.hasNext();) { - Map<String, Object> clientData = new HashMap<String, Object>(); - String clientId = (String) iterator.next(); - String host = snapshot.getClientHostName(clientId); - clientData.put(CLIENT_ID, clientId); - clientData.put(CLIENT_NAME, extractClientName(clientId, host)); - clientData.put(CLIENT_HOST, host); - clientData.put(CLIENT_QUEUESIZE, snapshot.getClientQueueSize(clientId)); - - ClientHealthStats clientHealthStats = (ClientHealthStats) clientHealthStatsMap.get(clientId); - if (clientHealthStats != null) { - clientData.put(CLIENT_STATS_GETS, clientHealthStats.getNumOfGets()); - clientData.put(CLIENT_STATS_PUTS, clientHealthStats.getNumOfPuts()); - clientData.put(CLIENT_STATS_CACHEMISSES, clientHealthStats.getNumOfMisses()); - clientData.put(CLIENT_STATS_CPUUSAGE, clientHealthStats.getProcessCpuTime()); - clientData.put(CLIENT_STATS_CPUS, clientHealthStats.getCpus()); - clientData.put(CLIENT_STATS_UPDATETIME, clientHealthStats.getUpdateTime().getTime()); - clientData.put(CLIENT_STATS_THREADS, clientHealthStats.getNumOfThreads()); - } else { - clientData.put(CLIENT_STATS_GETS, Integer.valueOf(0)); - clientData.put(CLIENT_STATS_PUTS, Integer.valueOf(0)); - clientData.put(CLIENT_STATS_CACHEMISSES, Integer.valueOf(0)); - clientData.put(CLIENT_STATS_CPUUSAGE, Long.valueOf(0)); - clientData.put(CLIENT_STATS_CPUS, Integer.valueOf(0)); - clientData.put(CLIENT_STATS_UPDATETIME, Long.valueOf(0)); - clientData.put(CLIENT_STATS_THREADS, Integer.valueOf(0)); - } - - clientsInfo.put(clientId, clientData); - } - } - - return clientsInfo; - } - - /** - * Returns a Map containing information about regions. - * - * @param cache - * Reference to an MBean representing a Cache on a member - * @param existingRegionMbeans - * Map of Path against Region MBean ObjectNames - * @return Map of all region details - * @throws OperationsException - * if fails to retrieve - */ - private Map<String, Map<String, ?>> getAllRegionsDetails( - SystemMemberCacheJmxImpl cache, - Map<String, ObjectName> existingRegionMbeans) - throws OperationsException { - Map<String, Map<String, ?>> regionsInfo = - new TreeMap<String, Map<String, ?>>(); - - if (cache != null) { - try { - RegionSubRegionSnapshot regionSnapshot = cache.getRegionSnapshot(); - collectAllRegionsDetails(cache, regionSnapshot, regionsInfo, existingRegionMbeans); - } catch (AdminException e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.ONE_ARG, "Exception occurred while getting region details."), e); - throw new OperationsException(e.getMessage()); - } catch (Exception e) { - logger.warn(LocalizedMessage.create(LocalizedStrings.ONE_ARG, "Exception occurred while getting region details."), e); - throw new OperationsException(e.getMessage()); - } - } - - return regionsInfo; - } - - /** - * Collects all the region details from the RegionSubRegionSnapshot instance - * passed and the Cache MBean. Checks in the set of existingRegionMbeans - * before initializing Region Mbeans if there are not initialized yet. - * - * @param cache - * Cache MBean instance - * @param regionSnapshot - * RegionSubRegionSnapshot instance - * @param regionsInfo - * Map of regions information that gets populated recursively - * @param existingRegionMbeans - * Map of ObjectNames of existing region MBeans - * @throws AdminException - * if unable to initialize region MBean - * @throws OperationsException - * if fails to retrieve the Region MBean attribute info - * @throws MBeanException - * if fails to retrieve the Region MBean attribute info - * @throws ReflectionException - * if fails to retrieve the Region MBean attribute info - */ - @SuppressWarnings("rawtypes") - private void collectAllRegionsDetails(SystemMemberCacheJmxImpl cache, - RegionSubRegionSnapshot regionSnapshot, - Map<String, Map<String, ?>> regionsInfo, - Map<String, ObjectName> existingRegionMbeans) - throws AdminException, OperationsException, - MBeanException, ReflectionException { - String fullPath = regionSnapshot.getFullPath(); - if (!fullPath.equals(PLACE_HOLDER_ROOT_REGION)) { - fullPath = fullPath.substring(PLACE_HOLDER_ROOT_REGION.length()-1); - String name = regionSnapshot.getName(); - Integer entryCount = Integer.valueOf(regionSnapshot.getEntryCount()); - Map<String, Object> details = new TreeMap<String, Object>(); - details.put(REGION_NAME, name); - details.put(REGION_PATH, fullPath); - details.put(REGION_ENTRYCOUNT, entryCount); - - ObjectName regionObjectName = existingRegionMbeans.get(fullPath); - if (regionObjectName == null) {//initialize if has not yet been - regionObjectName = cache.manageRegion(fullPath); - } - - Object attribute = getAttribute(regionObjectName, "scope", NOT_AVAILABLE); - attribute = attribute != null ? attribute.toString() : attribute; - details.put(REGION_SCOPE, attribute); - - attribute = getAttribute(regionObjectName, "dataPolicy", NOT_AVAILABLE); - attribute = attribute != null ? attribute.toString() : attribute; - details.put(REGION_DATAPOLICY, attribute); - - SubscriptionAttributes interestPolicyAttr = - (SubscriptionAttributes) getAttribute(regionObjectName, - "subscriptionAttributes", null); - String interestPolicyStr = NOT_AVAILABLE; - if (interestPolicyAttr != null) { - InterestPolicy interestPolicy = interestPolicyAttr.getInterestPolicy(); - if (interestPolicy != null) { - interestPolicyStr = interestPolicy.toString(); - } - } - details.put(REGION_INTERESTPOLICY, interestPolicyStr); - - attribute = getAttribute(regionObjectName, "diskWriteAttributes", NOT_AVAILABLE); - attribute = attribute != null ? attribute.toString() : attribute; - details.put(REGION_DISKATTRS, attribute); - - regionsInfo.put(fullPath, details); - } - - Set subRegionSnapshots = regionSnapshot.getSubRegionSnapshots(); - - for (Iterator iterator = subRegionSnapshots.iterator(); iterator.hasNext();) { - RegionSubRegionSnapshot subRegion = (RegionSubRegionSnapshot) iterator.next(); - collectAllRegionsDetails(cache, subRegion, regionsInfo, existingRegionMbeans); - } - } - - /** - * Checks if the given host name string contains ':' as in IPv6 host address. - * - * @param host - * host name string - * @return true if the host string contains ':', false otherwise - */ - private static boolean isIPv6(String host) { - return host.contains(":"); - } - - /** - * Checks if the given host name is actually a String representation of an - * IPv4 address. - * - * @param host - * host name string - * @return true if given host name is a String representation of an IPv4 - * address, false otherwise - */ - private static boolean isIPv4(String host) { - String regex = "\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}"; - - return host.matches(regex); - } - - /** - * Excludes the host name from the client id and returns the String. If the - * host name can not be detected, returns an empty string. Typically, the - * client id looks like: HOST(VM_PID:VM_KIND):PORT:RANDOM_STRING:CLIENT_NAME - * - * Extracts the client name from the client id. If the client id is not in the - * expected format, returns 'N/A' - * - * @param clientId - * string identifier for a client - * @param host - * host name (FQDN) the client is running on - * @return name extracted from given client id - */ - /* - * Some examples of Client Id format: - * (1) Java Client: - * nase(21716:loner):51789:42e9a0bf:client_nase_21716 - * nase(2560:loner):2:7a84729a:Feeder - * - * (2) Native Client: - * nase(21045:loner):2:GFNative_OnNnEpyRWL:ExampleDistributedSystem - * - * (3) IPv6 Host whose name can not be resolved: - * fdf0:76cf:a0ed:9449:0:0:0:1001(21716:loner):51789:42e9a0b:client_nase_21716 - * fdf0:76cf:a0ed:9449:0:0:0:1001:51789:42e9a0b:client_nase_21716 - */ - private static String extractClientName(String clientId, String host) { - /* This isIPv6, isIPv4, extractClientName is taken from GFMon code base*/ - String hostExcludedId = ""; - if ( (isIPv6(host) || isIPv4(host))&& clientId.startsWith(host)) { - hostExcludedId = clientId.substring(host.length()); - } else { - int firstDotIndex = host.indexOf("."); - if (firstDotIndex != -1) { - String hostShortName = host.substring(0, firstDotIndex); - hostExcludedId = clientId.substring(hostShortName.length()); - } - } - - String vmPIDAndKindRegex = "\\(\\w+:\\w+\\)"; - String regex = "(\\<ec\\>)?:[0-9]+(:\\w+){2}+"; - String name = NOT_AVAILABLE; - String temp = hostExcludedId; - - int openIndex = temp.indexOf("("); - if (openIndex != -1) { - regex = vmPIDAndKindRegex + regex; - } - - if (temp.matches(regex)) { - String[] splitted = temp.split(":"); - name = splitted[splitted.length - 1]; - } - - return name; - } - - /** - * Returns a Map of all the statistics required for Hyperic currently. It - * relies on the attribute of the StatisticsResource Mbeans. - * - * @param member - * instance for which the stats are needed - * @return Map of all the statistics required for Hyperic currently. - * @throws OperationsException - * exceptions thrown while retrieving the attributes - */ - private Map<String, Object> getRequiredStats(SystemMemberJmx member, boolean statSamplingEnabled) throws OperationsException { - Map<String, Object> statDetails = new TreeMap<String, Object>(); - - try { - if (!statSamplingEnabled) { - statDetails.put(STATS_PROCESSCPUTIME, NOT_AVAILABLE_NUMBER); - statDetails.put(STATS_CPUS, NOT_AVAILABLE_NUMBER); - statDetails.put(STATS_MAXMEMORY, NOT_AVAILABLE_NUMBER); - statDetails.put(STATS_USEDMEMORY, NOT_AVAILABLE_NUMBER); - statDetails.put(STATS_GETS, NOT_AVAILABLE_NUMBER); - statDetails.put(STATS_GETTIME, NOT_AVAILABLE_NUMBER); - statDetails.put(STATS_PUTS, NOT_AVAILABLE_NUMBER); - statDetails.put(STATS_PUTTIME, NOT_AVAILABLE_NUMBER); - } else { - MBeanServer mBeanServer = agent.getMBeanServer(); - Number defaultVal = NOT_AVAILABLE_NUMBER; - Number processCpuTime = defaultVal; - Number cpus = defaultVal; - Number maxMemory = defaultVal; - Number usedMemory = defaultVal; - Number gets = defaultVal; - Number getTime = defaultVal; - Number puts = defaultVal; - Number putTime = defaultVal; - - ObjectName[] vmMemoryUsageStats = getExistingStats(member.getId(), "vmHeapMemoryStats"); - ObjectName[] vmStats = getExistingStats(member.getId(), "vmStats"); - ObjectName[] cachePerfStats = getExistingStats(member.getId(), "cachePerfStats"); - boolean needToReinit = false; - if (vmMemoryUsageStats.length == 0 || vmStats.length == 0 || cachePerfStats.length == 0) { - //if the StatisticResource MBeans are not created - needToReinit = true; - } - if(!needToReinit) { - /* - * To handle a case when the StatisticResource MBeans are created but - * not registered with RefreshTimer. If VMMemoryUsageStats are - * present, maxMemory should always be non-zero. */ - for (int i = 0; i < vmMemoryUsageStats.length; i++) {//ideally there should be a single instance - String type = (String) mBeanServer.getAttribute(vmMemoryUsageStats[i], "type"); - - if ("VMMemoryUsageStats".equals(type)) { //first instance that has Statistics Type name - maxMemory = (Number) getAttribute(vmMemoryUsageStats[i], "maxMemory", defaultVal); - break; - } - } - - needToReinit = 0 == maxMemory.longValue(); - } - - if(needToReinit) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_REINITIALIZING_STATS_FOR_0, member.getId())); - initStats(member); - - vmMemoryUsageStats = getExistingStats(member.getId(), "vmHeapMemoryStats"); - vmStats = getExistingStats(member.getId(), "vmStats"); - cachePerfStats = getExistingStats(member.getId(), "cachePerfStats"); - } - - for (int i = 0; i < vmMemoryUsageStats.length; i++) {//ideally there should be a single instance - String type = (String) mBeanServer.getAttribute(vmMemoryUsageStats[i], "type"); - - if ("VMMemoryUsageStats".equals(type)) { //first instance that has Statistics Type name - maxMemory = (Number) getAttribute(vmMemoryUsageStats[i], "maxMemory", defaultVal); - usedMemory = (Number) getAttribute(vmMemoryUsageStats[i], "usedMemory", defaultVal); - break; - } - } - - for (int i = 0; i < vmStats.length; i++) {//ideally there should be a single instance - String type = (String) mBeanServer.getAttribute(vmStats[i], "type"); - - if ("VMStats".equals(type)) { //first instance that has Statistics Type name - processCpuTime = (Number) getAttribute(vmStats[i], "processCpuTime", defaultVal); - cpus = (Number) getAttribute(vmStats[i], "cpus", defaultVal); - break; - } - } - - for (int i = 0; i < cachePerfStats.length; i++) {//ideally there should be a single instance - String type = (String) mBeanServer.getAttribute(cachePerfStats[i], "type"); - - if ("CachePerfStats".equals(type)) { //first instance that has Statistics Type name - gets = (Number) getAttribute(cachePerfStats[i], "gets", defaultVal); - getTime = (Number) getAttribute(cachePerfStats[i], "getTime", defaultVal); - puts = (Number) getAttribute(cachePerfStats[i], "puts", defaultVal); - putTime = (Number) getAttribute(cachePerfStats[i], "putTime", defaultVal); - break; - } - } - - statDetails.put(STATS_PROCESSCPUTIME, processCpuTime == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : processCpuTime.longValue()); - statDetails.put(STATS_CPUS, cpus == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : cpus.intValue()); - statDetails.put(STATS_MAXMEMORY, maxMemory == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : maxMemory.longValue()); - statDetails.put(STATS_USEDMEMORY, usedMemory == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : usedMemory.longValue()); - statDetails.put(STATS_GETS, gets == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : gets.intValue()); - statDetails.put(STATS_GETTIME, getTime == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : getTime.intValue()); - statDetails.put(STATS_PUTS, puts == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : puts.intValue()); - statDetails.put(STATS_PUTTIME, putTime == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : putTime.longValue()); - } - } catch (Exception e) { - logger.warn(e.getMessage(), e); - throw new OperationsException(e.getMessage()); - } - - return statDetails; - } - - /** - * Returns attribute with given attribute name on MBean with given ObjectName. - * - * - * @param objectName - * ObjectName for the MBean - * @param attribute - * attribute name - * @param unavailableValue - * return this value if the attribute value is null - * @return value of attribute with given attribute name - * @throws OperationsException - * if attribute is not found for MBean with this ObjectName or MBean - * instance is not found - * @throws MBeanException - * if MBeans getter throws exception - * @throws ReflectionException - * thrown when trying to invoke the setter. - */ - private Object getAttribute(ObjectName objectName, String attribute, - Object unavailableValue) - throws OperationsException, MBeanException, ReflectionException { - /* NOTE: callers methods rely on non-null value being returned */ - Object value = null; - - MBeanServer mBeanServer = agent.getMBeanServer(); - value = mBeanServer.getAttribute(objectName, attribute); - - value = (value != null)? value : unavailableValue; - - return value; - } - - /** - * Return Map of region full against the ObjectName of existing region MBeans. - * - * @param memberId - * string identifier of a member - * @return Map of region path vs ObjectName for existing region MBeans - * @throws MalformedObjectNameException - * If the query expression used is not valid - */ - private Map<String, ObjectName> getExistingRegionMbeansFullPaths(String memberId) throws MalformedObjectNameException { - Map<String, ObjectName> pathsToObjName = new HashMap<String, ObjectName>(); - - if (memberId != null && memberId.trim().length() != 0) { - Object[] params = new Object[] {MBeanUtil.makeCompliantMBeanNameProperty(memberId)}; - Set<ObjectName> queryNames = queryObjectNames(REGION_QUERY_EXPRESSION, params); - for (ObjectName objectName : queryNames) { - pathsToObjName.put(objectName.getKeyProperty("path"), objectName); - } - } - - return pathsToObjName; - } - - /** - * Returns an array of ObjectNames existing statistics types MBeans - * - * @param memberId - * string identifier of a member - * @param name - * text id of the stats which appears in the stats ObjectName as name - * keyProperty - * @return Array of Stats MBean ObjectNames - * @throws MalformedObjectNameException - * If the query expression used is not valid - */ - private ObjectName[] getExistingStats(String memberId, String name) throws MalformedObjectNameException { - ObjectName[] statObjectNames = new ObjectName[0]; - - if (memberId != null && memberId.trim().length() != 0) { - Object[] params = new Object[] {MBeanUtil.makeCompliantMBeanNameProperty(memberId), name}; - Set<ObjectName> queryNames = queryObjectNames(STATS_QUERY_EXPRESSION, params); - statObjectNames = new ObjectName[queryNames.size()]; - statObjectNames = queryNames.toArray(statObjectNames); - } - - return statObjectNames; - } - - /** - * Queries the MBean server with the string formed using placing the params in - * the parameterized string passed as queryStr. - * - * @param queryStr - * parameterized string - * @param params - * params to put in the string - * @return results of an ObjectName query - * @throws MalformedObjectNameException - * If the query expression ObjectName formed is not valid - */ - private Set<ObjectName> queryObjectNames(String queryStr, Object ... params) - throws MalformedObjectNameException { - Set<ObjectName> queried = Collections.emptySet(); - - queryStr = MessageFormat.format(queryStr, params); - ObjectName queryExp = ObjectName.getInstance(queryStr); - queried = agent.getMBeanServer().queryNames(null, queryExp); - - return queried; - } - - - /* *************************************************************************/ - /* **************** NOTIFICATION EMITTER IMPLEMENTATION ********************/ - /* *************************************************************************/ - - /** - * @see NotificationEmitter#addNotificationListener(NotificationListener, NotificationFilter, Object) - */ - public void addNotificationListener(NotificationListener listener, - NotificationFilter filter, Object handback) - throws IllegalArgumentException { - forwarder.addNotificationListener(listener, filter, handback); - } - - /** - * @see NotificationEmitter#removeNotificationListener(NotificationListener) - */ - public void removeNotificationListener(NotificationListener listener) - throws ListenerNotFoundException { - forwarder.removeNotificationListener(listener); - } - - /** - * @see NotificationEmitter#getNotificationInfo() - */ - public MBeanNotificationInfo[] getNotificationInfo() { - return getMBeanInfo().getNotifications(); - } - - /** - * @see NotificationEmitter#removeNotificationListener(NotificationListener, NotificationFilter, Object) - */ - public void removeNotificationListener(NotificationListener listener, - NotificationFilter filter, Object handback) - throws ListenerNotFoundException { - forwarder.removeNotificationListener(listener, filter, handback); - } - -} - -/** - * This class acts as a hub for the Notifications defined on - * AdminDistributedSystem & SystemMember MBeans. This acts as a listener for - * these notifications and broadcasts them as notifications from the - * {@link MemberInfoWithStatsMBean} MBean. This class extends - * {@link NotificationBroadcasterSupport} only to have the functionality to send - * notifications. - * - * - * @since GemFire 6.5 - */ -class NotificationForwarder extends NotificationBroadcasterSupport - implements NotificationListener { - - private static final Logger logger = LogService.getLogger(); - - /* sequence generator for notifications from GemFireTypesWrapper MBean */ - private static AtomicLong notificationSequenceNumber = new AtomicLong(); - - /* reference to the MBeanServer instance */ - private MBeanServer mBeanServer; - - /** - * Default Constructor - * - * @param mBeanServer - * reference to the MBeanServer instance - */ - /*default*/NotificationForwarder(MBeanServer mBeanServer) { - this.mBeanServer = mBeanServer; - } - - /** - * Handles notifications as: 1. Member Joined: Registers this - * NotificationForwarder as a notification listener for Cache/Region - * Notifications. 2. Member Left/Crashed: Unregisters this - * NotificationForwarder as a notification listener for Cache/Region - * Notifications. 3. AdminDistributedSystem Disconnected: Unregisters this - * NotificationForwarder as a notification listener for member Notifications. - * - * Forwards the notifications to the JMX Clients that have registered for - * notifications on this MBean - * - * @param notification - * notification to be handled - * @param handback - * handback object used while NotificationForwarder was registered - * - * @see NotificationListener#handleNotification(Notification, Object) - */ - public void handleNotification(Notification notification, Object handback) { - Object notifSource = notification.getSource(); - if (AdminDistributedSystemJmxImpl.NOTIF_MEMBER_JOINED.equals(notification.getType())) { - ObjectName source = (ObjectName) notifSource; - //initialize statistics/register with refreshTimer for new member - String[] noArgs = {}; - try { - ObjectName[] stats = (ObjectName[]) mBeanServer.invoke(source, "manageStats", noArgs, noArgs); - if (stats != null) { - for (ObjectName stat : stats) { - mBeanServer.invoke(stat, "getStatistics", noArgs, noArgs); - } - } - logger.debug("getStatistics call completed with no exceptions."); - } catch (ReflectionException e) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INITIALIZING_STATISICS_FOR_0, source.toString()), e); - } catch (MBeanException e) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INITIALIZING_STATISICS_FOR_0, source.toString()), e); - } catch (InstanceNotFoundException e) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INITIALIZING_STATISICS_FOR_0, source.toString()), e); - } - //register this listener for joined member's cache/region notifications - try { - registerNotificationListener(source); - } catch (OperationsException e) { - logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_REGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString()), e); - } - } /*else if (AdminDistributedSystemJmxImpl.NOTIF_MEMBER_LEFT.equals(notification.getType()) || - AdminDistributedSystemJmxImpl.NOTIF_MEMBER_CRASHED.equals(notification.getType())) { - ObjectName source = (ObjectName) notifSource; - //unregister this listener from left member's cache/region notifications - try { - unregisterNotificationListener(source); - } catch (OperationsException e) { - logwriter.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_UNREGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString(), e); - } - } else if (AdminDistributedSystemJmxImpl.NOTIF_ADMIN_SYSTEM_DISCONNECT.equals(notification.getType())) { - String source = (String) notifSource; - //This notification does not have ObjectName as a source. - try { - ObjectName instance = ObjectName.getInstance(source); - unregisterNotificationListener(instance); - } catch (OperationsException e) { - logwriter.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_UNREGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString(), e); - } catch (NullPointerException e) { - logwriter.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_UNREGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString(), e); - } - } */ - //NOTIF_ALERT is sent as is - - //TODO: Check if same notification instance can be reused by simply changing the sequence number - notification = new Notification(notification.getType(), notifSource, - notificationSequenceNumber.addAndGet(1L), - notification.getTimeStamp(), - notification.getMessage()); - - sendNotification(notification); - } - - /** - * Registers itself as a NotificationListener for Notifications sent from - * MBean with the ObjectName given as source. - * - * @param source - * source of notifications - * @throws InstanceNotFoundException - * The MBean name provided does not match any of the registered - * MBeans. - */ - /*default*/void registerNotificationListener(ObjectName source) - throws InstanceNotFoundException { - mBeanServer.addNotificationListener(source, this, null/*handback*/, source); - } - - /** - * Unregisters itself as a NotificationListener for Notifications sent from - * MBean with the ObjectName given as source. - * - * @param source source of notifications - * @throws InstanceNotFoundException - * The MBean name provided does not match any of the registered - * MBeans. - * @throws ListenerNotFoundException - * The listener is not registered in the MBean. - */ - /*default*/void unregisterNotificationListener(ObjectName source) - throws InstanceNotFoundException, ListenerNotFoundException { - mBeanServer.removeNotificationListener(source, this); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryService.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryService.java deleted file mode 100644 index 6bf240f..0000000 --- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryService.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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.admin.jmx.internal; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.UnknownHostException; -import java.rmi.NoSuchObjectException; -import java.rmi.NotBoundException; -import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.RMIServerSocketFactory; -import java.rmi.server.UnicastRemoteObject; - -/** - * This MBean is an implementation of {@link RMIRegistryServiceMBean}. - * - */ -public class RMIRegistryService implements RMIRegistryServiceMBean { - /* RMI Registry host */ - private String host; - /* RMI Registry port */ - private int port; - /* RMI Registry */ - private Registry registry; - /* RMI Server Socket Factory */ - private RMIServerSocketFactory ssf; - /* Whether RMI Registry is started & running */ - private boolean isRunning; - - /** - * Constructor to configure RMI Registry to start using default RMI Registry - * port: {@link Registry#REGISTRY_PORT} - */ - public RMIRegistryService() { - this(Registry.REGISTRY_PORT); - } - - /** - * Constructor to configure RMI Registry to start using given RMI Registry - * port. - * - * @param port - * to run RMI Registry on - */ - public RMIRegistryService(int port) { - setPort(port); - } - - /** - * Constructor to configure RMI Registry to start using given RMI Registry - * port & host bind address. - * - * @param host - * to bind RMI Registry to - * @param port - * to run RMI Registry on - * - * @throws UnknownHostException - * if IP Address can not be resolved for the given host string while - * creating the RMIServerSocketFactory - */ - public RMIRegistryService(String host, int port) throws UnknownHostException { - setPort(port); - setHost(host); - if (host != null && !host.trim().equals("")) { - ssf = new RMIServerSocketFactoryImpl(host); - } - } - - /** - * Returns the host on which rmiregistry listens for incoming connections - * - * @return the host on which rmiregistry listens for incoming connections - */ - public String getHost() { - return host; - } - - /** - * Sets the host on which rmiregistry listens for incoming connections - * - * @param host - * the host on which rmiregistry listens for incoming connections - */ - protected void setHost(String host) { - if (isRunning()) { - throw new IllegalStateException("RMIRegistryService is running, cannot change the host"); - } - this.host = host; - } - - /** - * Returns the port on which rmiregistry listens for incoming connections - * - * @return the port on which rmiregistry listens for incoming connections - */ - public int getPort() { - return port; - } - - /** - * Sets the port on which rmiregistry listens for incoming connections - * - * @param port - * the port on which rmiregistry listens for incoming connections - */ - protected void setPort(int port) { - if (isRunning()) { - throw new IllegalStateException("RMIRegistryService is running, cannot change the port"); - } - this.port = port; - } - - /** - * Starts this MBean: rmiregistry can now accept incoming calls - * - * @see #stop - * @see #isRunning - */ - public synchronized void start() throws RemoteException { - if (!isRunning()) { - if (ssf != null) { - registry = LocateRegistry.createRegistry(port, - null, //RMIClientSocketFactory - ssf); //RMIServerSocketFactory - } else { - registry = LocateRegistry.createRegistry(port); - } - - isRunning = true; - } - } - - /** - * Returns whether this MBean has been started and not yet stopped. - * - * @return whether this MBean has been started and not yet stopped. - * @see #start - */ - public synchronized boolean isRunning() { - return isRunning; - } - - /** - * Stops this MBean: rmiregistry cannot accept anymore incoming calls - * - * @see #start - */ - public synchronized void stop() throws NoSuchObjectException { - if (isRunning()) { - isRunning = !UnicastRemoteObject.unexportObject(registry, true); - } - } - - /** - * Returns an array of the names bound in the rmiregistry - * - * @return an array of the names bound in the rmiregistry - * @see java.rmi.registry.Registry#list() - */ - public String[] list() throws RemoteException { - if (!isRunning()) { - throw new IllegalStateException("RMIRegistryService is not running"); - } - return registry.list(); - } - - /** - * Removes the binding for the specified <code>name</code> in the rmiregistry - * - * @see java.rmi.registry.Registry#unbind(String) - */ - public void unbind(String name) throws RemoteException, NotBoundException { - if (!isRunning()) { - throw new IllegalStateException("RMIRegistryService is not running"); - } - registry.unbind(name); - } -} - -/** - * Custom implementation of the {@link RMIServerSocketFactory} - * - */ -class RMIServerSocketFactoryImpl implements RMIServerSocketFactory { - /* IP address to use for creating ServerSocket */ - private InetAddress bindAddress; - - /** - * Constructs a RMIServerSocketFactory. The given rmiBindAddress is used to - * bind the ServerSockets created from this factory. - * - * @param rmiBindAddress - * String representation of the address to bind the ServerSockets to - * - * @throws UnknownHostException - * if IP Address can not be resolved for the given host string - */ - /*default */RMIServerSocketFactoryImpl(String rmiBindAddress) - throws UnknownHostException { - this.bindAddress = InetAddress.getByName(rmiBindAddress); - } - - /** - * Create a server socket on the specified port (port 0 indicates an anonymous - * port). - * - * @param port - * the port number - * @return the server socket on the specified port - * @exception IOException - * if an I/O error occurs during server socket creation - */ - public ServerSocket createServerSocket(int port) throws IOException { - return new ServerSocket(port, - 0/*backlog - for '0' internally uses the default*/, - bindAddress); - } -} - http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryServiceMBean.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryServiceMBean.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryServiceMBean.java deleted file mode 100644 index f2ac079..0000000 --- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RMIRegistryServiceMBean.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.admin.jmx.internal; - -import java.rmi.NoSuchObjectException; -import java.rmi.NotBoundException; -import java.rmi.RemoteException; - -/** - * This interface is similar to mx4j.tools.naming.NamingServiceMBean. - * Features that differ are: - * 1. This MBean interface additionally provides a way to specify the host that - * the RMI Registry should get bound to. - * 2. Port property can not be changed once set. - * - */ -public interface RMIRegistryServiceMBean { - - /** - * Returns the host on which rmiregistry listens for incoming connections - * - * @return the host on which rmiregistry listens for incoming connections - */ - public String getHost(); - - /** - * Returns the port on which rmiregistry listens for incoming connections - * - * @return the port on which rmiregistry listens for incoming connections - */ - public int getPort(); - - /** - * Returns whether this MBean has been started and not yet stopped. - * - * @return whether this MBean has been started and not yet stopped. - * @see #start - */ - public boolean isRunning(); - - /** - * Starts this MBean: rmiregistry can now accept incoming calls - * - * @see #stop - * @see #isRunning - */ - public void start() throws RemoteException; - - /** - * Stops this MBean: rmiregistry cannot accept anymore incoming calls - * - * @see #start - */ - public void stop() throws NoSuchObjectException; - - /** - * Returns an array of the names bound in the rmiregistry - * - * @return an array of the names bound in the rmiregistry - * @see java.rmi.registry.Registry#list() - */ - public String[] list() throws RemoteException; - - /** - * Removes the binding for the specified <code>name</code> in the rmiregistry - * - * @see java.rmi.registry.Registry#unbind(String) - */ - public void unbind(String name) throws RemoteException, NotBoundException; -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RefreshNotificationType.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RefreshNotificationType.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RefreshNotificationType.java deleted file mode 100755 index 93513e5..0000000 --- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/RefreshNotificationType.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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.admin.jmx.internal; - -import org.apache.commons.lang.StringUtils; - -/** - * Type-safe definition for refresh notifications. - * - * @since GemFire 3.5 - * - */ -public class RefreshNotificationType implements java.io.Serializable { - private static final long serialVersionUID = 4376763592395613794L; - - /** Notify StatisticResource to refresh statistics */ - public static final RefreshNotificationType STATISTIC_RESOURCE_STATISTICS = - new RefreshNotificationType( - "GemFire.Timer.StatisticResource.statistics.refresh", - "refresh"); - - /** Notify SystemMember to refresh config */ - public static final RefreshNotificationType SYSTEM_MEMBER_CONFIG = - new RefreshNotificationType( - "GemFire.Timer.SystemMember.config.refresh", - "refresh"); - - /** Notification type for the javax.management.Notification */ - private final transient String type; - - /** Notification msg for the javax.management.Notification */ - private final transient String msg; - - // The 4 declarations below are necessary for serialization - /** int used as ordinal to represent this Scope */ - public final int ordinal = nextOrdinal++; - - private static int nextOrdinal = 0; - - private static final RefreshNotificationType[] VALUES = - { STATISTIC_RESOURCE_STATISTICS, SYSTEM_MEMBER_CONFIG }; - - private Object readResolve() throws java.io.ObjectStreamException { - return VALUES[ordinal]; // Canonicalize - } - - /** Creates a new instance of RefreshNotificationType. */ - private RefreshNotificationType(String type, String msg) { - this.type = type; - this.msg = msg; - } - - /** Return the RefreshNotificationType represented by specified ordinal */ - public static RefreshNotificationType fromOrdinal(int ordinal) { - return VALUES[ordinal]; - } - - public String getType() { - return this.type; - } - - public String getMessage() { - return this.msg; - } - - /** - * Returns a string representation for this notification type. - * - * @return the type string for this Notification - */ - @Override - public String toString() { - return this.type; - } - - /** - * Indicates whether some other object is "equal to" this one. - * - * @param other the reference object with which to compare. - * @return true if this object is the same as the obj argument; - * false otherwise. - */ - @Override - public boolean equals(Object other) { - if (other == this) return true; - if (other == null) return false; - if (!(other instanceof RefreshNotificationType)) return false; - final RefreshNotificationType that = (RefreshNotificationType) other; - - if (!StringUtils.equals(this.type, that.type)) return false; - if (!StringUtils.equals(this.msg, that.msg)) return false; - - return true; - } - - /** - * Returns a hash code for the object. This method is supported for the - * benefit of hashtables such as those provided by java.util.Hashtable. - * - * @return the integer 0 if description is null; otherwise a unique integer. - */ - @Override - public int hashCode() { - int result = 17; - final int mult = 37; - - result = mult * result + - (this.type == null ? 0 : this.type.hashCode()); - result = mult * result + - (this.msg == null ? 0 : this.msg.hashCode()); - - return result; - } - -} - http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/StatAlertNotification.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/StatAlertNotification.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/StatAlertNotification.java deleted file mode 100644 index 59d7948..0000000 --- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/StatAlertNotification.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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.admin.jmx.internal; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.Serializable; -import java.io.IOException; - -import org.apache.geode.DataSerializer; -import org.apache.geode.DataSerializable; -import org.apache.geode.internal.DataSerializableFixedID; -import org.apache.geode.internal.Version; -import org.apache.geode.internal.admin.StatAlert; -import org.apache.geode.internal.admin.StatAlertDefinition; - -/** - * Notification to be sent to clients (e.g GFMon2.0 ). It incorporates - * - * @see StatAlert raised and also Gemfire member id which raised the alert - * - * - * @since GemFire 5.7 - */ -public class StatAlertNotification extends StatAlert implements Serializable, DataSerializable, DataSerializableFixedID { - private static final long serialVersionUID = -1634729103430107871L; - private String memberId; - - public StatAlertNotification() { - } - - public StatAlertNotification(StatAlert statAlert, String memberId) { - this.setDefinitionId(statAlert.getDefinitionId()); - this.setValues(statAlert.getValues()); - this.setTime(statAlert.getTime()); - this.memberId = memberId; - } - - public int getDSFID() { - return DataSerializableFixedID.STAT_ALERT_NOTIFICATION; - } - - /** - * @return the memberId - */ - public String getMemberId() { - return memberId; - } - - /** - * - * @param id - * of gemfire member which raised the alert - */ - public void setMemberId(String id) { - memberId = id; - } - - /** - * @return String representation of this object - */ - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("["); - for (int i = 0; i < getValues().length; i++) { - buf.append(getValues()[i] + ", "); - } - buf.append("]"); - return Integer.valueOf(getDefinitionId()) + ":" + buf.toString(); - } - - /** - * The notification is something like this - * "For Member ID: <ID> - * [ - * <StatName> = <Value> - * .. - * ]" - * @param defn - * {@link StatAlertDefinition} - * @return String representation of this object based on - * {@link StatAlertDefinition} - */ - public String toString(StatAlertDefinition defn) { - StringBuffer buf = new StringBuffer(); - buf.append("For Member ID: "); - buf.append(this.memberId); - buf.append("\n"); - buf.append("[ "); - for (int i = 0; i < getValues().length; i++) { - buf.append(defn.getStatisticInfo()[i].toString() + "=" + getValues()[i] - + "\n"); - } - buf.append("]"); - return getTime().toString() + ":" + buf.toString(); - } - - @Override - public boolean equals(Object object) { - if (object != null && !(object instanceof StatAlertNotification)) { - return false; - } - - StatAlertNotification other = (StatAlertNotification)object; - - int defId = getDefinitionId(); - - if (defId != -1 && defId == other.getDefinitionId() && memberId != null - && memberId.equals(other.getMemberId())) { - return true; - } - - return false; - } - - @Override - public int hashCode() { - return memberId.hashCode(); - } - - public void toData(DataOutput out) throws IOException { - // Do not modify StatAlert to allow 57 cacheservers to function with 57+ agent - // However, update of a new StatAlertDefn on 57 server from 57+ agent not covered with this - DataSerializer.writePrimitiveInt(this.getDefinitionId(), out); - DataSerializer.writeDate(this.getTime(), out); - DataSerializer.writeObjectArray(this.getValues(), out); - - DataSerializer.writeString(this.memberId, out); - } - - public void fromData(DataInput in) - throws IOException, ClassNotFoundException { - // Do not modify StatAlert to allow 57 cacheservers to function with 57+ agent - // However, update of a new StatAlertDefn on 57 server from 57+ agent not covered with this - this.setDefinitionId(DataSerializer.readPrimitiveInt(in)); - this.setTime(DataSerializer.readDate(in)); - this.setValues((Number[])DataSerializer.readObjectArray(in)); - - this.memberId = DataSerializer.readString(in); - } - - @Override - public Version[] getSerializationVersions() { - return null; - } -}