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

com.tangosol.coherence.management.internal.resources.AbstractManagementResource Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2023, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * https://oss.oracle.com/licenses/upl.
 */
package com.tangosol.coherence.management.internal.resources;

import com.tangosol.coherence.config.Config;
import com.tangosol.coherence.management.internal.Converter;
import com.tangosol.coherence.management.internal.EntityMBeanResponse;
import com.tangosol.coherence.management.internal.MBeanResponse;

import com.tangosol.net.CacheFactory;

import com.tangosol.net.management.MBeanAccessor;
import com.tangosol.net.management.MBeanServerProxy;
import com.tangosol.net.management.Registry;

import com.tangosol.net.management.MBeanAccessor.QueryBuilder;

import com.tangosol.util.Base;
import com.tangosol.util.Filter;
import com.tangosol.util.Filters;
import com.tangosol.util.ValueExtractor;

import java.io.ByteArrayInputStream;

import java.net.URI;

import java.nio.charset.StandardCharsets;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import javax.ws.rs.WebApplicationException;

import javax.ws.rs.container.ContainerRequestContext;

import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import static com.tangosol.net.CacheFactory.getStackTrace;
import static com.tangosol.net.CacheFactory.log;

/**
 * The base resource for Coherence management resources.
 *
 * @author sr  2017.08.21
 * @since 12.2.1.4.0
 */
public abstract class AbstractManagementResource
    {
    // ----- constructors ---------------------------------------------------

    /**
     * Default constructor.
     */
    public AbstractManagementResource()
        {
        m_sClusterName = Config.getProperty("coherence.management.http.cluster");
        }

    /**
     * Construct a AbstractManagementResource.
     *
     * @param resource  the {@link AbstractManagementResource} to be used to initialize the context
     */
    public AbstractManagementResource(AbstractManagementResource resource)
        {
        m_requestContext        = resource.m_requestContext;
        m_requestHeaders        = resource.m_requestHeaders;
        m_uriInfo               = resource.m_uriInfo;
        m_mBeanServerProxy      = resource.m_mBeanServerProxy;
        m_filterDomainPartition = resource.m_filterDomainPartition;
        m_sClusterName          = resource.m_sClusterName;
        }

    // ----- AbstractManagementResource methods -----------------------------

    /**
     * Update the attributes of an MBean, with the provided json entity
     *
     * @param entity     the json object which contains the keys to be updated
     * @param bldrQuery  the {@link QueryBuilder} to be used to generate MBean query
     *
     * @return the Response object
     */
    protected Response update(Map entity, QueryBuilder bldrQuery)
        {
        try
            {
            if (bldrQuery.toString().contains(MANAGEMENT_QUERY))
                {
                checkAttributeTypeConversion(entity, true);
                }
            else
                {
                checkAttributeTypeConversion(entity);
                }

            MBeanResponse responseEntity = new MBeanResponse(getRequestContext());
            MBeanAccessor accessor = getMBeanAccessor();

            if (!entity.isEmpty())
                {
                Map attrMap = entity.entrySet()
                        .stream()
                        .collect(Collectors.toMap(e -> fromRestName(e.getKey()), Map.Entry::getValue));

                Map> mapUpdatedMBeans = accessor.update(bldrQuery.build(), attrMap);

                if (mapUpdatedMBeans.isEmpty())
                    {
                    return Response.status(Response.Status.NOT_FOUND).build();
                    }

                for (Map.Entry> entry : mapUpdatedMBeans.entrySet())
                    {
                    String              sObjName      = entry.getKey();
                    Map mapAttributes = entry.getValue();

                    for (String sAttrKey : attrMap.keySet())
                        {
                        if (!mapAttributes.containsKey(sAttrKey))
                            {
                            responseEntity.addFailure(getRestName(sAttrKey),
                                    "Update attribute failed for MBean :" + sObjName);
                            }
                        }
                    }
                }
            return response(responseEntity.toJson());
            }
        catch (IllegalArgumentException iae)
            {
            Response.Status status = Response.Status.BAD_REQUEST;

            CacheFactory.log("Request precondition failure for updating an MBean with query " + bldrQuery.toString() +
                ". Failure is " + iae.getClass().getName() + " " + iae.getMessage(), CacheFactory.LOG_INFO);

            throw new WebApplicationException(Response.status(status).
                entity("HTTP " + status.getStatusCode() + ' ' + status.getReasonPhrase() + '\n' +
                    iae.getMessage()).build());
            }
        catch (Exception e)
            {
            CacheFactory.log("Exception occurred while updating an MBean with query "
                + bldrQuery.toString() + ", " + e + '\n'
                + Base.getStackTrace(e), CacheFactory.LOG_ERR);

            if (e instanceof WebApplicationException)
                {
                throw e;
                }

            // internal server error
            throw new WebApplicationException();
            }
        }

    /**
     * Calculate the response body required for a single MBean.
     *
     * @param bldrQuery     the {@link QueryBuilder} to be used to generate MBean query
     * @param asChildLinks  the child links to be added to the response
     *
     * @return the entity response for the MBean
     */
    protected EntityMBeanResponse getResponseEntityForMbean(QueryBuilder bldrQuery,
                                                            String...    asChildLinks)
        {
        return getResponseEntityForMbean(bldrQuery, getParentUri(), getCurrentUri(),
                getAttributesFilter(), getLinksFilter(),  asChildLinks);
        }

    /**
     * Calculate the response body required for a single MBean.
     *
     * @param bldrQuery     the {@link QueryBuilder} to be used to generate MBean query
     * @param uriParent     the parent URI of the request, the parent URI is one level up
     *                      from the current resource
     * @param uriSelf       the self URI of the Mbean
     * @param mapQuery      the object query map, query map contains which child elements must be returned
     * @param asChildLinks  the child links to be added to the response
     *
     * @return the entity response for the MBean
     */
    protected EntityMBeanResponse getResponseEntityForMbean(QueryBuilder bldrQuery,
                                                            URI          uriParent,
                                                            URI          uriSelf,
                                                            Map          mapQuery,
                                                            String...    asChildLinks)
        {
        return getResponseEntityForMbean(bldrQuery, uriParent, uriSelf, getAttributesFilter(mapQuery),
                getLinksFilter(mapQuery), asChildLinks);
        }

    /**
     * Calculate the response body for a single MBean.
     *
     * @param bldrQuery         the {@link QueryBuilder} to be used to generate MBean query
     * @param uriParent         the parent URI of the resource
     * @param uriSelf           the self URI of the Mbean
     * @param filterAttributes  the attributes filter
     * @param filterLinks       the links filter
     * @param asChildLinks      the child links to be added to the response
     *
     * @return the entity response for the MBean
     */
    protected EntityMBeanResponse getResponseEntityForMbean(QueryBuilder   bldrQuery,
                                                            URI            uriParent,
                                                            URI            uriSelf,
                                                            Filter filterAttributes,
                                                            Filter filterLinks,
                                                            String...      asChildLinks)
        {
        try
            {
            EntityMBeanResponse responseEntity = createResponse(uriParent, uriSelf, filterLinks);
            MBeanAccessor       accessor       = getMBeanAccessor();

            Map> mapResponses = accessor.getAttributes(bldrQuery.build());

            if (!mapResponses.isEmpty())
                {
                Map.Entry> responseEntry = mapResponses.entrySet().iterator().next();
                responseEntity.setEntity(getMBeanAttributesMap(filterAttributes, responseEntry.getValue(),
                        responseEntry.getKey()));
                }
            else
                {
                return null;
                }

            if (asChildLinks != null)
                {
                Arrays.stream(asChildLinks).forEach(l -> responseEntity.addResourceLink(l, getSubUri(uriSelf, l)));
                }

            return responseEntity;
            }
        catch (Exception e)
            {
            log("Exception occurred while getting response body for MBean with query "
                    + bldrQuery.build() + "\n" + getStackTrace(e), CacheFactory.LOG_ERR);
            if (e instanceof WebApplicationException)
                {
                throw (WebApplicationException) e;
                }

            // internal server error, also do not propagate the error
            throw new WebApplicationException();
            }
        }

    /**
     * Execute an MBean operation with the provided parameters.
     *
     * @param bldrQuery       the {@link QueryBuilder} to be used to generate MBean query
     * @param sOperationName  the name of the operation
     * @param aoArguments     the arguments of the operation
     * @param asSignature     the signature for the operation
     *
     * @return the Response to be sent
     */
    protected Response executeMBeanOperation(QueryBuilder  bldrQuery,
                                             String        sOperationName,
                                             Object[]      aoArguments,
                                             String[]      asSignature)
        {
        try
            {
            MBeanAccessor accessor = getMBeanAccessor();

            Map mapMBeans = accessor.invoke(bldrQuery.build(), sOperationName, aoArguments, asSignature);

            if (mapMBeans.isEmpty())
                {
                return Response.status(Response.Status.NOT_FOUND).build();
                }
            else if (!mapMBeans.isEmpty() &&
                    getRequestContext().getMethod().equalsIgnoreCase("GET") &&
                    !MEDIA_TYPE_JSON.equals(getRequestContext().getHeaderString("Accept")))
               {
               Object obj = mapMBeans.get(mapMBeans.keySet().iterator().next());
               if (obj instanceof String)
                   {
                   return Response.ok(new ByteArrayInputStream(((String) obj).getBytes(StandardCharsets.UTF_8))).build();
                   }
               }
            }
        catch (RuntimeException e)
            {
            log("Exception occurred while executing an Mbean operation on query "
                            + bldrQuery.build() + ", and operationName " + sOperationName + "\n" + getStackTrace(e), CacheFactory.LOG_ERR);

            if (e instanceof WebApplicationException)
                {
                throw (WebApplicationException) e;
                }

            MBeanResponse response = new MBeanResponse(getRequestContext());
            String        sCause   = "unknown, refer to log files for more information";

            // extract the original error message
            Throwable tCause = Base.getOriginalException(e);
            if (tCause != null)
                {
                sCause = Base.getDeepMessage(tCause, "\n");
                }

            response.addFailure(sOperationName + " failed, Cause=" + sCause);
            return Response.status(Response.Status.BAD_REQUEST).entity(response.toJson()).build();
            }
        return response(new MBeanResponse(getRequestContext()).toJson());
        }

    /**
     * Execute an operation in an Mbean and return the response.
     *
     * @param bldrQuery       the {@link QueryBuilder} to be used to generate MBean query
     * @param sResponseKey    the key in the response map to which the result must be put
     * @param sOperationName  the operation name
     *
     * @return the response
     */
    protected EntityMBeanResponse getResponseFromMBeanOperation(QueryBuilder bldrQuery,
                                                                String       sResponseKey,
                                                                String       sOperationName)
        {
        return getResponseFromMBeanOperation(bldrQuery, sResponseKey, sOperationName,
                null, null);
        }

    /**
     * Execute an operation in an MBean and return the response.
     *
     * @param bldrQuery       the {@link QueryBuilder} to be used to generate MBean query
     * @param sResponseKey    the key in the response map to which the result must be put
     * @param sOperationName  the operation name
     * @param aoArguments     the arguments of the Mbean operations
     * @param asSignature     the signature of the MBean operation
     *
     * @return the response
     */
    protected EntityMBeanResponse getResponseFromMBeanOperation(QueryBuilder  bldrQuery,
                                                                String        sResponseKey,
                                                                String        sOperationName,
                                                                Object[]      aoArguments,
                                                                String[]      asSignature)
        {
        URI             uriParent        = getParentUri();
        URI             uriSelf          = getCurrentUri();
        Filter  filterLinks      = getLinksFilter();
        Filter  filterAttributes = getAttributesFilter();

        try
            {
            EntityMBeanResponse responseBody = createResponse(uriParent, uriSelf, filterLinks);
            MBeanAccessor       accessor     = getMBeanAccessor();
            Map mapMBeans    =
                    accessor.invoke(bldrQuery.build(), sOperationName, aoArguments, asSignature);

            if (!mapMBeans.isEmpty())
                {
                // when we are doing MBean operations isn REST with sResponseKey set, then the operation
                // should typically happen on only one MBean. In any case, we return the result
                // of only one MBean
                Map.Entry entry       = mapMBeans.entrySet().iterator().next();
                Map       mapResponse = new LinkedHashMap<>();

                if (filterAttributes.evaluate(sResponseKey.toUpperCase()))
                    {
                    mapResponse.put(getRestName(sResponseKey), Converter.convert(entry.getValue()));
                    }

                responseBody.setEntity(mapResponse);
                }
            return responseBody;
            }
        catch (RuntimeException e)
            {
            log("Exception occurred while executing an Mbean operation on query" + bldrQuery.toString()
                    + "and operationName " + sOperationName + "\n" + getStackTrace(e), CacheFactory.LOG_ERR);

            if (e instanceof WebApplicationException)
                {
                throw e;
                }
            
            EntityMBeanResponse responseBody = createResponse(uriParent, uriSelf, filterLinks);
            String              sCause       = "unknown, refer to log files for more information";

            // extract the original error message
            Throwable tCause = Base.getOriginalException(e);
            if (tCause != null)
                {
                sCause = Base.getDeepMessage(tCause, "\n");
                }

            responseBody.addFailure(sOperationName + " failed, Cause=" + sCause);
            return responseBody;
            }
        }

    /**
     * Generate a response for a collection query. There are cases wherein a list of MBeans needs
     * to be grouped based on a unique key, for example list of services, list of caches etc. In such cases
     * the MBeans are grouped with that unique key property and the response is generated using the child
     * resource class.
     *
     * @param bldrQuery           the {@link QueryBuilder} to be used to generate MBean query
     * @param resource            the resource object to be used to generate response for a individual element
     * @param sUniqueKeyProperty  the unique key property to use, in case multiple objects needs to be
     *                            coalesced into one. For example, there can be multiple Service MBeans
     *                            for the same service.
     * @param mapQuery            the object query map, query map contains which child elements must be returned
     * @param uriParent           the parent URI
     * @param uriSelf             the current URI
     *
     * @return the response for the collection
     */
    protected EntityMBeanResponse getResponseBodyForMBeanCollection(QueryBuilder               bldrQuery,
                                                                    AbstractManagementResource resource,
                                                                    String                     sUniqueKeyProperty,
                                                                    Map                        mapQuery,
                                                                    URI                        uriParent,
                                                                    URI                        uriSelf,
                                                                    Map        mapArguments)
        {
        try
            {
            Filter      filterLinks    = getLinksFilter(mapQuery);
            EntityMBeanResponse responseEntity = createResponse(uriParent, uriSelf, filterLinks);
            MBeanAccessor       accessor       = getMBeanAccessor();
            Set         setObjectNames = accessor.queryKeys(bldrQuery.build());

            if (setObjectNames != null && !setObjectNames.isEmpty())
                {
                List> listChildEntities = new ArrayList<>();

                // this is the case where there is a unique property, and the response needs to be fetched from
                // a child resource. For example, while querying for list of services, there can be multiple
                // ServiceMBeans
                // but there is only a single service, similarly CacheMBean as well. the unique property in both
                // theses cases is the name of the service/cache

                Set setObjNames = convertToObjectNames(setObjectNames);

                Map> mapMBeanToName = setObjNames.stream()
                        .collect(Collectors.groupingBy(o -> o.getKeyProperty(sUniqueKeyProperty)));

                for (Map.Entry> entry : mapMBeanToName.entrySet())
                    {
                    // propagate the argument map to the child resources after appending the unique key
                    Map mapChildResourceArgs = new HashMap<>();
                    if (mapArguments != null)
                        {
                        mapChildResourceArgs.putAll(mapArguments);
                        }

                    mapChildResourceArgs.put(sUniqueKeyProperty, entry.getKey());

                    Map mapObjResponse = resource.getQueryResult(mapQuery,
                                                                                 mapChildResourceArgs,
                                                                                 uriSelf).toJson();

                    listChildEntities.add(mapObjResponse);
                    }
                responseEntity.setEntities(listChildEntities);
                }
            else
                {
                return null;
                }

            return responseEntity;
            }
        catch (Exception e)
            {
            log("Exception occurred while getting response for an MBean collection with query " + bldrQuery.build().getQuery() +
                    "\n" + getStackTrace(e), CacheFactory.LOG_ERR);
            throw new WebApplicationException();
            }
        }

    /**
     * Generate a response for a collection query. For each child MBean, the response is generated
     * for its attributes followed by querying the child resources.
     *
     * @param bldrQuery     the {@link QueryBuilder} to be used to generate MBean query
     * @param resource      the resource object to be used to generate response for a individual element
     * @param mapQuery      the object query map, query map contains which child elements must be returned
     * @param mapArguments  the arguments to the child resource
     * @param uriParent     the parent URI
     * @param uriSelf       the current URI
     *
     * @return the response for the collection
     */
    protected EntityMBeanResponse getResponseBodyForMBeanCollection(QueryBuilder               bldrQuery,
                                                                    AbstractManagementResource resource,
                                                                    Map                        mapQuery,
                                                                    Map        mapArguments,
                                                                    URI                        uriParent,
                                                                    URI                        uriSelf)
        {
        try
            {
            Filter                   filterLinks    = getLinksFilter(mapQuery);
            EntityMBeanResponse              responseEntity = createResponse(uriParent, uriSelf, filterLinks);
            MBeanAccessor                    accessor       = getMBeanAccessor();
            Map> mapMBeans      = accessor.getAttributes(bldrQuery.build());

            if (mapMBeans != null && !mapMBeans.isEmpty())
                {
                List> listChildEntities = new ArrayList<>();
                Filter            filterAttributes  = getAttributesFilter(mapQuery);

                for (Map.Entry> entry: mapMBeans.entrySet())
                    {
                    String              sObjName = entry.getKey();
                    ObjectName          objName  = new ObjectName(sObjName);

                    // propagate the argument map to the child resources after appending the unique key
                    Map mapChildResourceArgs = new HashMap<>();
                    if (mapArguments != null)
                        {
                        mapChildResourceArgs.putAll(mapArguments);
                        }

                    mapChildResourceArgs.put(MEMBER_KEY, getMemberReference(objName));

                    EntityMBeanResponse response = resource.getQueryResult(mapQuery, mapChildResourceArgs, uriSelf);

                    response.getEntity().putAll(getMBeanAttributesMap(
                            filterAttributes, entry.getValue(), entry.getKey()));

                    listChildEntities.add(response.toJson());
                    }

                responseEntity.setEntities(listChildEntities);
                }
            return responseEntity;
            }
        catch (Exception e)
            {
            log("Exception occurred while getting response for an MBean collection with query " +
                    bldrQuery.build() + "\n" + getStackTrace(e), CacheFactory.LOG_ERR);
            throw new WebApplicationException();
            }
        }

    /**
     * Generate a response for a collection query. Examples of collection queries are
     * list of members in a cluster, list of services in a cluster etc.
     *
     * @param bldrQuery           the {@link QueryBuilder} to be used to generate MBean query
     * @param sUniqueKeyProperty  the unique key property, which is used to create the self link for the MBean.
     *                            For example, while querying for the list of federation topologies, each topology MBean
     *                            response will have a self link, and the self link will be {parentUri}/{name}.
     *                            In this case, the unique key property is the name, which is the topology name.
     * @param mapQuery            the object query map, query map contains which child elements must be returned
     * @param uriParent           the parent URI
     * @param uriSelf             the current URI
     *
     * @return the response for the collection
     */
    protected EntityMBeanResponse getResponseBodyForMBeanCollection(QueryBuilder bldrQuery,
                                                                    String       sUniqueKeyProperty,
                                                                    Map          mapQuery,
                                                                    URI          uriParent,
                                                                    URI          uriSelf)
        {
        try
            {
            Filter                   filterLinks    = getLinksFilter(mapQuery);
            EntityMBeanResponse              responseEntity = createResponse(uriParent, uriSelf, filterLinks);
            MBeanAccessor                    accessor       = getMBeanAccessor();
            Map> mapMBeans      = accessor.getAttributes(bldrQuery.build());

            if (mapMBeans != null && !mapMBeans.isEmpty())
                {
                List> listChildEntities = new ArrayList<>();

                // this is the cache where there are no child resource required
                // we just need to send the response for a list of MBeans, for example
                // list of back cache members for a single cache in a member
                Filter filterAttributes = getAttributesFilter(mapQuery);

                for (Map.Entry> entry: mapMBeans.entrySet())
                    {
                    String              sObjName      = entry.getKey();
                    Map mapAttributes = entry.getValue();
                    ObjectName          objectName    = new ObjectName(entry.getKey());
                    URI                 uriSub        =
                            getSubUri(uriSelf, objectName.getKeyProperty(sUniqueKeyProperty));

                    EntityMBeanResponse responseEntityChild = createResponse(uriSelf, uriSub, filterLinks);

                    responseEntityChild.setEntity(getMBeanAttributesMap(filterAttributes, mapAttributes, sObjName));

                    listChildEntities.add(responseEntityChild.toJson());
                    }
                responseEntity.setEntities(listChildEntities);
                }

            return responseEntity;
            }
        catch (Exception e)
            {
            log("Exception occurred while getting response for an MBean collection with query " + bldrQuery.build() +
                    getStackTrace(e), CacheFactory.LOG_ERR);
            throw new WebApplicationException();
            }
        }

    /**
     * Generate a response for a collection query. Examples of collection queries are
     * list of members in a cluster, list of services in a cluster etc.
     *
     * @param bldrQuery  the {@link QueryBuilder} to be used to generate MBean query
     * @param mapQuery   the object query map, query map contains which child elements must be returned
     * @param uriParent  the parent URI
     * @param uriSelf    the current URI
     *
     * @return the response for the collection
     */
    protected EntityMBeanResponse getResponseBodyForMBeanCollection(QueryBuilder bldrQuery,
                                                                    Map          mapQuery,
                                                                    URI          uriParent,
                                                                    URI          uriSelf)
        {
        try
            {
            Filter                   filterLinks    = getLinksFilter(mapQuery);
            EntityMBeanResponse              responseEntity = createResponse(uriParent, uriSelf, filterLinks);
            MBeanAccessor                    accessor       = getMBeanAccessor();
            Map> mapMBeans      = accessor.getAttributes(bldrQuery.build());

            if (mapMBeans != null && !mapMBeans.isEmpty())
                {
                List> listChildEntities = new ArrayList<>();

                // this is the cache where there are no child resource required
                // we just need to send the response for a list of MBeans, for example
                // list of back cache members for a single cache in a member
                Filter filterAttributes = getAttributesFilter(mapQuery);

                for (Map.Entry> entry: mapMBeans.entrySet())
                    {
                    listChildEntities.add(getMBeanAttributesMap(filterAttributes, entry.getValue(), entry.getKey()));
                    }

                responseEntity.setEntities(listChildEntities);
                }
            return responseEntity;
            }
        catch (Exception e)
            {
            log("Exception occurred while getting response for an MBean collection with query " + bldrQuery.build()
                    + "\n" + getStackTrace(e), CacheFactory.LOG_ERR);
            throw new WebApplicationException();
            }
        }

    /**
     * Generate a response containing only links. Useful in cases where a URL may not have any
     * responses, but can have child URL's.
     *
     * @param uriParent    the parent URI
     * @param uriSelf      the self URI
     * @param filterLinks  the links filter
     * @param aChildLinks  the child links to be added
     *
     * @return the response
     */
    protected EntityMBeanResponse getLinksOnlyResponseBody(URI            uriParent,
                                                           URI            uriSelf,
                                                           Filter filterLinks,
                                                           String...      aChildLinks)
        {
        EntityMBeanResponse responseEntity = createResponse(uriParent, uriSelf, filterLinks);

        if (aChildLinks != null)
            {
            Arrays.stream(aChildLinks).forEach(l -> responseEntity.addResourceLink(l, getSubUri(uriSelf, l)));
            }

        return responseEntity;
        }

    /**
     * Generate a response containing only links. Useful in cases where a URL may not have any
     * responses, but can have child URL's.
     *
     * @param uriParent    the parent URI
     * @param uriSelf      the current URI
     * @param aChildLinks  the child links to be added
     *
     * @return the response
     */
    protected EntityMBeanResponse getLinksOnlyResponseBody(URI uriParent, URI uriSelf, String... aChildLinks)
        {
        return getLinksOnlyResponseBody(uriParent, uriSelf, getLinksFilter(), aChildLinks);
        }


    protected Map getAggregatedMetrics(String       sLocator,
                                                       String       sAttribute,
                                                       String       sCollector,
                                                       QueryBuilder bldrQuery)
        {
        try
            {
            MBeanAccessor accessor = getMBeanAccessor();
            return accessor.aggregate(bldrQuery.build(), sLocator, sAttribute, sCollector);
            }
        catch (RuntimeException e)
            {
            Response.Status status = Response.Status.SERVICE_UNAVAILABLE;
            for (Throwable t = e; t != null; t = t.getCause())
                {
                if (t instanceof IllegalArgumentException ||
                        t instanceof AttributeNotFoundException)
                    {
                    status = Response.Status.BAD_REQUEST;
                    }
                }
            // if the request was well formed the issue must be with the remote
            // MBeanServer; log an error
            if (status.equals(Response.Status.BAD_REQUEST))
                {
                throw new WebApplicationException(Response.status(status).
                        entity("HTTP " + status.getStatusCode() + ' ' + status.getReasonPhrase() + '\n' +
                                e.getMessage()).build());
                }
            else
                {
                log("Exception occurred while aggregating metrics with query "
                        + bldrQuery.build() + "\n" + getStackTrace(e), CacheFactory.LOG_ERR);
                throw new WebApplicationException();
                }
            }
        }

    /**
     * Get the response, if the request is a query. Queries are special in the fact that
     * they start from the root resource(Cluster), and takes in an filter map.
     *
     * @param  mapQuery      the object query map, query map contains which child elements must be returned
     * @param  mapArguments  the arguments to the child resource
     * @param  uriParent     the parent URI
     *
     * @return the response for the query
     */
    protected EntityMBeanResponse getQueryResult(Map mapQuery, Map mapArguments, URI uriParent)
        {
        return null;
        }

    /**
     * For the provided child resource, add the response of the query request.
     *
     * @param resource        the child Resource class
     * @param mapResponse        the response map, to which the child response must be added
     * @param sChildResourceKey  the string key of the child in the query
     * @param mapQuery           the object query map, query map contains which child elements must be returned
     * @param uriParent          the parent URI
     */
    protected void addChildResourceQueryResult(AbstractManagementResource resource,
                                               String                     sChildResourceKey,
                                               Map        mapResponse,
                                               Map                        mapQuery,
                                               Map        mapArguments,
                                               URI                        uriParent)
        {
        Object childQueryEntity = mapQuery.get(sChildResourceKey);
        if (childQueryEntity != null && childQueryEntity instanceof Map)
            {
            EntityMBeanResponse responseEntity
                    = resource.getQueryResult((Map) childQueryEntity, mapArguments, uriParent);
            // add the response only if there is an entity
            if (responseEntity != null)
                {
                mapResponse.put(sChildResourceKey, responseEntity.toJson());
                }
            }
        }

    /**
     * For the provided child MBean query, fetch the response and add to the parent JSON.
     *
     * @param sChildKey    the string key of the child in the query
     * @param bldrQuery    the child Mbean query builder
     * @param mapResponse  the response map, to which the child response must be added
     * @param mapQuery     the object query map, query map contains which child elements must be returned
     * @param childLinks   the child links
     */
    protected void addChildMbeanQueryResult(String              sChildKey,
                                            QueryBuilder        bldrQuery,
                                            Map mapResponse,
                                            Map                 mapQuery,
                                            String...           childLinks)
        {
        Object oChildValue = mapQuery.get(sChildKey);
        if (oChildValue != null && oChildValue instanceof Map)
            {
            Map mapChildrenQuery = (Map) oChildValue;
            EntityMBeanResponse responseEntity = getResponseEntityForMbean(bldrQuery, getParentUri(),
                getCurrentUri(), getAttributesFilter(mapChildrenQuery), getLinksFilter(mapChildrenQuery), childLinks);

            if (responseEntity != null)
                {
                mapResponse.put(sChildKey, responseEntity.toJson());
                }
            }
        }

    /**
     * Add the aggregated metrics of the provided MBean type in the response.
     *
     * @param sRoleName    either a regex to be applied against node ids or a role name
     * @param sCollector   the collector to use instead of the default
     * @param mapResponse  the response map to which the metrics needs to be added.
     */
    protected void addAggregatedMetricsToResponseMap(String              sRoleName,
                                                     String              sCollector,
                                                     QueryBuilder        bldrQuery,
                                                     Map mapResponse)
        {
        Map mapAggregatedMetrics =
                getAggregatedMetrics(sRoleName, null, sCollector, bldrQuery);

        Filter filterAttributes = getAttributesFilter();

        for (Map.Entry entry : mapAggregatedMetrics.entrySet())
            {
            String sAttributeKey = entry.getKey();
            if (filterAttributes.evaluate(sAttributeKey.toUpperCase()))
                {
                mapResponse.put(getRestName(sAttributeKey), Converter.convert(entry.getValue()));
                }
            }
        }

    /**
     * The filter used against the domainPartition.
     *
     * @return the filter used against the domainPartition
     */
    protected Filter getDomainPartitionFilter()
        {
        return m_filterDomainPartition;
        }

    /**
     * Return the reference to be used to link to a Member.
     * 

* If the provided {@link ObjectName} has a key property {@link MBeanAccessor#MEMBER member}, return its * property value. Otherwise, return the {@link ObjectName} key property value for * {@link MBeanAccessor#NODE_ID nodeId}. * * @param objName the ObjectName of the MBean * * @return the member reference */ protected String getMemberReference(ObjectName objName) { String sMemberName = objName.getKeyProperty(MEMBER); if (sMemberName != null) { return sMemberName; } return objName.getKeyProperty(MBeanAccessor.NODE_ID); } /** * Return the value corresponding to the key "children" * * @param mapQuery the map which needs to be used * * @return the children value */ protected Object getChildrenQuery(Map mapQuery) { return mapQuery == null ? null : mapQuery.get(CHILDREN); } /** * Return a {@link Map} which contains the attributes of the provided MBean. * * @param filterAttributes the filter to be applied on the attributes * @param mapResponse the response map * @param sObjName the ObjectName of the MBean * * @return the {@link Map} containing the attributes of the MBean * * @throws Exception thrown in case of JMX exceptions */ protected Map getMBeanAttributesMap(Filter filterAttributes, Map mapResponse, String sObjName) throws Exception { Map mapAttributes = new LinkedHashMap<>(); for (Map.Entry entry : mapResponse.entrySet()) { String sAttrName = getRestName(entry.getKey()); if (filterAttributes.evaluate(sAttrName)) { mapAttributes.put(sAttrName, Converter.convert(entry.getValue())); } } for (Map.Entry entryKeyValue : new ObjectName(sObjName).getKeyPropertyList().entrySet()) { String sKey = getRestName(entryKeyValue.getKey()); if (filterAttributes.evaluate(sKey)) { // avoid clobbering existing MBean attribute when there is a ObjectName key property with same name. // examples include Service MBean Type attribute and PSOldGen MemoryPool MBean Type attribute // clashing with ObjectName key property type. mapAttributes.putIfAbsent(sKey, entryKeyValue.getValue()); } } return mapAttributes; } /** * Convert the entity map to an {@link AttributeList} * * @param mapEntity the input entity map * * @return the {@link AttributeList} */ protected AttributeList getAttributeList(Map mapEntity) { return new AttributeList(mapEntity.entrySet() .stream().map(e -> new Attribute(fromRestName(e.getKey()), e.getValue())) .collect(Collectors.toList())); } /** * Return an attributes filter based on the URI query parameters. * * @return the attributes filter */ protected Filter getAttributesFilter() { // MBean attributes are called "fields" in the REST language String sIncludeFields = m_uriInfo.getQueryParameters().getFirst(INCLUDE_FIELDS); String sExcludeFields = m_uriInfo.getQueryParameters().getFirst(EXCLUDE_FIELDS); return getAttributesFilter(sIncludeFields, sExcludeFields); } /** * Return an attributes filter based on the provided include and exclude strings. * * @param sIncludeFields the comma separated list of included attributes * @param sExcludeFields the comma separated list of excluded attributes * * @return the attributes filter */ protected Filter getAttributesFilter(String sIncludeFields, String sExcludeFields) { Filter filterAttributes = Filters.always(); if (sIncludeFields != null) { Set setIncludedFields = Arrays.stream(sIncludeFields.split(",")) .map(String::toUpperCase) .collect(Collectors.toSet()); filterAttributes = Filters.in(String::toUpperCase, setIncludedFields); } if (sExcludeFields != null) { Set setExcludedFields = Arrays.stream(sExcludeFields.split(",")) .map(String::toUpperCase) .collect(Collectors.toSet()); Filter filterExclude = Filters.not(Filters.in(String::toUpperCase, setExcludedFields)); filterAttributes = filterExclude.and(filterAttributes); } return filterAttributes; } /** * Return a links filter based on the URI query parameters. * * @return the links filter */ protected Filter getLinksFilter() { String sIncludeLinks = m_uriInfo.getQueryParameters().getFirst(INCLUDE_LINKS); String sExcludeLinks = m_uriInfo.getQueryParameters().getFirst(EXCLUDE_LINKS); Filter filterLinks = Filters.always(); if (sIncludeLinks != null) { Set setIncludedLinks = Arrays.stream(sIncludeLinks.split(",")) .collect(Collectors.toSet()); filterLinks = Filters.in(ValueExtractor.identity(), setIncludedLinks); } if (sExcludeLinks != null) { Set setExcludedLinks = Arrays.stream(sExcludeLinks.split(",")) .collect(Collectors.toSet()); Filter filterExclude = Filters.not(Filters.in(ValueExtractor.identity(), setExcludedLinks)); filterLinks = filterExclude.and(filterLinks); } return filterLinks; } /** * Return a fields filter, the filter parameters is taken from the query map if that is not null * else it is taken from the URI query parameters. * * @param mapQuery the query map * * @return the fields filter */ protected Filter getAttributesFilter(Map mapQuery) { if (mapQuery == null) { return getAttributesFilter(); } List listIncludeFields = (List) mapQuery.get(INCLUDE_FIELDS); List listExcludeFields = (List) mapQuery.get(EXCLUDE_FIELDS); Filter filterAttributes = Filters.always(); if (listIncludeFields != null) { Set setIncludedFields = listIncludeFields.stream() .map(String::toUpperCase) .collect(Collectors.toSet()); filterAttributes = Filters.in(String::toUpperCase, setIncludedFields); } if (listExcludeFields != null) { Set setExcludedFields = listExcludeFields.stream() .map(String::toUpperCase) .collect(Collectors.toSet()); Filter filterExclude = Filters.not(Filters.in(String::toUpperCase, setExcludedFields)); filterAttributes = filterExclude.and(filterAttributes); } return filterAttributes; } /** * Return a links filter, the filter parameters is taken from the query map if that is not null * else it is taken from the URI query parameters. * * @param mapQuery the query map * * @return the links filter */ protected Filter getLinksFilter(Map mapQuery) { if (mapQuery == null) { return getLinksFilter(); } List listIncludeLinks = (List) mapQuery.get(INCLUDE_LINKS); List listExcludeLinks = (List) mapQuery.get(EXCLUDE_LINKS); Filter filterLinks = Filters.always(); if (listIncludeLinks != null) { Set setIncludedLinks = listIncludeLinks.stream() .collect(Collectors.toSet()); filterLinks = Filters.in(ValueExtractor.identity(), setIncludedLinks); } if (listExcludeLinks != null) { Set setExcludedLinks = listExcludeLinks.stream() .map(s -> fromRestName(s)) .collect(Collectors.toSet()); Filter filterExclude = Filters.not(Filters.in(ValueExtractor.identity(), setExcludedLinks)); filterLinks = filterExclude.and(filterLinks); } return filterLinks; } /** * Get the exclude list, from the mapQuery, if not null, else from the * URI query parameter. * * @param mapQuery the Query map * * @return the comma separated list of attributes which needs to be excluded */ protected String getExcludeList(Map mapQuery) { if (mapQuery == null) { return m_uriInfo.getQueryParameters().getFirst(EXCLUDE_FIELDS); } List listExcludeFields = (List) mapQuery.get(EXCLUDE_FIELDS); return listExcludeFields == null ? null : listExcludeFields.stream().collect(Collectors.joining(",")); } /** * Create an entity response. * * @param parentUri the parent URI which needs to be added to the response * @param selfUri the self URI which needs to be added to the response * @param linksFilter the filter which needs to be applied on the links * * @return the entity response */ protected EntityMBeanResponse createResponse(URI parentUri, URI selfUri, Filter linksFilter) { EntityMBeanResponse responseBody = new EntityMBeanResponse(m_requestContext, linksFilter); responseBody.addParentResourceLink(parentUri); responseBody.addSelfResourceLinks(selfUri); return responseBody; } /** * Create a response from the provided entity response. This method will throw an exception * if there is no entity in the MBean response. * * @param responseEntity the response entity * * @return the {@link Response} object */ protected Response response(EntityMBeanResponse responseEntity) { if (responseEntity == null || (!responseEntity.hasFailures() && responseEntity.getEntities().isEmpty() && responseEntity.getEntity().isEmpty())) { return Response.status(Response.Status.NOT_FOUND).build(); } // check if there are failures, and if so, should be classified as bad request if (responseEntity.hasFailures()) { return Response.status(Response.Status.BAD_REQUEST).entity(responseEntity.toJson()).build(); } return Response.ok(responseEntity.toJson()).build(); } /** * Set the filter to be applied against the domainPartition. * * @param filter a filter to apply against the domainPartition */ protected void setDomainPartitionFilter(Filter filter) { m_filterDomainPartition = filter; } /** * Create an OK response with the provided map as entity. * * @param mapResponse the response entity * * @return the {@link Response} object */ protected Response response(Map mapResponse) { return Response.ok(mapResponse).build(); } /** * Set the cluster name. * * @param sClusterName the cluster name */ public void setClusterName(String sClusterName) { m_sClusterName = sClusterName; } /** * Check for any attribute that must always converted to {@link Long}/{@link Integer}/{@link Float}. * * @param entity {@link Map} to check */ protected void checkAttributeTypeConversion(Map entity) { checkAttributeTypeConversion(entity, false); } /** * Check for any attribute that must always be converted to {@link Long}/{@link Integer}/{@link Float}. *

* The type of the {@code expiryDelay} attribute for {@code CacheMBean} is {@link Integer} but it * is {@link Long} for {@code ManagementMBean}, therefore, this code takes this into account. * * @param entity {@link Map} to check * @param fManagement a flag to indicate if the query type is Management * * @throws IllegalArgumentException if type conversion for attribute's value fails */ protected void checkAttributeTypeConversion(Map entity, boolean fManagement) { entity.replaceAll((k, v) -> { Class clzConvertTo = Object.class; try { if ((SET_LONG.contains(k) || (fManagement && k.compareToIgnoreCase("expiryDelay") == 0)) && !(v instanceof Long)) { clzConvertTo = Long.TYPE; return Long.valueOf(v.toString()); } else if (SET_INTEGER.contains(k) && !(v instanceof Integer)) { clzConvertTo = Integer.TYPE; return Integer.valueOf(v.toString()); } else if (SET_FLOAT.contains(k) && !(v instanceof Float)) { clzConvertTo = Float.TYPE; return Float.valueOf(v.toString()); } else { return v; } } catch (Exception e) { throw new IllegalArgumentException("invalid value for attribute " + k + "; failed type conversion to " + clzConvertTo.getName() + " due to " + e.getClass().getName() + " " + e.getMessage(), e); } }); } // ----- accessors ------------------------------------------------------ /** * The service name parameter from the URI. * * @return the service name */ protected String getService() { return m_uriInfo.getPathParameters().getFirst(SERVICE_NAME); } /** * The parent URI of the resource. * * @return the parent URI */ protected URI getParentUri() { return getParentUri(m_uriInfo); } /** * The URI of the current resource. * * @return the resource URI */ protected URI getCurrentUri() { return getSubUri(m_uriInfo); } /** * The {@link MBeanServerProxy} to be used. * * @return the {@link MBeanServerProxy} */ protected MBeanServerProxy getMBeanServerProxy() { return m_mBeanServerProxy; } /** * The {@link ContainerRequestContext} of the current request. * * @return the {@link ContainerRequestContext} */ protected ContainerRequestContext getRequestContext() { return m_requestContext; } /** * The cluster name to be used in the resource. * * @return the cluster name */ protected String getCluster() { return m_sClusterName; } /** * The MBean Domain name to be used in the resource. * * @return the MBean domain name */ protected String getMBeanDomainName() { return ensureMBeanDomainName(); } // ----- static helper methods ------------------------------------------ private static String ensureMBeanDomainName() { if (s_sMBeanDomainName == null) { synchronized (AbstractManagementResource.class) { if (s_sMBeanDomainName == null) { Registry registry = CacheFactory.getCluster().getManagement(); String sDomainName = registry.getDomainName(); s_sMBeanDomainName = sDomainName == null || sDomainName.isEmpty() ? "Coherence*" : sDomainName; } } } return s_sMBeanDomainName; } /** * Convert a name into a REST standards compatible name. * * @param sName the service name to be normalized * * @return the REST compatible name */ public static String getRestName(String sName) { // find the first set of upper case letters int count = 0; for (; count < sName.length(); count++) { if (!Character.isUpperCase(sName.charAt(count))) { break; } } if (count == sName.length()) { // all upper case - leave it alone return sName; } if (count == 0) { // doesn't start upper case - leave it alone return sName; } if (count == 1) { // first letter is upper case and next letter is lower case, so convert // first letter to lower case // for example RefreshTime must be returned as refreshTime return sName.substring(0, count).toLowerCase() + sName.substring(count); } // starts with an acronym - leave it alone return sName; } /** * Convert a name from a REST standards compatible name to attribute name. * * @param sName the service name to be normalized * * @return the REST compatible name */ public static String fromRestName(String sName) { // we are assuming here that any attribute which can be updated belongs to the standard // set of attributes which we converted in the getRestName method above // we need to have a better logic based on a cached set of MBeaninfo objects here // if we find more number of instances of attributes which starts with acronym etc return sName.substring(0, 1).toUpperCase() + sName.substring(1); } /** * Append the provided segments to the parent URI. * * @param uriParent the parent URI * @param asSegments the segments to be appended * * @return the resulting URI */ public static URI getSubUri(URI uriParent, String... asSegments) { UriBuilder bldr = UriBuilder.fromUri(uriParent); for (String segment : asSegments) { int cSlash = segment.indexOf('/'); if (cSlash == -1) { bldr.segment(segment); } else { for (String sPart : PATH_PATTERN.split(segment)) { bldr.segment(sPart); } } } return bldr.build(); } /** * Append the provided segments to the current URI. * * @param uriInfo the URI info object * @param asSegments the segments to be appended * * @return the resulting URI */ public static URI getSubUri(UriInfo uriInfo, String... asSegments) { UriBuilder builder = uriInfo.getAbsolutePathBuilder(); Arrays.stream(asSegments).forEach(builder::segment); return builder.build(); } /** * Return the parent URI of the resource. * * @param uriInfo the URI info object * * @return the parent URI */ public static URI getParentUri(UriInfo uriInfo) { int count = getParentUriSegmentsCount(uriInfo); List pathSegments = uriInfo.getPathSegments(); UriBuilder bldr = uriInfo.getBaseUriBuilder(); for (int i = 0; i < count; i++) { bldr.path(pathSegments.get(i).getPath()); } return bldr.build(); } /** * Convert the set string representations of {@link ObjectName}. * * @param setObjectNames the set of object names(string objects) * * @return the set of {@link ObjectName}s * * @throws MalformedObjectNameException thrown in case of malformed object name */ public static Set convertToObjectNames(Set setObjectNames) throws MalformedObjectNameException { Set setObjNames = new HashSet<>(); for (String sObjectName : setObjectNames) { setObjNames.add(new ObjectName(sObjectName)); } return setObjNames; } /** * Return the number of URI segments in the parent URL. * * @param uriInfo the URI Info * * @return the number of segments in the parent URL */ protected static int getParentUriSegmentsCount(UriInfo uriInfo) { List pathSegments = uriInfo.getPathSegments(); int count = pathSegments.size() - 1; // go up a level to get to the parent if (pathSegments.get(count).getPath().isEmpty()) { count--; // go up for one level because of trailing slash } return count; } /** * Create a QueryBuilder, also set the common parameters in the builder. * * @return the QueryBuilder */ protected QueryBuilder createQueryBuilder() { QueryBuilder bldrQuery = new QueryBuilder().withMBeanDomainName(getMBeanDomainName()) .withCluster(getCluster()); Filter filter = getDomainPartitionFilter(); if (filter != null) { bldrQuery.withFilter(DOMAIN_PARTITION, getDomainPartitionFilter()); } return bldrQuery; } protected MBeanAccessor getMBeanAccessor() { MBeanAccessor accessor = m_accessor; if (accessor == null) { accessor = m_accessor = new MBeanAccessor(m_mBeanServerProxy); } return accessor; } // ----- constants ------------------------------------------------------ /** * The query parameter used to filter attributes, the parameter value must be a subset of * attributes which needs to be included. */ public static final String INCLUDE_FIELDS = "fields"; /** * The query parameter used to filter links, the parameter value must be a subset of * links which needs to be included. */ public static final String INCLUDE_LINKS = "links"; /** * The query parameter used to filter attributes, the parameter value must be a subset of * attributes which needs to be excluded. */ public static final String EXCLUDE_FIELDS = "excludeFields"; /** * The query parameter used to filter links, the parameter value must be a subset of * links which needs to be excluded. */ public static final String EXCLUDE_LINKS = "excludeLinks"; /** * Constant used for json application type. */ public static final String MEDIA_TYPE_JSON = MediaType.APPLICATION_JSON; /** * Constant used for xml application type. */ public static final String MEDIA_TYPE_XML = "application/xml"; /** * Constant used for Swagger. */ public static final String MEDIA_TYPE_SWAGGER_JSON = "application/swagger+json"; /** * Swagger resource file name. */ public static final String SWAGGER_RESOURCE = "management-swagger.json"; /** * Constant used for applicable media types in the management REST interface. */ public static final String MEDIA_TYPES = MEDIA_TYPE_JSON; // ------------------------------ Mbean Query patterns ----------------------------------- /** * MBean query to filter out all the CacheMBean objects in the cluster. */ public static final String CACHES_QUERY = ":" + Registry.CACHE_TYPE; /** * MBean query to filter out all the CacheMBean objects of a particular cache. */ public static final String CACHE_QUERY = CACHES_QUERY + ",name="; /** * MBean query to filter out all the CacheMBean objects of a particular cache and service. */ public static final String CACHE_MEMBERS_WITH_SERVICE_QUERY = CACHES_QUERY +",name="; /** * MBean query to filter out all the NodeMBean objects. */ public static final String CLUSTER_MEMBERS_QUERY = ":" + Registry.NODE_TYPE; /** * MBean query to filter out all the ReporterMBean objects. */ public static final String REPORTER_MEMBERS_QUERY = ":" + Registry.REPORTER_TYPE; /** * MBean query to filter out all the Flash journal MBean objects. */ public static final String FLASH_JOURNAL_QUERY = ":" + Registry.JOURNAL_TYPE + ",name=FlashJournalRM"; /** * MBean query to filter out all the RAM journal MBean objects. */ public static final String RAM_JOURNAL_QUERY = ":" + Registry.JOURNAL_TYPE + ",name=RamJournalRM"; /** * MBean query to filter out all the Cluster MBeans. */ public static final String CLUSTER_QUERY = ":" + Registry.CLUSTER_TYPE; /** * MBean query to filter out all the Management MBeans. */ public static final String MANAGEMENT_QUERY = ":" + Registry.MANAGEMENT_TYPE; /** * MBean query to filter out all the PointToPoint MBeans. */ public static final String POINT_TO_POINT_QUERY = ":" + Registry.POINT_TO_POINT_TYPE; /** * MBean query to filter out all the ConnectionManager(Proxy) MBeans. */ public static final String CONNECTION_MANAGERS_QUERY = ":" + Registry.CONNECTION_MANAGER_TYPE; /** * MBean query to filter out all the ConnectionManager(Proxy) MBeans of a specific proxy service. */ public static final String CONNECTION_MANAGER_QUERY = CONNECTION_MANAGERS_QUERY + ",name="; /** * MBean query to filter out all the Connection(Proxy) MBeans. */ public static final String CONNECTIONS_QUERY = ":" + Registry.CONNECTION_TYPE + ",name="; /** * MBean query to filter out all the ServiceMBean of a specific service. */ public static final String SERVICE_MEMBERS_QUERY = ":" + Registry.SERVICE_TYPE + ",name="; /** * MBean query to filter out PartitionAssignment MBean of a specific service. */ public static final String PARTITION_ASSIGNMENT_QUERY = ":" + Registry.PARTITION_ASSIGNMENT_TYPE; /** * MBean query to filter out all ServiceMBean objects. */ public static final String SERVICES_QUERY = ":" + Registry.SERVICE_TYPE; /** * MBean query to filter out all ServiceMBean objects. */ public static final String FEDERATION_TYPE = ":" + Registry.FEDERATION_TYPE; /** * MBean query to filter out FederationManager MBean of a specific federated service. */ public static final String FEDERATION_COORDINATOR_QUERY = FEDERATION_TYPE + ",responsibility=Coordinator"; /** * MBean query to filter out Topology MBeans of a specific federated service and a specific participant. */ public static final String FEDERATION_TOPOLOGY_MEMBER_QUERY = FEDERATION_TYPE + ",subType=Topology,name=%s"; /** * MBean query to filter out Topology MBeans. */ public static final String FEDERATION_TOPOLOGIES_QUERY = FEDERATION_TYPE + ",subType=Topology"; /** * MBean query to filter out Destination MBeans of a specific federated service and a specific participant. */ public static final String DESTINATIONS_QUERY = FEDERATION_TYPE + ",subType=Destination,name="; /** * MBean query to filter out Destination MBeans of a specific federated service. */ public static final String DESTINATIONS_COLLECTION_QUERY= FEDERATION_TYPE + ",subType=Destination"; /** * MBean query to filter out Origin MBeans of a specific federated service. */ public static final String ORIGINS_COLLECTION_QUERY = FEDERATION_TYPE + ",subType=Origin"; /** * MBean query to filter out Origin MBeans of a specific federated service and specific participant. */ public static final String ORIGINS_QUERY = FEDERATION_TYPE + ",subType=Origin,name="; /** * MBean query to filter out PersistenceCoordinator MBean of a specific service. */ public static final String PERSISTENCE_CONTROLLER_QUERY = ":" + Registry.PERSISTENCE_SNAPSHOT_TYPE + ",responsibility=PersistenceCoordinator"; /** * MBean query to filter out platform(JVM) Memory MBean. */ public static final String PLATFORM_MEMORY_QUERY = ":type=Platform,Domain=java.lang,subType=Memory"; /** * MBean query to filter out platform(JVM) MemoryPool MBean(Compressed Class Space). */ public static final String COMPRESSED_CLASS_SPACE_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=Compressed Class Space"; /** * MBean query to filter out platform(JVM) MemoryPool MBean(Metaspace). */ public static final String META_SPACE_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=Metaspace"; /** * MBean query to filter out platform(JVM) PS GarbageCollector MBean(PS Mark sweep). */ public static final String PS_MARK_SWEEP_QUERY = ":type=Platform,Domain=java.lang,subType=GarbageCollector,name=PS MarkSweep"; /** * MBean query to filter out platform(JVM) PS GarbageCollector MBean(PS Scavenge). */ public static final String PS_SCAVENGE_QUERY = ":type=Platform,Domain=java.lang,subType=GarbageCollector,name=PS Scavenge"; /** * MBean query to filter out platform(JVM) PS MemoryPool MBean(PS Old Gen). */ public static final String PS_OLDGEN_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=PS Old Gen"; /** * MBean query to filter out platform(JVM) PS MemoryPool MBean(Code Cache). */ public static final String CODECACHE_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=Code Cache"; /** * MBean query to filter out platform(JVM) PS MemoryPool MBean(PS Eden Space). */ public static final String PS_EDEN_SPACE_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=PS Eden Space"; /** * MBean query to filter out platform(JVM) PS MemoryPool MBean(PS Survivor Space). */ public static final String PS_SURVIVOR_SPACE_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=PS Survivor Space"; /** * MBean query to filter out platform(JVM) OperatingSystem MBean. */ public static final String OS_QUERY = ":type=Platform,Domain=java.lang,subType=OperatingSystem"; /** * MBean query to filter out platform(JVM) Runtime MBean. */ public static final String RUNTIME_QUERY = ":type=Platform,Domain=java.lang,subType=Runtime"; /** * MBean query to filter out platform(JVM) G1 GarbageCollector MBean(G1 Old Generation). */ public static final String G1_OLD_GENERATION_QUERY = ":type=Platform,Domain=java.lang,subType=GarbageCollector,name=G1 Old Generation"; /** * MBean query to filter out platform(JVM) G1 GarbageCollector MBean(G1 Young Generation). */ public static final String G1_YOUNG_GENERATION_QUERY = ":type=Platform,Domain=java.lang,subType=GarbageCollector,name=G1 Young Generation"; /** * MBean query to filter out platform(JVM) G1 MemoryPool MBean(G1 Eden Space). */ public static final String G1_EDEN_SPACE_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=G1 Eden Space"; /** * MBean query to filter out platform(JVM) G1 MemoryPool MBean(G1 Old Gen). */ public static final String G1_OLDGEN_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=G1 Old Gen"; /** * MBean query to filter out platform(JVM) G1 MemoryPool MBean(G1 Survivor Space). */ public static final String G1_SURVIVOR_SPACE_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=G1 Survivor Space"; /** * MBean query to filter out platform(JVM) G1 MemoryPool MBean(CodeHeap 'non-nmethods'). */ public static final String G1_CODEHEAP_NON_NMETHODS_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=CodeHeap \'non-nmethods\'"; /** * MBean query to filter out platform(JVM) G1 MemoryPool MBean(CodeHeap 'profiled nmethods'). */ public static final String G1_CODEHEAP_PROFILED_NMETHODS_QUERY = ":type=Platform,Domain=java.lang,subType=MemoryPool,name=CodeHeap \'profiled nmethods\'"; /** * MBean query to filter out platform(JVM) G1 MemoryManager MBean(CodeCacheManager). */ public static final String G1_CODECACHE_MANAGER = ":type=Platform,Domain=java.lang,subType=MemoryManager,name=CodeCacheManager"; /** * MBean query to filter out platform(JVM) G1 MemoryManager MBean(Metaspace Manager). */ public static final String G1_METASPACE_MANAGER = ":type=Platform,Domain=java.lang,subType=MemoryManager,name=Metaspace Manager"; /** * MBean query to filter out HttpSessionManager(CWEb) MBeans. The * before the HttpSessionManager is to filter * out 2 kinds of MBeans, HttpSessionManager and WeblogicHttpSessionManager MBeans. */ public static final String CWEB_APPLICATIONS_QUERY = ":type=*HttpSessionManager"; /** * MBean query to filter out HttpSessionManager(CWEb) MBeans of a particular application. * The * before the HttpSessionManager is to filter out 2 kinds of MBeans, HttpSessionManager * and WeblogicHttpSessionManager MBeans. */ public static final String CWEB_APPLICATION_QUERY = ":type=*HttpSessionManager,appId="; /** * MBean query to filter out all StorageManager MBean objects in the cluster. */ public static final String STORAGE_MANAGERS_ALL_QUERY = ":type=StorageManager"; /** * MBean query to filter out StorageManager MBean of a specific cache and service, running on a specific node. */ public static final String STORAGE_MANAGERS_QUERY = ":type=StorageManager,cache=%s"; /** * MBean query to filter out StorageManager MBean of a specific cache and service, running on a specific node. */ public static final String STORAGE_MANAGER_QUERY = ":type=StorageManager,cache=%s,service=%s,nodeId=%s"; // ------------------------------ Mbean Query patterns ends --------------------------------- // ------------------------------ Path param constants -------------------------------------- public static final String CLUSTER_NAME = "clusterName"; public static final String SERVICE_NAME = "serviceName"; public static final String CACHE_NAME = "cacheName"; public static final String MEMBER_KEY = "memberKey"; public static final String VERSION = "versionName"; public static final String PARTICIPANT_NAME = "participantName"; public static final String TOPOLOGY_NAME = "topologyName"; public static final String OPERATION_NAME = "operationName"; public static final String PLATFORM_MBEAN = "platformMBean"; public static final String APPLICATION_ID = "applicationId"; public static final String DOMAIN_PARTITION = "domainPartition"; public static final String TOPOLOGIES = "topologies"; public static final String SNAPSHOT_NAME = "snapshotName"; public static final String JFR_CMD = "jfrCmd"; // ------------------------------ Path param constants ends -------------------------------------- // ------------------------------ URL constants -------------------------------------------------- public static final String METADATA_CATALOG = "metadata-catalog"; public static final String SERVICES = "services"; public static final String MEMBERS = "members"; public static final String REPORTERS = "reporters"; public static final String CACHES = "caches"; public static final String MANAGEMENT = "management"; public static final String SHUTDOWN = "shutdown"; public static final String CLUSTER = "cluster"; public static final String SEARCH = "search"; public static final String STORAGE = "storage"; public static final String JOURNAL = "journal"; public static final String JOURNAL_TYPE = "journalType"; public static final String NETWORK_STATS = "networkStats"; public static final String VERBOSE = "verbose"; public static final String WEB_APPS = "webApplications"; public static final String PERSISTENCE = "persistence"; public static final String PROXY = "proxy"; public static final String STATISTICS = "statistics"; public static final String INCOMING = "incoming"; public static final String OUTGOING = "outgoing"; public static final String DESCRIPTION = "description"; // ------------------------------ URL constants ends --------------------------------------------- // ------------------------------ Misc constants ------------------------------------------------- public static final String LOADER = "loader"; public static final String MEMBER = "member"; public static final String CONNECTIONS = "connections"; public static final String ROLE_NAME = "role"; public static final String COLLECTOR = "collector"; public static final String PLATFORM = "platform"; public static final String RAM_JOURNAL_TYPE = "ram"; public static final String FLASH_JOURNAL_TYPE = "flash"; public static final String PARTITION = "partition"; public static final String RESET_STATS = "resetStatistics"; public static final String CHILDREN = "children"; public static final String NAME = "name"; public static final String TYPE = "type"; public static final String NODE_ID = "nodeId"; public static final String SERVICE = "service"; public static final String TIER_BACK = "back"; public static final String TIER = "tier"; public static final String OPTIONS = "options"; public static final String CACHE = "cache"; public static final String TRUNCATE = "truncate"; public static final String CLEAR = "clear"; /** * Map of URL to platform Mbean query. */ public static final Map MAP_PLATFORM_URL_TO_MBEAN_QUERY = Collections.unmodifiableMap(new HashMap() {{ put("memory", PLATFORM_MEMORY_QUERY); put("metaSpace", META_SPACE_QUERY); put("compressedClassSpace", COMPRESSED_CLASS_SPACE_QUERY); put("operatingSystem", OS_QUERY); put("runtime", RUNTIME_QUERY); }}); /** * Map of URL to platform PS GC Mbean query. */ public static final Map MAP_PLATFORM_PS_URL_TO_MBEAN_QUERY = Collections.unmodifiableMap(new HashMap() {{ put("psMarkSweep", PS_MARK_SWEEP_QUERY); put("psScavenge", PS_SCAVENGE_QUERY); put("psOldGen", PS_OLDGEN_QUERY); put("psEdenSpace", PS_EDEN_SPACE_QUERY); put("psSurvivorSpace", PS_SURVIVOR_SPACE_QUERY); put("codeCache", CODECACHE_QUERY); }}); /** * Map of URL to platform G1 GC Mbean query. */ public static final Map MAP_PLATFORM_G1_URL_TO_MBEAN_QUERY = Collections.unmodifiableMap(new HashMap() {{ put("g1EdenSpace", G1_EDEN_SPACE_QUERY); put("g1OldGen", G1_OLDGEN_QUERY); put("g1OldGeneration", G1_OLD_GENERATION_QUERY); put("g1SurvivorSpace", G1_SURVIVOR_SPACE_QUERY); put("g1YoungGeneration", G1_YOUNG_GENERATION_QUERY); put("g1CodeHeapNonNMethods", G1_CODEHEAP_NON_NMETHODS_QUERY); put("g1CodeHeapProfiledNMethods", G1_CODEHEAP_PROFILED_NMETHODS_QUERY); put("g1CodeCacheManager", G1_CODECACHE_MANAGER); put("g1MetaSpaceManager", G1_METASPACE_MANAGER); }}); /** * Map of journal type fo MBean query. */ public static final Map MAP_JOURNAL_URL_TO_MBEAN_QUERY = Collections.unmodifiableMap(new HashMap() {{ put("flash", FLASH_JOURNAL_QUERY); put("ram", RAM_JOURNAL_QUERY); }}); /** * Set of attributes to be converted to Long. */ private static final Set SET_LONG = new HashSet<>(Arrays.asList( "intervalSeconds", "currentBatch", "taskHungThresholdMillis", "maxQueryThresholdMillis", "transportRetainedBytes", "requestTimeoutMillis", "taskTimeoutMillis")); /** * Set of attributes to be converted to Integer. */ private static final Set SET_INTEGER = new HashSet<>(Arrays.asList( "expiryDelay")); /** * Set of attributes to be converted to Float. */ private static final Set SET_FLOAT = new HashSet<>(Arrays.asList( "tracingSamplingRatio")); /** * Cached pattern for splitting request paths. */ private static final Pattern PATH_PATTERN = Pattern.compile("/"); // ----- data members --------------------------------------------------- /** * The request headers, available in the context. */ @Context protected HttpHeaders m_requestHeaders; /** * The UriInfo available in the context. */ @Context protected UriInfo m_uriInfo; /** * The container request context. */ @Context protected ContainerRequestContext m_requestContext; /** * The Mbean server proxy. */ @Context protected MBeanServerProxy m_mBeanServerProxy; /** * The filter used against the domainPartition. */ private Filter m_filterDomainPartition; /** * The cluster name to be used by the resource. This has to be set while * creating the resource. */ private String m_sClusterName; /** * The Coherence MBean domain name to be used. */ private static volatile String s_sMBeanDomainName = null; /** * The {@link MBeanAccessor} to use to access MBean information. */ protected MBeanAccessor m_accessor; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy