com.tangosol.internal.net.management.MBeanCollectorFunction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of coherence Show documentation
Show all versions of coherence Show documentation
Oracle Coherence Community Edition
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.internal.net.management;
import com.oracle.coherence.common.base.Logger;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.Member;
import com.tangosol.net.management.MBeanAccessor;
import com.tangosol.net.management.MBeanHelper.QueryExpFilter;
import com.tangosol.net.management.Registry;
import com.tangosol.util.Base;
import com.tangosol.util.SetMap;
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;
import com.tangosol.util.filter.AlwaysFilter;
import com.tangosol.util.filter.NeverFilter;
import com.tangosol.util.filter.RegexFilter;
import com.tangosol.util.function.Remote;
import com.tangosol.util.stream.RemoteCollectors;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularDataSupport;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.ToLongFunction;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collector;
/**
* MBeanCollectorFunction is {@link Function} that provided with an {@link
* MBeanServer} will return a Map of MBean attributes with each attribute being
* aggregated or listed. The type of aggregation to be performed is based on
* the collector associated to each attribute. The collector is derived based
* on precedence order as specified in the {@link CacheMBeanAttribute} and {@link
* ServiceMBeanAttribute} docs.
*
* @author hr 2016.09.28
* @since 12.2.1.4.0
*/
public class MBeanCollectorFunction
implements Remote.Function>
{
// ----- constructors ---------------------------------------------------
/**
* Construct an MBeanCollectorFunction function.
*
* @param sLocator either a regex to be applied against nodeids or a role name
* @param sAttribute the attribute to return
* @param sCollector the collector to use instead of the default
* @param query the MBean Object query to use
*/
public MBeanCollectorFunction(String sLocator,
String sAttribute,
String sCollector,
MBeanAccessor.QueryBuilder.ParsedQuery query)
{
f_sLocator = sLocator;
f_sAttribute = sAttribute;
f_sCollector = sCollector;
f_query = query;
}
@Override
public Map apply(MBeanServer mbs)
{
boolean fAllAttributes = isOmitted(f_sAttribute);
QueryExp query = createQuery();
String sObjectQuery = f_query.getQuery();
// populate a map of attribute names to a collection of ObjectNames
IdentityHashMap, Collection> mapObjectNames = new IdentityHashMap<>(2);
ObjectName objName = null;
try
{
objName = new ObjectName(sObjectQuery);
}
catch(MalformedObjectNameException e)
{
throw new IllegalArgumentException("Malformed ObjectName: '" + objName + "', Query: '" + query + '\'', e);
}
Collection colNames;
try
{
colNames = mbs.queryNames(objName, query);
}
catch (RuntimeException e)
{
throw new IllegalArgumentException("Illegal query; ObjectName: '" + objName + "', Query: '" + query + '\'', e);
}
Iterator iterNames = colNames.iterator();
if (iterNames.hasNext())
{
try
{
MBeanInfo info = mbs.getMBeanInfo(iterNames.next());
MBeanAttributeInfo[] aAttribute = info.getAttributes();
Set setAttributeName = new HashSet<>(aAttribute.length);
for (MBeanAttributeInfo attribute : aAttribute)
{
setAttributeName.add(attribute.getName());
}
mapObjectNames.put(setAttributeName, colNames);
}
catch (InstanceNotFoundException ex)
{
// ignore when MBean unregistered between query and request for its info/attributes
Logger.log("MBeanCollector#apply(objName=" + objName +
"): ignoring InstanceNotFoundException: " + ex.getMessage(), Base.LOG_QUIET);
}
catch (Exception e)
{
throw Base.ensureRuntimeException(e);
}
}
// validate the requested attribute exists on the MBean being queried
if (!fAllAttributes)
{
for (Iterator> iter = mapObjectNames.keySet().iterator(); iter.hasNext(); )
{
Set setAttributeName = iter.next();
// mutating the key of a hash container is generally erroneous
// but identity based maps are an exception
setAttributeName.retainAll(Collections.singletonList(f_sAttribute));
if (setAttributeName.isEmpty())
{
iter.remove();
}
}
if (mapObjectNames.isEmpty())
{
throw Base.ensureRuntimeException(new AttributeNotFoundException(
"Attribute \"" + f_sAttribute + "\" cannot be found"));
}
}
// create a collector capable of aggregating each MBean attribute
Collector, Map> collector =
createCollector(objName, f_sCollector, mbs);
BiConsumer