Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* RHQ Management Platform
* Copyright (C) 2005-2009 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 as published by
* the Free Software Foundation version 2 of the License.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.rhq.augeas.node.AugeasNode;
import org.rhq.augeas.tree.AugeasTree;
import org.rhq.augeas.util.Glob;
import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
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.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
import org.rhq.plugins.apache.parser.ApacheDirective;
import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
import org.rhq.plugins.apache.parser.ApacheParser;
import org.rhq.plugins.apache.parser.ApacheParserImpl;
import org.rhq.plugins.apache.util.ApacheBinaryInfo;
import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
import org.rhq.plugins.platform.PlatformComponent;
import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
/**
* The discovery component for Apache 2.x servers.
*
* @author Ian Springer
* @author Lukas Krejci
*/
public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log = LogFactory.getLog(ApacheServerDiscoveryComponent.class);
public Set discoverResources(ResourceDiscoveryContext discoveryContext) throws Exception {
Set discoveredResources = new HashSet();
// Process any PC-discovered OS processes...
List processes = discoveryContext.getAutoDiscoveredProcesses();
for (ProcessScanResult process : processes) {
//String executablePath = process.getProcessInfo().getName();
String executableName = getExecutableName(process);
File executablePath = OsProcessUtility.getProcExe(process.getProcessInfo().getPid(), executableName);
if (executablePath == null) {
log.error("Executable path could not be determined for Apache [" + process.getProcessInfo() + "].");
continue;
}
if (!executablePath.isAbsolute()) {
log.error("Executable path (" + executablePath + ") is not absolute for Apache [" +
process.getProcessInfo() + "]." +
"Please restart Apache specifying an absolute path for the executable.");
continue;
}
log.debug("Apache executable path: " + executablePath);
ApacheBinaryInfo binaryInfo;
try {
binaryInfo = ApacheBinaryInfo.getInfo(executablePath.getPath(),
discoveryContext.getSystemInformation());
} catch (Exception e) {
log.error("'" + executablePath + "' is not a valid Apache executable (" + e + ").");
continue;
}
if (isSupportedVersion(binaryInfo.getVersion())) {
String serverRoot = getServerRoot(binaryInfo, process.getProcessInfo());
if (serverRoot == null) {
log.error("Unable to determine server root for Apache process: " + process.getProcessInfo());
continue;
}
File serverConfigFile = getServerConfigFile(binaryInfo, process.getProcessInfo(), serverRoot);
if (serverConfigFile == null) {
log.error("Unable to determine server config file for Apache process: " + process.getProcessInfo());
continue;
}
Configuration pluginConfig = discoveryContext.getDefaultPluginConfiguration();
PropertySimple executablePathProp = new PropertySimple(
ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH, executablePath);
pluginConfig.put(executablePathProp);
PropertySimple serverRootProp = new PropertySimple(
ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT, serverRoot);
pluginConfig.put(serverRootProp);
PropertySimple configFile = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF,
serverConfigFile);
pluginConfig.put(configFile);
PropertySimple inclusionGlobs = new PropertySimple(PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP, serverConfigFile);
pluginConfig.put(inclusionGlobs);
ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(),serverRoot);
String serverUrl = null;
String vhostsGlobInclude = null;
//now check if the httpd.conf doesn't redefine the ServerRoot
List serverRoots = serverConfig.search("/ServerRoot");
if (!serverRoots.isEmpty()) {
serverRoot = AugeasNodeValueUtil.unescape(serverRoots.get(0).getValuesAsString());
serverRootProp.setValue(serverRoot);
}
serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
vhostsGlobInclude = scanForGlobInclude(serverConfig);
if (serverUrl != null) {
Property urlProp = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, serverUrl);
pluginConfig.put(urlProp);
}
if (vhostsGlobInclude != null) {
pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, vhostsGlobInclude));
}else
{
if (serverConfigFile.exists())
pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, serverConfigFile.getParent()+File.separator+"*"));
}
discoveredResources.add(createResourceDetails(discoveryContext, pluginConfig, process.getProcessInfo(),
binaryInfo));
}
}
return discoveredResources;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
ResourceDiscoveryContext discoveryContext)
throws InvalidPluginConfigurationException {
validateServerRootAndServerConfigFile(pluginConfig);
String executablePath = pluginConfig
.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
String absoluteExecutablePath = ApacheServerComponent.resolvePathRelativeToServerRoot(pluginConfig,
executablePath).getPath();
ApacheBinaryInfo binaryInfo;
try {
binaryInfo = ApacheBinaryInfo.getInfo(absoluteExecutablePath, discoveryContext.getSystemInformation());
} catch (Exception e) {
throw new InvalidPluginConfigurationException("'" + absoluteExecutablePath
+ "' is not a valid Apache executable (" + e + "). Please make sure the '"
+ ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH
+ "' connection property is set correctly.");
}
if (!isSupportedVersion(binaryInfo.getVersion())) {
throw new InvalidPluginConfigurationException("Version of Apache executable ("
+ binaryInfo.getVersion() + ") is not a supported version; supported versions are 1.3.x and 2.x.");
}
ProcessInfo processInfo = null;
try {
DiscoveredResourceDetails resourceDetails = createResourceDetails(discoveryContext, pluginConfig,
processInfo, binaryInfo);
return resourceDetails;
}
catch (Exception e) {
throw new RuntimeException("Failed to create resource details during manual add.");
}
}
private boolean isSupportedVersion(String version) {
// TODO: Compare against a version range defined in the plugin descriptor.
return (version != null) && (version.startsWith("1.3") || version.startsWith("2."));
}
private DiscoveredResourceDetails createResourceDetails(ResourceDiscoveryContext discoveryContext,
Configuration pluginConfig, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
String httpdConf = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
String version = binaryInfo.getVersion();
String serverUrl = pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, null);
//use the server url if we could detect it, otherwise use something unique
String name;
if (serverUrl == null) {
name = httpdConf;
} else {
URI uri = new URI(serverUrl);
name = uri.getHost() + ":" + uri.getPort();
}
String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
.getStringValue();
String key = FileUtils.getCanonicalPath(serverRoot);
//BZ 612189 - reverting to the serverRoot as the resource key temporarily until we have the resource
//upgrade functionality ready (BZ 592038). Uncommenting the line below will make the resource key totally unique
//(see BZ 593270).
//key += "|" + httpdConf;
DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
log.debug("Apache Server resource details created: " + resourceDetails);
return resourceDetails;
}
/**
* Return the root URL as determined from the Httpd configuration loaded by Augeas.
* he URL's protocol is assumed to be "http" and its path is assumed to be "/".
*
* @return
*
* @throws Exception
*/
private static String getUrl(ApacheDirectiveTree serverConfig, String version) throws Exception {
Address addr = HttpdAddressUtility.get(version).getMainServerSampleAddress(serverConfig, null, 0);
return addr == null ? null : "http://" + addr.host + ":" + addr.port + "/";
}
@Nullable
private String getServerRoot(@NotNull ApacheBinaryInfo binaryInfo, @NotNull ProcessInfo processInfo) {
// First see if -d was specified on the httpd command line.
String[] cmdLine = processInfo.getCommandLine();
String root = getCommandLineOption(cmdLine, "-d");
// If not, extract the path from the httpd binary.
if (root == null) {
root = binaryInfo.getRoot();
}
if (root == null) {
// We have failed to determine the server root :(
return null;
}
// If the path is relative, convert it to an absolute path, resolving it relative to the cwd of the httpd process.
File rootFile = new File(root);
if (!rootFile.isAbsolute()) {
String currentWorkingDir;
try {
currentWorkingDir = processInfo.getCurrentWorkingDirectory();
} catch (Exception e) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
+ "], which is needed to determine the server root of the Apache instance.", e);
return null;
}
if (currentWorkingDir == null) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
+ "], which is needed to determine the server root of the Apache instance.");
return null;
} else {
rootFile = new File(currentWorkingDir, root);
root = rootFile.getPath();
}
}
// And finally canonicalize the path, but using our own getCanonicalPath() method, which preserves symlinks.
root = FileUtils.getCanonicalPath(root);
return root;
}
@Nullable
private File getServerConfigFile(ApacheBinaryInfo binaryInfo, ProcessInfo processInfo, String serverRoot) {
// First see if -f was specified on the httpd command line.
String[] cmdLine = processInfo.getCommandLine();
String serverConfigFile = getCommandLineOption(cmdLine, "-f");
// If not, extract the path from the httpd binary.
if (serverConfigFile == null) {
serverConfigFile = binaryInfo.getCtl();
}
if (serverConfigFile == null) {
// We have failed to determine the config file path :(
return null;
}
// If the path is relative, convert it to an absolute path, resolving it relative to the server root dir.
File file = new File(serverConfigFile);
if (!file.isAbsolute()) {
file = new File(serverRoot, serverConfigFile);
serverConfigFile = file.getPath();
}
// And finally canonicalize the path, but using our own getCanonicalPath() method, which preserves symlinks.
serverConfigFile = FileUtils.getCanonicalPath(serverConfigFile);
return new File(serverConfigFile);
}
private String getCommandLineOption(String[] cmdLine, String option) {
String root = null;
for (int i = 1; i < cmdLine.length; i++) {
String arg = cmdLine[i];
if (arg.startsWith(option)) {
root = arg.substring(2, arg.length());
if (root.length() == 0) {
root = cmdLine[i + 1];
}
break;
}
}
return root;
}
private static String getExecutableName(ProcessScanResult processScanResult) {
String query = processScanResult.getProcessScan().getQuery().toLowerCase();
String executableName;
if (query.contains("apache.exe")) {
executableName = "apache.exe";
} else if (query.contains("httpd.exe")) {
executableName = "httpd.exe";
} else if (query.contains("apache2")) {
executableName = "apache2";
} else if (query.contains("httpd")) {
executableName = "httpd";
} else {
executableName = null;
}
return executableName;
}
private static void validateServerRootAndServerConfigFile(Configuration pluginConfig) {
String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
File serverRootFile;
try {
serverRootFile = new File(serverRoot).getCanonicalFile(); // this will resolve symlinks
}
catch (IOException e) {
serverRootFile = null;
}
if (serverRootFile == null || !serverRootFile.isDirectory()) {
throw new InvalidPluginConfigurationException("'" + serverRoot
+ "' does not exist or is not a directory. Please make sure the '"
+ ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT + "' connection property is set correctly.");
}
String httpdConf = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
File httpdConfFile;
try {
httpdConfFile = new File(httpdConf).getCanonicalFile(); // this will resolve symlinks
}
catch (IOException e) {
httpdConfFile = null;
}
if (httpdConfFile == null || !httpdConfFile.isFile()) {
throw new InvalidPluginConfigurationException("'" + httpdConf
+ "' does not exist or is not a regular file. Please make sure the '"
+ ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF + "' connection property is set correctly.");
}
}
private static ApacheDirectiveTree loadParser(String path,String serverRoot) throws Exception{
ApacheDirectiveTree tree = new ApacheDirectiveTree();
ApacheParser parser = new ApacheParserImpl(tree,serverRoot);
ApacheConfigReader.buildTree(path, parser);
return tree;
}
public static String scanForGlobInclude(ApacheDirectiveTree tree) {
try {
List includes = tree.search("/Include");
for (ApacheDirective n : includes) {
String include = n.getValuesAsString();
if (Glob.isWildcard(include)) {
//we only take the '*.something' into account here
//so that we have a useful mask to base the file names on.
//the only special glob character allowed is *.
for(char specialChar : GlobFilter.WILDCARD_CHARS) {
if (specialChar == '*') {
if (include.indexOf(specialChar) != include.lastIndexOf(specialChar)) {
//more than 1 star... that's too much
break;
}
//we found what we're looking for...
return include;
}
if (include.indexOf(specialChar) >= 0) {
break;
}
}
}
}
} catch (Exception e) {
log.debug("Failed to detect glob includes in httpd.conf.", e);
}
return null;
}
}