package org.jolokia.detector; /* * 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.Map; import javax.management.*; import org.jolokia.backend.executor.MBeanServerExecutor; import org.jolokia.config.ConfigKey; import org.jolokia.config.Configuration; import org.jolokia.request.JmxRequest; import org.jolokia.util.LogHandler; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; /** * Information about the the server product the agent is running in. * * @author roland * @since 05.11.10 */ public class ServerHandle { // product name of server running private String product; // version number private String version; // extra information private Map<String,String> extraInfo; // vendor name private String vendor; /** * Constructor * * @param vendor product vendor (like RedHat or Oracle) * @param product name of the product * @param version version * @param extraInfo free form extra information */ public ServerHandle(String vendor, String product, String version, Map<String, String> extraInfo) { this.product = product; this.version = version; this.extraInfo = extraInfo; this.vendor = vendor; } /** * Get name of vendor */ public String getVendor() { return vendor; } /** * Get the name of the server this agent is running in * * @return server name */ public String getProduct() { return product; } /** * Get version number of the agent server * @return version number */ public String getVersion() { return version; } /** * Get extra information specific to a server. A subclass can overwrite this in order * to provide dynamice information on the server which gets calculated afresh * on each invokation. * * * * @param pServerManager MBeanServers to query * @return a map of extra info or <code>null</code> if no extra information is given. */ public Map<String,String> getExtraInfo(MBeanServerExecutor pServerManager) { return extraInfo; } /** * Hook for performing certain workarounds/pre processing just before * a request gets dispatched * * @param pMBeanServerExecutor the detected MBeanServers * @param pJmxReq the request to dispatch */ public void preDispatch(MBeanServerExecutor pMBeanServerExecutor, JmxRequest pJmxReq) { // Do nothing } /** * Hook called after the detection phase. This can be used by a handle to perform * some specific action, possibly based on the configuration given. * * The default is a no-op. * * @param pServerManager * @param pConfig agent configuration * @param pLoghandler logger to use for logging any error. */ public void postDetect(MBeanServerExecutor pServerManager, Configuration pConfig, LogHandler pLoghandler) { // Do nothing } /** * Register a MBean at the dedicated server. This method can be overridden if * something special registration procedure is required, like for using the * specific name for the registration or deligating the namin to MBean to register. * * @param pServer server an MBean should be registered * @param pMBean the MBean to register * @param pName an optional name under which the MBean should be registered. Can be null * @return the object name of the registered MBean * @throws MBeanRegistrationException when registration failed * @throws InstanceAlreadyExistsException when there is already MBean with this name * @throws NotCompliantMBeanException * @throws MalformedObjectNameException if the name is not valid */ public ObjectName registerMBeanAtServer(MBeanServer pServer, Object pMBean, String pName) throws MBeanRegistrationException, InstanceAlreadyExistsException, NotCompliantMBeanException, MalformedObjectNameException { if (pName != null) { ObjectName oName = new ObjectName(pName); return pServer.registerMBean(pMBean,oName).getObjectName(); } else { // Needs to implement MBeanRegistration interface return pServer.registerMBean(pMBean,null).getObjectName(); } } /** * Return this info as an JSONObject * * * * @param pServerManager servers, for which dynamic part might be queried * @return this object in JSON representation */ public JSONObject toJSONObject(MBeanServerExecutor pServerManager) { JSONObject ret = new JSONObject(); addNullSafe(ret, "vendor", vendor); addNullSafe(ret, "product", product); addNullSafe(ret, "version", version); Map<String,String> extra = getExtraInfo(pServerManager); if (extra != null) { JSONObject jsonExtra = new JSONObject(); for (Map.Entry<String,String> entry : extra.entrySet()) { jsonExtra.put(entry.getKey(),entry.getValue()); } ret.put("extraInfo", jsonExtra); } return ret; } private void addNullSafe(JSONObject pRet, String pKey, Object pValue) { if (pValue != null) { pRet.put(pKey,pValue); } } /** * Get the optional options used for detectors. This should be a JSON string specifying all options * for all detectors. Keys are the name of the detector's product, the values are JSON object containing * specific parameters for this agent. E.g. * * <pre> * { * "glassfish" : { "bootAmx": true } * } * </pre> * * * @param pConfig the agent configuration * @param pLogHandler a log handler for putting out error messages * @return the detector specific configuration */ protected JSONObject getDetectorOptions(Configuration pConfig, LogHandler pLogHandler) { String options = pConfig.get(ConfigKey.DETECTOR_OPTIONS); try { if (options != null) { JSONObject opts = (JSONObject) new JSONParser().parse(options); return (JSONObject) opts.get(getProduct()); } return null; } catch (ParseException e) { pLogHandler.error("Could not parse detector options '" + options + "' as JSON object: " + e,e); } return null; } }