package org.jolokia.request; /* * Copyright 2009-2013 Roland Huss * * Licensed 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. */ import java.util.*; import org.jolokia.config.*; import org.jolokia.converter.json.ValueFaultHandler; import org.jolokia.util.*; import org.json.simple.JSONObject; /** * Abstract base class for a JMX request. This is the server side * representation of a Jolokia request. * * * @author roland * @since 15.03.11 */ public abstract class JmxRequest { // Type of request private RequestType type; // An optional target configuration private ProxyTargetConfig targetConfig = null; // Processing configuration for tis request object private ProcessingParameters processingConfig; // A value fault handler for dealing with exception when extracting values private ValueFaultHandler valueFaultHandler; // HTTP method which lead to this request. The method is selected dependent on the // constructor used. private HttpMethod method; // Path parts, which are used for selecting parts of the return value private List<String> pathParts; /** * Constructor used for representing {@link HttpMethod#GET} requests. * * @param pType request type * @param pPathParts an optional path, splitted up in parts. Not all requests do handle a path. * @param pProcessingParams init parameters provided as query params for a GET request. They are used to * to influence the processing. */ protected JmxRequest(RequestType pType, List<String> pPathParts, ProcessingParameters pProcessingParams) { this(pType, HttpMethod.GET, pPathParts, pProcessingParams); } /** * Constructor used for {@link HttpMethod#POST} requests, which receive a JSON payload. * * @param pMap map containing requests parameters * @param pInitParams optional processing parameters (obtained as query parameters or from within the * JSON request) */ public JmxRequest(Map<String, ?> pMap, ProcessingParameters pInitParams) { this(RequestType.getTypeByName((String) pMap.get("type")), HttpMethod.POST, EscapeUtil.parsePath((String) pMap.get("path")), pInitParams); Map target = (Map) pMap.get("target"); if (target != null) { targetConfig = new ProxyTargetConfig(target); } } // Common parts of both constructors private JmxRequest(RequestType pType, HttpMethod pMethod, List<String> pPathParts, ProcessingParameters pProcessingParams) { method = pMethod; type = pType; verifyPath(pPathParts); pathParts = pPathParts; initParameters(pProcessingParams); } /** * Get request type * * @return request type of this request. */ public RequestType getType() { return type; } /** * Get a processing configuration or null if not set * @param pConfigKey configuration key to fetch * @return string value or <code>null</code> if not set */ public String getParameter(ConfigKey pConfigKey) { return processingConfig.get(pConfigKey); } /** * Get a processing configuration as integer or null * if not set * * @param pConfigKey configuration to lookup * @return integer value of configuration or 0 if not set. */ public int getParameterAsInt(ConfigKey pConfigKey) { String intValueS = processingConfig.get(pConfigKey); if (intValueS != null) { return Integer.parseInt(intValueS); } else { return 0; } } /** * Get a processing configuration as a boolean value * * @param pConfigKey configuration to lookup * @return boolean value of the configuration, the default value or false if the default value is null */ public Boolean getParameterAsBool(ConfigKey pConfigKey) { String booleanS = getParameter(pConfigKey); return Boolean.parseBoolean(booleanS != null ? booleanS : pConfigKey.getDefaultValue()); } /** * Get the proxy target configuration provided with the request * * @return the proxy target configuration or null if the the request * is not a proxy based request. */ public ProxyTargetConfig getTargetConfig() { return targetConfig; } /** * HTTP method used for creating this request * * @return HTTP method which lead to this request */ public HttpMethod getHttpMethod() { return method; } /** * Get tha value fault handler, which can be passwed around. * @return the value fault handler */ public ValueFaultHandler getValueFaultHandler() { return valueFaultHandler; } /** * Textual description of this request containing base information. Can be used in toString() methods * of subclasses * * @return description of this base request */ protected String getInfo() { StringBuffer ret = new StringBuffer(); if (pathParts != null) { ret.append(", path=").append(pathParts); } if (targetConfig != null) { ret.append(", target=").append(targetConfig); } return ret.length() > 0 ? ret.toString() : null; } /** * Get the parts of a path * * @return the parts of an path or null if no path was used */ public List<String> getPathParts() { return pathParts; } /** * Get the path combined with proper escaping * * @return path as string or null if no path is given. */ public String getPath() { return EscapeUtil.combineToPath(pathParts); } /** * Convert this request to a JSON object, which can be used as a part of a return value. * * @return JSON object representing this base request object */ public JSONObject toJSON() { JSONObject ret = new JSONObject(); ret.put("type",type.getName()); if (targetConfig != null) { ret.put("target", targetConfig.toJSON()); } if (pathParts != null) { try { ret.put("path",getPath()); } catch (UnsupportedOperationException exp) { // Happens when request doesnt support paths } } return ret; } // Init parameters and value fault handler private void initParameters(ProcessingParameters pParams) { processingConfig = pParams; String ignoreErrors = processingConfig.get(ConfigKey.IGNORE_ERRORS); if (ignoreErrors != null && ignoreErrors.matches("^(true|yes|on|1)$")) { valueFaultHandler = ValueFaultHandler.IGNORING_VALUE_FAULT_HANDLER; } else { valueFaultHandler = ValueFaultHandler.THROWING_VALUE_FAULT_HANDLER; } } private void verifyPath(List<String> pPathParts) { if (pPathParts != null && !pPathParts.isEmpty() && pPathParts.get(pPathParts.size() - 1) == null) { String path = EscapeUtil.combineToPath(pPathParts); throw new IllegalArgumentException("Path '" + path + "' must not end with a wildcard"); } } }