/* * 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.management.internal; import java.io.Serializable; import javax.management.Attribute; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.ReflectionException; import org.apache.logging.log4j.Logger; import org.apache.geode.cache.execute.FunctionAdapter; import org.apache.geode.cache.execute.FunctionContext; import org.apache.geode.internal.InternalEntity; import org.apache.geode.internal.cache.GemFireCacheImpl; import org.apache.geode.internal.logging.LogService; /** * A generic function to act as a conduit between Managing Node and Managed nodes. * * The direction of request flow is from Managing Node to Managing Node. * * The following methods are executed at Managed node on behalf of the proxy. * * 1) All setter methods 2) All operations 3) addNotificationListener 4) removeNotificationListener * 5) getNotificationInfo * * */ public class ManagementFunction extends FunctionAdapter implements InternalEntity { private static final Logger logger = LogService.getLogger(); /** * */ private static final long serialVersionUID = 1L; /** * Platform MBean server. */ private MBeanServer mbeanServer = MBeanJMXAdapter.mbeanServer; /** * Notification hub instance */ private NotificationHub notificationHub; /** * Public constructor * * @param notifHub */ public ManagementFunction(NotificationHub notifHub) { this.notificationHub = notifHub; } /** * Actual function execution. It delegates task at managed node according to the request received. * * If any exception is encountered it will set the result to UNDEFINED */ public void execute(FunctionContext fc) { boolean executedSuccessfully = false; GemFireCacheImpl cache = GemFireCacheImpl.getInstance(); Object[] functionArguments = (Object[]) fc.getArguments(); ObjectName objectName = (ObjectName) functionArguments[0]; String methodName = (String) functionArguments[1]; String[] signature = (String[]) functionArguments[2]; Object[] args = (Object[]) functionArguments[3]; String memberName = (String) functionArguments[4]; Object returnObj = null; try { final int nargs = (args == null) ? 0 : args.length; if (methodName.startsWith("set") && methodName.length() > 3 && nargs == 1) { Attribute attr = new Attribute(methodName.substring(3), args[0]); mbeanServer.setAttribute(objectName, attr); fc.getResultSender().lastResult((Serializable) null); } else if (methodName.equals("addNotificationListener")) { notificationHub.addHubNotificationListener(memberName, objectName); fc.getResultSender().lastResult((Serializable) ManagementConstants.UNDEFINED); } else if (methodName.equals("removeNotificationListener")) { notificationHub.removeHubNotificationListener(memberName, objectName); fc.getResultSender().lastResult((Serializable) ManagementConstants.UNDEFINED); } else if (methodName.equals("getNotificationInfo")) { fc.getResultSender().lastResult(mbeanServer.getMBeanInfo(objectName)); } else { returnObj = mbeanServer.invoke(objectName, methodName, args, signature); fc.getResultSender().lastResult((Serializable) returnObj); } executedSuccessfully = true; } catch (InstanceNotFoundException e) { if (cache != null && !cache.isClosed()) { sendException(e, fc); } } catch (ReflectionException e) { sendException(e, fc); } catch (MBeanException e) { sendException(e, fc); } catch (NullPointerException e) { sendException(e, fc); } catch (Exception e) { sendException(e, fc); } finally { if (!executedSuccessfully) { if (cache == null || (cache != null && cache.isClosed())) { Exception e = new Exception(ManagementStrings.MEMBER_IS_SHUTTING_DOWN.toLocalizedString()); sendException(e, fc); return; // member is closing or invalid member } } } } public String getId() { return ManagementConstants.MGMT_FUNCTION_ID; } private void sendException(Exception e, FunctionContext fc) { if (logger.isDebugEnabled()) { logger.debug(ManagementStrings.MANAGEMENT_FUNCTION_COULD_NOT_EXECUTE.toLocalizedString()); logger.debug(e.getMessage(), e); } fc.getResultSender().sendException(e); } }