/*
* NOTE: This copyright does *not* cover user programs that use HQ
* program services by normal system calls through the application
* program interfaces provided as part of the Hyperic Plug-in Development
* Kit or the Hyperic Client Development Kit - this is merely considered
* normal use of the program, and does *not* fall under the heading of
* "derived work".
*
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
* This file is part of HQ.
*
* HQ is free software; you can redistribute it and/or modify
* it under the terms version 2 of the GNU General Public License as
* published by the Free Software Foundation. This program is distributed
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
package org.hyperic.hq.plugin.weblogic;
import java.io.File;
import java.util.List;
import java.util.Arrays;
import org.hyperic.hq.bizapp.shared.lather.ControlSendCommandResult_args;
import org.hyperic.hq.product.Metric;
import org.hyperic.hq.product.MetricNotFoundException;
import org.hyperic.hq.product.MetricUnreachableException;
import org.hyperic.hq.product.ServerControlPlugin;
import org.hyperic.hq.product.PluginException;
import org.hyperic.hq.product.ProductPluginManager;
import org.hyperic.hq.product.TypeInfo;
import org.hyperic.util.config.ConfigOption;
import org.hyperic.util.config.ConfigResponse;
import org.hyperic.util.config.ConfigSchema;
import org.hyperic.hq.product.PluginException;
public class WeblogicControlPlugin
extends ServerControlPlugin
implements WeblogicAction {
//10 minutes ought to be plenty
public static final int DEFAULT_TIMEOUT = 60 * 10;
private static final String[] actions = {
"start", "stop", "runGarbageCollector"
};
private static final List commands = Arrays.asList(actions);
protected static final String DEFAULT_SCRIPT = "startWebLogic.sh";
static final String SERVER_METRIC =
WeblogicMetric.template(WeblogicMetric.SERVER_RUNTIME,
WeblogicMetric.SERVER_RUNTIME_STATE);
//the Server "configuration" MBean use for start via node manager
static final String ADMIN_METRIC =
WeblogicMetric.template("%domain%:Name=%server%,Type=Server",
WeblogicMetric.SERVER_RUNTIME_STATE);
private WeblogicAuthControl authControl;
private Metric lifecycleMetric = null;
private Metric adminMetric = null;
private Metric jvmMetric = null;
public WeblogicControlPlugin() {
super();
//give waitForState enough time
setTimeout(DEFAULT_TIMEOUT);
setControlProgram(DEFAULT_SCRIPT);
}
public void configure(ConfigResponse config)
throws PluginException
{
super.configure(config);
/*
XXX: enable again
File script = new File(getControlProgram());
if (!script.exists()) {
throw new PluginException("Weblogic startup script " +
"not found");
}
*/
this.authControl = new WeblogicAuthControl(this,
getLifecycleMetric());
}
public ConfigSchema getConfigSchema(TypeInfo info,
ConfigResponse config) {
ConfigSchema schema = super.getConfigSchema(info, config);
//control program is optional for Node servers
//when empty the NodeManager is used to start them.
if (info.isServer(WeblogicProductPlugin.SERVER_NAME)) {
ConfigOption option =
schema.getOption(WeblogicControlPlugin.PROP_PROGRAM);
if (option != null) {
option.setOptional(true);
}
}
return schema;
}
public List getActions() {
return commands;
}
private Metric configureMetric(String template) {
template = WeblogicMetric.translateNode(template, getConfig());
String metric = Metric.translate(template, getConfig());
getLog().debug("configureMetric=" + metric);
try {
return Metric.parse(metric); //parsing will be cached
} catch (Exception e) {
e.printStackTrace(); //XXX; but aint gonna happen
return null;
}
}
protected Metric getLifecycleMetric() {
if (this.lifecycleMetric == null) {
this.lifecycleMetric = configureMetric(SERVER_METRIC);
}
return this.lifecycleMetric;
}
private Metric getJVMMetric() {
if (this.jvmMetric == null) {
String jvmObjectName =
WeblogicMetric.getObjectTemplate(this, "JVMRuntime");
String jvmMetric =
WeblogicMetric.template(jvmObjectName, "Name");
this.jvmMetric = configureMetric(jvmMetric);
}
return this.jvmMetric;
}
protected Metric getAdminMetric() {
if (this.adminMetric == null) {
String metric =
Metric.translate(ADMIN_METRIC, getConfig());
getLog().debug("adminMetric=" + metric);
try {
return Metric.parse(metric); //parsing will be cached
} catch (Exception e) {
e.printStackTrace(); //XXX; but aint gonna happen
return null;
}
}
return this.adminMetric;
}
protected boolean isRunning() {
return this.authControl.isRunning();
}
public boolean isWeblogicRunning() {
boolean res = false;
Metric metric = getLifecycleMetric();
try {
Integer state = (Integer) WeblogicUtil.getRemoteMBeanValue(metric);
double val = WeblogicUtil.convertStateVal(state);
res = (val == Metric.AVAIL_UP);
} catch (Exception e) {
if (getLog().isDebugEnabled()) {
getLog().error(e);
}
}
getLog().error("[isWeblogicRunning] "+res);
return res;
}
protected boolean isBackgroundCommand() {
return true;
}
protected void start() {
File script = new File(getControlProgram());
if (!script.exists()) {
setResult(RESULT_FAILURE);
setMessage("Control program does not exist: " +
getControlProgram());
return;
}
if (isWeblogicRunning()) {
setResult(RESULT_FAILURE);
setMessage("Server already running");
return;
}
super.start(null); //requires a script
if (isWeblogicRunning()) {
setResult(RESULT_SUCCESS);
setMessage("Server started");
return;
}
setResult(RESULT_FAILURE);
if (getMessage() == null) {
setMessage("Server did not start");
}
}
protected Object invokeAction(Metric metric, String action) {
try {
Object obj = WeblogicUtil.invoke(metric, action);
setResult(RESULT_SUCCESS);
if (obj != null) {
setMessage(obj.toString());
}
return obj;
} catch (MetricNotFoundException e) {
setMessage(e.getMessage());
setResult(RESULT_FAILURE);
} catch (MetricUnreachableException e) {
setMessage(e.getMessage());
setResult(RESULT_FAILURE);
} catch (PluginException e) {
if (action.equals("shutdown") &&
!isRunning())
{
//might get nested java.net.SocketException: Connection reset
//which is ok/expected-ish if we are stopping the server
setResult(RESULT_SUCCESS);
}
else {
setMessage(e.getMessage());
setResult(-2);
}
}
return null;
}
public void doAction(String action) throws PluginException{
this.authControl.doAction(action);
}
public void doWeblogicAction(String action) {
if (action.equals("start")) {
start();
return;
}
Metric metric;
String method;
if (action.equals("stop")) {
metric = getLifecycleMetric();
method = "shutdown";
}
else if (action.equals("runGarbageCollector")) {
metric = getJVMMetric();
method = "runGC";
}
else {
return; //ControlPluginManager checks for valid actions
}
invokeAction(metric, method);
}
}