org.apache.geode.admin.jmx.internal.SystemMemberCacheJmxImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.geode.admin.jmx.internal.SystemMemberCacheJmxImpl.java

Source

/*
 * 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.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.modelmbean.ModelMBean;

import org.apache.commons.modeler.ManagedBean;
import org.apache.logging.log4j.Level;

import org.apache.geode.SystemFailure;
import org.apache.geode.admin.AdminException;
import org.apache.geode.admin.SystemMemberCacheServer;
import org.apache.geode.admin.SystemMemberRegion;
import org.apache.geode.admin.internal.SystemMemberBridgeServerImpl;
import org.apache.geode.cache.Region;
import org.apache.geode.internal.admin.AdminBridgeServer;
import org.apache.geode.internal.admin.GemFireVM;
import org.apache.geode.internal.i18n.LocalizedStrings;
import org.apache.geode.internal.logging.InternalLogWriter;

/**
 * MBean representation of {@link org.apache.geode.admin.SystemMemberCache}.
 *
 * @since GemFire 3.5
 */
public class SystemMemberCacheJmxImpl extends org.apache.geode.admin.internal.SystemMemberCacheImpl
        implements org.apache.geode.admin.jmx.internal.ManagedResource {

    /** The object name of this managed resource */
    private ObjectName objectName;

    /** collection to collect all the resources created for this member */
    private Map<String, SystemMemberRegionJmxImpl> managedRegionResourcesMap = new HashMap<String, SystemMemberRegionJmxImpl>();
    private Map<Number, SystemMemberBridgeServerJmxImpl> managedCacheServerResourcesMap = new HashMap<Number, SystemMemberBridgeServerJmxImpl>();

    // -------------------------------------------------------------------------
    // Constructor(s)
    // -------------------------------------------------------------------------

    /**
     * Constructs an instance of SystemMemberCacheJmxImpl.
     *
     * @param vm The vm owning the cache this object will manage
     */
    public SystemMemberCacheJmxImpl(GemFireVM vm) throws org.apache.geode.admin.AdminException {
        super(vm);
        initializeMBean();
    }

    /** Create and register the MBean to manage this resource */
    private void initializeMBean() throws org.apache.geode.admin.AdminException {
        this.mbeanName = new StringBuffer("GemFire.Cache:").append("name=")
                .append(MBeanUtil.makeCompliantMBeanNameProperty(getName())).append(",id=").append(getId())
                .append(",owner=").append(MBeanUtil.makeCompliantMBeanNameProperty(vm.getId().toString()))
                .append(",type=Cache").toString();

        this.objectName = MBeanUtil.createMBean(this, addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
    }

    // -------------------------------------------------------------------------
    // Template methods overriden from superclass...
    // -------------------------------------------------------------------------

    /**
     * Override createSystemMemberRegion by instantiating SystemMemberRegionJmxImpl. This instance is
     * also added to the managedResources collection.
     * 
     * @param r reference to Region instance for which this JMX resource is to be created
     * @return SystemMemberRegionJmxImpl - JMX Implementation of SystemMemberRegion
     * @throws AdminException if constructing SystemMemberRegionJmxImpl instance fails
     */
    @Override
    protected SystemMemberRegion createSystemMemberRegion(Region r) throws org.apache.geode.admin.AdminException {
        SystemMemberRegionJmxImpl managedSystemMemberRegion = null;
        boolean needsRefresh = false;
        synchronized (this.managedRegionResourcesMap) {
            /*
             * Ensuring that a single instance of System Member Region is created per Region.
             */
            SystemMemberRegionJmxImpl managedResource = managedRegionResourcesMap.get(r.getFullPath());
            if (managedResource != null) {
                managedSystemMemberRegion = managedResource;
            } else {
                managedSystemMemberRegion = new SystemMemberRegionJmxImpl(this, r);
                managedRegionResourcesMap.put(r.getFullPath(), managedSystemMemberRegion);
                needsRefresh = true;
            }
        }
        if (needsRefresh) {
            managedSystemMemberRegion.refresh();
        }
        return managedSystemMemberRegion;
    }

    /**
     * Creates a SystemMemberBridgeServerJmxImpl instance. This instance is also added to the
     * managedResources collection.
     * 
     * @param bridge reference to AdminBridgeServer for which this JMX resource is to be created
     * @return SystemMemberBridgeServerJmxImpl - JMX Implementation of SystemMemberBridgeServerImpl
     * @throws AdminException if constructing SystemMemberBridgeServerJmxImpl instance fails
     */
    @Override
    protected SystemMemberBridgeServerImpl createSystemMemberBridgeServer(AdminBridgeServer bridge)
            throws AdminException {
        SystemMemberBridgeServerJmxImpl managedSystemMemberBridgeServer = null;
        synchronized (this.managedCacheServerResourcesMap) {
            /*
             * Ensuring that a single instance of SystemMember BridgeServer is created per
             * AdminBridgeServer.
             */
            SystemMemberBridgeServerJmxImpl managedCacheServerResource = managedCacheServerResourcesMap
                    .get(bridge.getId());
            if (managedCacheServerResource != null) {
                managedSystemMemberBridgeServer = managedCacheServerResource;
            } else {
                managedSystemMemberBridgeServer = new SystemMemberBridgeServerJmxImpl(this, bridge);
                managedCacheServerResourcesMap.put(bridge.getId(), managedSystemMemberBridgeServer);
            }
        }
        return managedSystemMemberBridgeServer;
    }

    // -------------------------------------------------------------------------
    // Create MBean attributes for each Statistic
    // -------------------------------------------------------------------------

    /**
     * Add MBean attribute definitions for each Statistic.
     *
     * @param managed the mbean definition to add attributes to
     * @return a new instance of ManagedBean copied from <code>managed</code> but with the new
     *         attributes added
     */
    ManagedBean addDynamicAttributes(ManagedBean managed) throws org.apache.geode.admin.AdminException {
        if (managed == null) {
            throw new IllegalArgumentException(
                    LocalizedStrings.SystemMemberCacheJmxImpl_MANAGEDBEAN_IS_NULL.toLocalizedString());
        }

        refresh(); // to get the stats...

        // need to create a new instance of ManagedBean to clean the "slate"...
        ManagedBean newManagedBean = new DynamicManagedBean(managed);
        for (int i = 0; i < this.statistics.length; i++) {
            StatisticAttributeInfo attrInfo = new StatisticAttributeInfo();

            attrInfo.setName(this.statistics[i].getName());
            attrInfo.setDisplayName(this.statistics[i].getName());
            attrInfo.setDescription(this.statistics[i].getDescription());
            attrInfo.setType("java.lang.Number");

            attrInfo.setIs(false);
            attrInfo.setReadable(true);
            attrInfo.setWriteable(false);

            attrInfo.setStat(this.statistics[i]);

            newManagedBean.addAttribute(attrInfo);
        }

        return newManagedBean;
    }

    // -------------------------------------------------------------------------
    // MBean Operations
    // -------------------------------------------------------------------------

    /**
     * Returns the ObjectName of the Region for the specified path.
     *
     * @throws AdminException If no region with path <code>path</code> exists
     */
    public ObjectName manageRegion(String path) throws AdminException, MalformedObjectNameException {
        try {
            SystemMemberRegionJmxImpl region = null;

            try {
                region = (SystemMemberRegionJmxImpl) getRegion(path);

            } catch (AdminException e) {
                MBeanUtil.logStackTrace(Level.WARN, e);
                throw e;
            }

            if (region == null) {
                throw new AdminException(
                        LocalizedStrings.SystemMemberCacheJmxImpl_THIS_CACHE_DOES_NOT_CONTAIN_REGION_0
                                .toLocalizedString(path));

            } else {
                return ObjectName.getInstance(region.getMBeanName());
            }
        } catch (RuntimeException e) {
            MBeanUtil.logStackTrace(Level.WARN, e);
            throw e;
        } catch (VirtualMachineError err) {
            SystemFailure.initiateFailure(err);
            // If this ever returns, rethrow the error. We're poisoned
            // now, so don't let this thread continue.
            throw err;
        } catch (Error e) {
            // Whenever you catch Error or Throwable, you must also
            // catch VirtualMachineError (see above). However, there is
            // _still_ a possibility that you are dealing with a cascading
            // error condition, so you also need to check to see if the JVM
            // is still usable:
            SystemFailure.checkFailure();
            MBeanUtil.logStackTrace(Level.ERROR, e);
            throw e;
        }
    }

    /**
     * Creates a new cache server MBean and returns its <code>ObjectName</code>.
     *
     * @since GemFire 5.7
     */
    public ObjectName manageCacheServer() throws AdminException, MalformedObjectNameException {

        try {
            SystemMemberBridgeServerJmxImpl bridge = (SystemMemberBridgeServerJmxImpl) addCacheServer();
            return ObjectName.getInstance(bridge.getMBeanName());
        } catch (AdminException e) {
            MBeanUtil.logStackTrace(Level.WARN, e);
            throw e;
        } catch (RuntimeException e) {
            MBeanUtil.logStackTrace(Level.WARN, e);
            throw e;
        } catch (VirtualMachineError err) {
            SystemFailure.initiateFailure(err);
            // If this ever returns, rethrow the error. We're poisoned
            // now, so don't let this thread continue.
            throw err;
        } catch (Error e) {
            // Whenever you catch Error or Throwable, you must also
            // catch VirtualMachineError (see above). However, there is
            // _still_ a possibility that you are dealing with a cascading
            // error condition, so you also need to check to see if the JVM
            // is still usable:
            SystemFailure.checkFailure();
            MBeanUtil.logStackTrace(Level.ERROR, e);
            throw e;
        }
    }

    /**
     * Returns the MBean <code>ObjectName</code>s for all cache servers that serve this cache to
     * clients.
     *
     * @since GemFire 4.0
     */
    public ObjectName[] manageCacheServers() throws AdminException, MalformedObjectNameException {

        try {
            SystemMemberCacheServer[] bridges = getCacheServers();
            ObjectName[] names = new ObjectName[bridges.length];
            for (int i = 0; i < bridges.length; i++) {
                SystemMemberBridgeServerJmxImpl bridge = (SystemMemberBridgeServerJmxImpl) bridges[i];
                names[i] = ObjectName.getInstance(bridge.getMBeanName());
            }

            return names;
        } catch (AdminException e) {
            MBeanUtil.logStackTrace(Level.WARN, e);
            throw e;
        } catch (RuntimeException e) {
            MBeanUtil.logStackTrace(Level.WARN, e);
            throw e;
        } catch (VirtualMachineError err) {
            SystemFailure.initiateFailure(err);
            // If this ever returns, rethrow the error. We're poisoned
            // now, so don't let this thread continue.
            throw err;
        } catch (Error e) {
            // Whenever you catch Error or Throwable, you must also
            // catch VirtualMachineError (see above). However, there is
            // _still_ a possibility that you are dealing with a cascading
            // error condition, so you also need to check to see if the JVM
            // is still usable:
            SystemFailure.checkFailure();
            MBeanUtil.logStackTrace(Level.ERROR, e);
            throw e;
        }
    }

    /**
     * Returns the MBean <code>ObjectName</code>s for all bridge servers that serve this cache.
     *
     * @since GemFire 4.0
     * @deprecated as of 5.7
     */
    @Deprecated
    public ObjectName[] manageBridgeServers() throws AdminException, MalformedObjectNameException {
        return manageCacheServers();
    }

    // -------------------------------------------------------------------------
    // ManagedResource implementation
    // -------------------------------------------------------------------------

    /** The name of the MBean that will manage this resource */
    private String mbeanName;

    /** The ModelMBean that is configured to manage this resource */
    private ModelMBean modelMBean;

    public String getMBeanName() {
        return this.mbeanName;
    }

    public ModelMBean getModelMBean() {
        return this.modelMBean;
    }

    public void setModelMBean(ModelMBean modelMBean) {
        this.modelMBean = modelMBean;
    }

    public ObjectName getObjectName() {
        return this.objectName;
    }

    public ManagedResourceType getManagedResourceType() {
        return ManagedResourceType.SYSTEM_MEMBER_CACHE;
    }

    /**
     * Un-registers all the statistics & cache managed resource created for this member. After
     * un-registering the resource MBean instances, clears this.memberResources collection.
     * 
     * Creates ConfigurationParameterJmxImpl, StatisticResourceJmxImpl and SystemMemberCacheJmxImpl.
     * But cleans up only StatisticResourceJmxImpl and SystemMemberCacheJmxImpl which are of type
     * ManagedResource.
     */
    public void cleanupResource() {
        synchronized (this.managedRegionResourcesMap) {
            Collection<SystemMemberRegionJmxImpl> values = managedRegionResourcesMap.values();

            for (SystemMemberRegionJmxImpl systemMemberRegionJmxImpl : values) {
                MBeanUtil.unregisterMBean(systemMemberRegionJmxImpl);
            }

            this.managedRegionResourcesMap.clear();
        }

        synchronized (this.managedCacheServerResourcesMap) {
            Collection<SystemMemberBridgeServerJmxImpl> values = managedCacheServerResourcesMap.values();

            for (SystemMemberBridgeServerJmxImpl SystemMemberBridgeServerJmxImpl : values) {
                MBeanUtil.unregisterMBean(SystemMemberBridgeServerJmxImpl);
            }

            this.managedCacheServerResourcesMap.clear();
        }
    }

    /**
     * Cleans up managed resources created for the region that was (created and) destroyed in a cache
     * represented by this Managed Resource.
     * 
     * @param regionPath path of the region that got destroyed
     * @return a managed resource related to this region path
     */
    public ManagedResource cleanupRegionResources(String regionPath) {
        ManagedResource cleaned = null;

        synchronized (this.managedRegionResourcesMap) {
            Set<Entry<String, SystemMemberRegionJmxImpl>> entries = managedRegionResourcesMap.entrySet();
            for (Iterator<Entry<String, SystemMemberRegionJmxImpl>> it = entries.iterator(); it.hasNext();) {
                Entry<String, SystemMemberRegionJmxImpl> entry = it.next();
                SystemMemberRegionJmxImpl managedResource = entry.getValue();
                ObjectName objName = managedResource.getObjectName();

                String pathProp = objName.getKeyProperty("path");
                if (pathProp != null && pathProp.equals(regionPath)) {
                    cleaned = managedResource;
                    it.remove();

                    break;
                }
            }
        }

        return cleaned;
    }

    /**
     * Checks equality of the given object with <code>this</code> based on the type (Class) and the
     * MBean Name returned by <code>getMBeanName()</code> methods.
     * 
     * @param obj object to check equality with
     * @return true if the given object is if the same type and its MBean Name is same as
     *         <code>this</code> object's MBean Name, false otherwise
     */
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof SystemMemberCacheJmxImpl)) {
            return false;
        }

        SystemMemberCacheJmxImpl other = (SystemMemberCacheJmxImpl) obj;

        return this.getMBeanName().equals(other.getMBeanName());
    }

    /**
     * Returns hash code for <code>this</code> object which is based on the MBean Name generated.
     * 
     * @return hash code for <code>this</code> object
     */
    @Override
    public int hashCode() {
        return this.getMBeanName().hashCode();
    }
}