/*
* Jopr Management Platform
* Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also 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 and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.plugins.jbossas5.script;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.jbossas5.ApplicationServerComponent;
/**
* A discovery component for Script services.
*
* @author Ian Springer
*/
public class ScriptDiscoveryComponent implements ResourceDiscoveryComponent<ApplicationServerComponent<?>>,
ManualAddFacet<ApplicationServerComponent<?>>, ResourceUpgradeFacet<ApplicationServerComponent<?>> {
private final Log log = LogFactory.getLog(this.getClass());
static final String SERVER_HOME_DIR = "homeDir";
public Set<DiscoveredResourceDetails> discoverResources(
ResourceDiscoveryContext<ApplicationServerComponent<?>> discoveryContext)
throws InvalidPluginConfigurationException {
Set<DiscoveredResourceDetails> resources = new HashSet<DiscoveredResourceDetails>();
ResourceContext<?> parentResourceContext = discoveryContext.getParentResourceContext();
File binDir = getServerBinDirectory(parentResourceContext);
log.debug("Searching for scripts beneath JBossAS server bin directory (" + binDir + ")...");
ScriptFileFinder scriptFileFinder = new ScriptFileFinder(discoveryContext.getSystemInformation(), binDir);
List<File> scriptFiles = scriptFileFinder.findScriptFiles();
for (File scriptFile : scriptFiles) {
Configuration pluginConfig = new Configuration();
pluginConfig.put(new PropertySimple(ScriptComponent.PATH_CONFIG_PROP, scriptFile.getPath()));
Map<String, String> defaultScriptEnvironment = getDefaultScriptEnvironment();
pluginConfig.put(new PropertySimple(ScriptComponent.ENVIRONMENT_VARIABLES_CONFIG_PROP,
toString(defaultScriptEnvironment)));
DiscoveredResourceDetails resource = createResourceDetails(discoveryContext, pluginConfig, binDir);
log.debug("Auto-discovered script service: " + resource);
resources.add(resource);
}
return resources;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
ResourceDiscoveryContext<ApplicationServerComponent<?>> discoveryContext)
throws InvalidPluginConfigurationException {
File path = new File(pluginConfig.getSimple(ScriptComponent.PATH_CONFIG_PROP).getStringValue());
validatePath(path);
ResourceContext parentResourceContext = discoveryContext.getParentResourceContext();
File binDir = getServerBinDirectory(parentResourceContext);
DiscoveredResourceDetails resource = createResourceDetails(discoveryContext, pluginConfig, binDir);
log.debug("Manually added script service: " + resource);
return resource;
}
@Override
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ApplicationServerComponent<?>> upgradeContext) {
String inventoriedResourceKey = upgradeContext.getResourceKey();
ResourceContext<?> parentResourceContext = upgradeContext.getParentResourceContext();
File binDir = getServerBinDirectory(parentResourceContext);
// The new format is to use paths relative to the server bin dir for scripts in that dir and to otherwise
// use absolute paths, so we only need to upgrade existing keys that start with the bin dir path.
if (!inventoriedResourceKey.startsWith(binDir.getPath())) {
// key is already in the new format
return null;
}
// key is in the old format - build a key in the new format
String resourceKey = buildResourceKey(inventoriedResourceKey, binDir);
ResourceUpgradeReport upgradeReport = new ResourceUpgradeReport();
upgradeReport.setNewResourceKey(resourceKey);
return upgradeReport;
}
private File getServerBinDirectory(ResourceContext parentResourceContext) {
Configuration parentPluginConfig = parentResourceContext.getPluginConfiguration();
String homeDir = parentPluginConfig.getSimple(SERVER_HOME_DIR).getStringValue();
return new File(homeDir, "bin");
}
private static String buildResourceKey(String scriptPath, File binDir) {
return (scriptPath.startsWith(binDir.getPath())) ? scriptPath.substring(binDir.getPath().length() + 1)
: scriptPath;
}
private void validatePath(File path) {
if (!path.isAbsolute()) {
throw new InvalidPluginConfigurationException("Path '" + path + "' is not absolute.");
}
if (!path.exists()) {
throw new InvalidPluginConfigurationException("Path '" + path + "' does not exist.");
}
if (path.isDirectory()) {
throw new InvalidPluginConfigurationException("Path '" + path + "' is a directory, not a file.");
}
}
private Map<String, String> getDefaultScriptEnvironment() {
Map<String, String> defaultScriptEnvironment = new HashMap<String, String>();
// Name the environment variables after the standard JBossAS properties
// to make things more intuitive for users.
// Don't use any "."'s in the environment variable names, as they
// confuse UNIX shells (see JBNADM-2762).
defaultScriptEnvironment.put("JBOSS_SERVER_NAME", "%serverName%");
defaultScriptEnvironment.put("JBOSS_SERVER_HOME_DIR", "%serverHomeDir%");
return defaultScriptEnvironment;
}
private String toString(Map<String, String> defaultScriptEnvironment) {
StringBuilder environmentVariables = new StringBuilder();
if (defaultScriptEnvironment != null) {
for (String varName : defaultScriptEnvironment.keySet()) {
String varValue = defaultScriptEnvironment.get(varName);
environmentVariables.append(varName).append("=").append(varValue).append("\n");
}
}
return environmentVariables.toString();
}
private DiscoveredResourceDetails createResourceDetails(
ResourceDiscoveryContext<ApplicationServerComponent<?>> discoveryContext, Configuration pluginConfig,
File binDir) {
String path = pluginConfig.getSimple(ScriptComponent.PATH_CONFIG_PROP).getStringValue();
String key = buildResourceKey(path, binDir);
String name = new File(path).getName();
String version = null;
String description = null;
ProcessInfo processInfo = null;
// noinspection ConstantConditions
return new DiscoveredResourceDetails(discoveryContext.getResourceType(), key, name, version, description,
pluginConfig, processInfo);
}
}