blob: c799f8ee486575fbcd4f1a0406e7372dba2ddc30 [file] [log] [blame]
/*
* 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.MBeanServer;
import javax.management.ObjectName;
import org.apache.logging.log4j.Logger;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.execute.InternalFunction;
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 implements InternalFunction {
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
*
*/
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
*/
@Override
public void execute(FunctionContext fc) {
boolean executedSuccessfully = false;
InternalCache cache = ((InternalCache) fc.getCache()).getCacheForProcessingClientRequests();
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 (Exception e) {
sendException(e, fc);
} finally {
if (!executedSuccessfully) {
if (cache == null || cache.isClosed()) {
Exception e =
new Exception("Member Is Shutting down");
sendException(e, fc);
return; // member is closing or invalid member
}
}
}
}
@Override
public String getId() {
return ManagementConstants.MGMT_FUNCTION_ID;
}
private void sendException(Exception e, FunctionContext fc) {
if (logger.isDebugEnabled()) {
logger.debug("Management Function Could Not Be Executed", e);
}
fc.getResultSender().sendException(e);
}
}