blob: 992a7696c67e7abe04fcc6309270b3da12c3cad0 [file] [log] [blame]
/*
* 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;
/**
* MBean representation of {@link org.apache.geode.admin.SystemMemberCache}.
*
* @since GemFire 3.5
*/
@Deprecated
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 final Map<String, SystemMemberRegionJmxImpl> managedRegionResourcesMap =
new HashMap<>();
private final Map<Number, SystemMemberBridgeServerJmxImpl> managedCacheServerResourcesMap =
new HashMap<>();
// -------------------------------------------------------------------------
// 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 {
mbeanName = "GemFire.Cache:" + "name="
+ MBeanUtils.makeCompliantMBeanNameProperty(getName()) + ",id=" + getId()
+ ",owner=" + MBeanUtils.makeCompliantMBeanNameProperty(vm.getId().toString())
+ ",type=Cache";
objectName =
MBeanUtils.createMBean(this, addDynamicAttributes(MBeanUtils.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 (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 (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(
"ManagedBean is null");
}
refresh(); // to get the stats...
// need to create a new instance of ManagedBean to clean the "slate"...
ManagedBean newManagedBean = new DynamicManagedBean(managed);
for (final org.apache.geode.admin.Statistic statistic : statistics) {
StatisticAttributeInfo attrInfo = new StatisticAttributeInfo();
attrInfo.setName(statistic.getName());
attrInfo.setDisplayName(statistic.getName());
attrInfo.setDescription(statistic.getDescription());
attrInfo.setType("java.lang.Number");
attrInfo.setIs(false);
attrInfo.setReadable(true);
attrInfo.setWriteable(false);
attrInfo.setStat(statistic);
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) {
MBeanUtils.logStackTrace(Level.WARN, e);
throw e;
}
if (region == null) {
throw new AdminException(
String.format("This cache does not contain region %s",
path));
} else {
return ObjectName.getInstance(region.getMBeanName());
}
} catch (RuntimeException e) {
MBeanUtils.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();
MBeanUtils.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) {
MBeanUtils.logStackTrace(Level.WARN, e);
throw e;
} catch (RuntimeException e) {
MBeanUtils.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();
MBeanUtils.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) {
MBeanUtils.logStackTrace(Level.WARN, e);
throw e;
} catch (RuntimeException e) {
MBeanUtils.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();
MBeanUtils.logStackTrace(Level.ERROR, e);
throw e;
}
}
/**
* Returns the MBean <code>ObjectName</code>s for all cache 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;
@Override
public String getMBeanName() {
return mbeanName;
}
@Override
public ModelMBean getModelMBean() {
return modelMBean;
}
@Override
public void setModelMBean(ModelMBean modelMBean) {
this.modelMBean = modelMBean;
}
@Override
public ObjectName getObjectName() {
return objectName;
}
@Override
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.
*/
@Override
public void cleanupResource() {
synchronized (managedRegionResourcesMap) {
Collection<SystemMemberRegionJmxImpl> values = managedRegionResourcesMap.values();
for (SystemMemberRegionJmxImpl systemMemberRegionJmxImpl : values) {
MBeanUtils.unregisterMBean(systemMemberRegionJmxImpl);
}
managedRegionResourcesMap.clear();
}
synchronized (managedCacheServerResourcesMap) {
Collection<SystemMemberBridgeServerJmxImpl> values = managedCacheServerResourcesMap.values();
for (SystemMemberBridgeServerJmxImpl SystemMemberBridgeServerJmxImpl : values) {
MBeanUtils.unregisterMBean(SystemMemberBridgeServerJmxImpl);
}
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 (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 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 getMBeanName().hashCode();
}
}