/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.rhq.plugins.mobicents.tools;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarFile;
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.pluginapi.inventory.DiscoveredResourceDetails;
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.system.ProcessInfo;
import org.rhq.core.system.SystemInfo;
/**
* Discovers Mobicents Sip Balancer
*
* @author jean.deruelle@gmail.com
*/
public class MobicentsSipBalancerDiscoveryComponent implements ResourceDiscoveryComponent {
private final Log log = LogFactory.getLog(MobicentsSipBalancerDiscoveryComponent.class);
public static final String HOST_PROP = "host";
public static final String EXTERNAL_PORT_PROP = "externalPort";
public static final String INTERNAL_PORT_PROP = "internalPort";
public static final String RMI_REGISTRY_PORT_PROP = "rmiRegistryPort";
public static final String JMX_HTML_ADAPTER_PORT_PROP = "jmxHtmlAdapterPort";
public static final String BALANCER_EXECUTABLE_JAR_FILE_PATH = "balancerJarPath";
public static final String BALANCER_EXECUTABLE_JAR_FILE = "balancerJar";
public static final String MOBICENTS_BALANCER_CONFIG_ARG = "-mobicents-balancer-config=";
/**
* Formal name used to identify the Mobicents Sip Balancer.
*/
private static final String PRODUCT_NAME = "Mobicents Sip Load Balancer";
/**
* Formal description of the Mobicents Sip Balancer product passed into discovered resources.
*/
private static final String PRODUCT_DESCRIPTION = "Mobicents Sip Load Balancer";
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
log.debug("Discovering Mobicents Sip Load Balancers ...");
Set<DiscoveredResourceDetails> resources = new HashSet<DiscoveredResourceDetails>();
// For each Mobicents Sip Load Balancer process found in the context, process and create a resource details instance
List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
log.debug("Discovered Mobicents Sip Load Balancer process: " + autoDiscoveryResult);
try {
DiscoveredResourceDetails resource = parseMobicentsSipBalancerProcess(context, autoDiscoveryResult);
log.debug("Mobicents Sip Load Balancer resource: " + resource);
if (resource != null) {
resources.add(resource);
}
} catch (Exception e) {
log.error("Error creating discovered resource for process: " + autoDiscoveryResult, e);
}
}
return resources;
}
/**
* Processes a process that has been detected to be a Mobicents Sip Balancer. The result will be a JON resource ready to be
* returned as part of the discovery report.
*
* @param context discovery context making this call
* @param autoDiscoveryResult process scan being parsed for a Mobicents Sip Balancer resource
*
* @return resource object describing the Mobicents Sip Balancer running in the specified process
*/
private DiscoveredResourceDetails parseMobicentsSipBalancerProcess(
ResourceDiscoveryContext context,
ProcessScanResult autoDiscoveryResult) {
// Pull out data from the discovery call
ProcessInfo processInfo = autoDiscoveryResult.getProcessInfo();
SystemInfo systemInfo = context.getSystemInformation();
String[] commandLine = processInfo.getCommandLine();
String installationPath =
determineMobicentsSipBalancerConfigPath(processInfo);
log.debug("Installation path for the newly found mobicents sip balancer process is " + installationPath);
Properties config = parseMobicentsSipBalancerConfig(commandLine, installationPath);
// Create pieces necessary for the resource creation
String resourceVersion = determineVersion(commandLine, installationPath);
log.debug("Version for the newly found mobicents sip balancer process is " + resourceVersion);
String hostname = systemInfo.getHostname();
String resourceName = ((hostname == null) ? "" : (hostname + " ")) + PRODUCT_NAME + " " + resourceVersion + "(" + config.getProperty(HOST_PROP) + ")";
String resourceKey = installationPath;
Configuration pluginConfiguration = populatePluginConfiguration(config, processInfo);
DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), resourceKey,
resourceName, resourceVersion, PRODUCT_DESCRIPTION, pluginConfiguration, processInfo);
return resource;
}
private String determineMobicentsSipBalancerConfigPath(
ProcessInfo processInfo) {
String installationPath = processInfo.getCurrentWorkingDirectory();
log.debug("Process Info Working Directory" + installationPath);
// String argMainJar = findMainJarArgument(processInfo.getCommandLine());
// log.debug("Argument Main Balancer Jar" + argMainJar);
//
// if(argMainJar != null) {
// int indexOfLastSeparator = argMainJar.lastIndexOf(File.separatorChar);
// if(indexOfLastSeparator != -1) {
// installationPath = argMainJar.substring(0, indexOfLastSeparator);
// }
// }
return installationPath;
}
private String determineVersion(String[] commandLine, String installationPath) {
String version = "1.0";
String argMainJar = findMainJarArgument(commandLine);
if(argMainJar != null) {
try {
JarFile mainJar = new JarFile(installationPath + File.separatorChar + argMainJar);
version = mainJar.getManifest().getMainAttributes().getValue("Implementation-Version");
} catch (IOException e) {
log.error("An unexpected exception occured while trying to open the following jar file " + installationPath + File.separatorChar + argMainJar, e);
}
}
return version;
}
/**
* @param commandLine
* @return
*/
private String findMainJarArgument(String[] commandLine) {
String argMainJar = null;
int i = 0;
while(i < commandLine.length) {
if(commandLine[i].indexOf(".jar") != -1) {
argMainJar = commandLine[i];
}
i++;
}
return argMainJar;
}
private Properties parseMobicentsSipBalancerConfig(
String[] commandLine, String installationPath) {
String configurationFileLocation = null;
int i = 0;
while(i < commandLine.length) {
if(commandLine[i].indexOf(MOBICENTS_BALANCER_CONFIG_ARG) != -1) {
configurationFileLocation = commandLine[i].substring(MOBICENTS_BALANCER_CONFIG_ARG.length());
}
i++;
}
if(!configurationFileLocation.startsWith("file://")) {
configurationFileLocation = installationPath + File.separatorChar + configurationFileLocation;
}
File file = new File(configurationFileLocation);
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
throw new IllegalArgumentException("the configuration file location " + configurationFileLocation + " does not exists !");
}
Properties properties = new Properties(System.getProperties());
try {
properties.load(fileInputStream);
} catch (IOException e) {
throw new IllegalArgumentException("Unable to load the properties configuration file located at " + configurationFileLocation);
}
return properties;
}
/**
* Populates the plugin configuration for the Mobicents Sip Load Balancer instance being discovered.
*
* @param installationPath identifies the Mobicents Sip Load Balancer being discovered
*
* @return populated plugin configuration instance
*/
private Configuration populatePluginConfiguration(Properties properties, ProcessInfo processInfo) {
Configuration configuration = new Configuration();
configuration.put(new PropertySimple(HOST_PROP, properties.getProperty(HOST_PROP)));
configuration.put(new PropertySimple(INTERNAL_PORT_PROP, properties.getProperty(INTERNAL_PORT_PROP)));
configuration.put(new PropertySimple(EXTERNAL_PORT_PROP, properties.getProperty(EXTERNAL_PORT_PROP)));
configuration.put(new PropertySimple(RMI_REGISTRY_PORT_PROP, properties.getProperty(RMI_REGISTRY_PORT_PROP)));
configuration.put(new PropertySimple(JMX_HTML_ADAPTER_PORT_PROP, properties.getProperty(JMX_HTML_ADAPTER_PORT_PROP)));
String balancerJar = findMainJarArgument(processInfo.getCommandLine());
log.debug("balancerJar = " + balancerJar);
// String balancerJarPath = balancerJar.substring(0, balancerJar.lastIndexOf(File.separatorChar));
String balancerJarPath = determineMobicentsSipBalancerConfigPath(processInfo);
log.debug("balancerJarPath = " + balancerJarPath);
configuration.put(new PropertySimple(BALANCER_EXECUTABLE_JAR_FILE_PATH, balancerJarPath));
configuration.put(new PropertySimple(BALANCER_EXECUTABLE_JAR_FILE, balancerJar));
//allow JMX to unmarshall SIPNode class in LoadBalancerComponent
// configuration.put(new PropertySimple("additionalClassPathEntries", balancerJar));
return configuration;
}
}