PageRenderTime 25ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/diameter/tools/jopr-plugin/src/main/java/org/rhq/plugins/diameter/DiameterServerDiscoveryComponent.java

http://mobicents.googlecode.com/
Java | 409 lines | 305 code | 64 blank | 40 comment | 61 complexity | b34f25468e1e54ece42ae30e1e33ab83 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, CC0-1.0, Apache-2.0, BSD-3-Clause
  1. package org.rhq.plugins.diameter;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileReader;
  6. import java.io.IOException;
  7. import java.net.URL;
  8. import java.util.ArrayList;
  9. import java.util.Arrays;
  10. import java.util.HashSet;
  11. import java.util.List;
  12. import java.util.Properties;
  13. import java.util.Set;
  14. import org.apache.commons.logging.Log;
  15. import org.apache.commons.logging.LogFactory;
  16. import org.jboss.util.file.FilenamePrefixFilter;
  17. import org.rhq.core.domain.configuration.Configuration;
  18. import org.rhq.core.domain.configuration.PropertyList;
  19. import org.rhq.core.domain.configuration.PropertyMap;
  20. import org.rhq.core.domain.configuration.PropertySimple;
  21. import org.rhq.core.pluginapi.event.log.LogFileEventResourceComponentHelper;
  22. import org.rhq.core.pluginapi.inventory.ClassLoaderFacet;
  23. import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
  24. import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
  25. import org.rhq.core.pluginapi.inventory.ManualAddFacet;
  26. import org.rhq.core.pluginapi.inventory.ProcessScanResult;
  27. import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
  28. import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
  29. import org.rhq.core.pluginapi.util.FileUtils;
  30. import org.rhq.core.system.ProcessInfo;
  31. import org.rhq.plugins.diameter.jbossas5.ApplicationServerPluginConfigurationProperties;
  32. import org.rhq.plugins.diameter.jbossas5.helper.JBossInstallationInfo;
  33. import org.rhq.plugins.diameter.jbossas5.helper.JBossInstanceInfo;
  34. import org.rhq.plugins.diameter.jbossas5.helper.JBossProperties;
  35. import org.rhq.plugins.diameter.jbossas5.helper.MobicentsDiameterProperties;
  36. import org.rhq.plugins.diameter.jbossas5.util.JBossASDiscoveryUtils;
  37. import org.rhq.plugins.diameter.jbossas5.util.JnpConfig;
  38. public class DiameterServerDiscoveryComponent implements ResourceDiscoveryComponent<DiameterServerComponent>, ManualAddFacet<DiameterServerComponent>, ClassLoaderFacet<DiameterServerComponent> {
  39. private final Log logger = LogFactory.getLog(DiameterServerDiscoveryComponent.class);
  40. private static final String CHANGE_ME = "***CHANGE_ME***";
  41. private static final String ANY_ADDRESS = "0.0.0.0";
  42. private static final String LOCALHOST = "127.0.0.1";
  43. private static final String JBOSS_SERVICE_XML = "conf" + File.separator + "jboss-service.xml";
  44. private static final String JBOSS_NAMING_SERVICE_XML = "deploy" + File.separator + "naming-service.xml";
  45. private static final String JAVA_HOME_ENV_VAR = "JAVA_HOME";
  46. private static final String[] CLIENT_JARS = new String[] { "client/jbossall-client.jar",
  47. /*"common/lib/jboss-security-aspects.jar", "lib/jboss-managed.jar", "lib/jboss-metatype.jar",
  48. "lib/jboss-dependency.jar"*/ };
  49. @Override
  50. public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<DiameterServerComponent> discoveryContext) throws InvalidPluginConfigurationException, Exception {
  51. if(logger.isInfoEnabled()) {
  52. logger.info("Discovering Mobicents Diameter Resources...");
  53. }
  54. Set<DiscoveredResourceDetails> resources = new HashSet<DiscoveredResourceDetails>();
  55. DiscoveredResourceDetails inProcessJBossAS = discoverInProcessJBossAS(discoveryContext);
  56. if (inProcessJBossAS != null) {
  57. // If we're running inside a JBoss AS JVM, that's the only AS instance we want to discover.
  58. resources.add(inProcessJBossAS);
  59. }
  60. else {
  61. // Otherwise, scan the process table for external AS instances.
  62. resources.addAll(discoverExternalJBossAsProcesses(discoveryContext));
  63. }
  64. if(logger.isInfoEnabled()) {
  65. logger.info("Discovered " + resources.size() + " Mobicents Diameter Resources.");
  66. }
  67. return resources;
  68. }
  69. @Override
  70. public DiscoveredResourceDetails discoverResource(Configuration pluginConfig, ResourceDiscoveryContext<DiameterServerComponent> context) throws InvalidPluginConfigurationException {
  71. ProcessInfo processInfo = null;
  72. String jbossHomeDir = pluginConfig.getSimple(ApplicationServerPluginConfigurationProperties.SERVER_HOME_DIR).getStringValue();
  73. String jbossDeploy = jbossHomeDir + File.separator + "deploy" + File.separator;
  74. File f = new File(jbossDeploy);
  75. String[] diameterList = f.list(new FilenamePrefixFilter("mobicents-diameter-mux"));
  76. if(diameterList.length > 1) {
  77. logger.warn("More than one Mobicents Diameter MUX were found.");
  78. }
  79. else if(diameterList.length < 1) {
  80. logger.error("Skipping discovery for Mobicents Diameter " + jbossDeploy + ", because Mobicents Diameter dir could not be found.");
  81. throw new InvalidPluginConfigurationException("");
  82. }
  83. String mobicentsDiameterHome = jbossDeploy + diameterList[0];
  84. String diameterVersion = diameterList[0].replaceFirst("mobicents-diameter-mux-", "").replaceAll(".sar", "");
  85. pluginConfig.setNotes(diameterVersion);
  86. File mobicentsDiameter = new File(mobicentsDiameterHome);
  87. try {
  88. if (!mobicentsDiameter.getCanonicalFile().isDirectory()) {
  89. logger.warn("Skipping manual add for Mobicents Diameter " + mobicentsDiameterHome + ", because Mobicents Diameter dir 'mobicents-diameter.sar' does not exist or is not a directory.");
  90. }
  91. }
  92. catch (IOException e) {
  93. logger.error("Skipping discovery for Mobicents Diameter " + mobicentsDiameterHome + ", because Mobicents Diameter dir could not be canonicalized.", e);
  94. throw new InvalidPluginConfigurationException(e);
  95. }
  96. pluginConfig.put(new PropertySimple(MobicentsDiameterProperties.DIAMETER_HOME_DIR, mobicentsDiameterHome));
  97. JBossInstallationInfo installInfo;
  98. try {
  99. installInfo = new JBossInstallationInfo(new File(jbossHomeDir));
  100. }
  101. catch (IOException e) {
  102. throw new InvalidPluginConfigurationException(e);
  103. }
  104. DiscoveredResourceDetails resourceDetails;
  105. try {
  106. resourceDetails = createResourceDetails(context, pluginConfig, processInfo, installInfo);
  107. }
  108. catch (Exception e) {
  109. throw new InvalidPluginConfigurationException(e);
  110. }
  111. return resourceDetails;
  112. }
  113. @Override
  114. public List<URL> getAdditionalClasspathUrls(ResourceDiscoveryContext<DiameterServerComponent> context, DiscoveredResourceDetails details) throws Exception {
  115. if(logger.isInfoEnabled()) {
  116. logger.info("Diameter Server Discovery Component > getAdditionalClasspathUrls called.");
  117. }
  118. Configuration pluginConfig = details.getPluginConfiguration();
  119. String homeDir = pluginConfig.getSimple(ApplicationServerPluginConfigurationProperties.HOME_DIR).getStringValue();
  120. List<URL> clientJars = new ArrayList<URL>();
  121. for (String jarFileName : CLIENT_JARS) {
  122. File clientJar = new File(homeDir, jarFileName);
  123. if (!clientJar.exists()) {
  124. throw new FileNotFoundException("Cannot find [" + clientJar + "] - unable to manage server.");
  125. }
  126. if (!clientJar.canRead()) {
  127. throw new IOException("Cannot read [" + clientJar + "] - unable to manage server.");
  128. }
  129. clientJars.add(clientJar.toURI().toURL());
  130. }
  131. return clientJars;
  132. }
  133. // Private Methods -----------------------------------------------------
  134. private DiscoveredResourceDetails discoverInProcessJBossAS(ResourceDiscoveryContext discoveryContext) {
  135. try {
  136. return null;// new InProcessJBossASDiscovery().discoverInProcessJBossAS(discoveryContext);
  137. }
  138. catch (Throwable t) {
  139. if(logger.isDebugEnabled()) {
  140. logger.debug("In-process JBoss AS discovery failed - we are probably not running embedded within JBoss AS.", t);
  141. }
  142. return null;
  143. }
  144. }
  145. private Set<DiscoveredResourceDetails> discoverExternalJBossAsProcesses(ResourceDiscoveryContext discoveryContext) throws Exception {
  146. Set<DiscoveredResourceDetails> resources = new HashSet<DiscoveredResourceDetails>();
  147. List<ProcessScanResult> autoDiscoveryResults = discoveryContext.getAutoDiscoveredProcesses();
  148. for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
  149. ProcessInfo processInfo = autoDiscoveryResult.getProcessInfo();
  150. if (logger.isDebugEnabled()) {
  151. logger.debug("Discovered JBoss AS process: " + processInfo);
  152. }
  153. JBossInstanceInfo cmdLine;
  154. try {
  155. cmdLine = new JBossInstanceInfo(processInfo);
  156. }
  157. catch (Exception e) {
  158. logger.error("Failed to process JBoss AS command line: " + Arrays.asList(processInfo.getCommandLine()), e);
  159. continue;
  160. }
  161. // Skip it if it's an AS/EAP/SOA-P version we don't support.
  162. JBossInstallationInfo installInfo = cmdLine.getInstallInfo();
  163. // if (!isSupportedProduct(installInfo)) {
  164. // // continue;
  165. // }
  166. File installHome = new File(cmdLine.getSystemProperties().getProperty(JBossProperties.HOME_DIR));
  167. File configDir = new File(cmdLine.getSystemProperties().getProperty(JBossProperties.SERVER_HOME_DIR));
  168. // The config dir might be a symlink - call getCanonicalFile() to resolve it if so, before calling
  169. // isDirectory() (isDirectory() returns false for a symlink, even if it points at a directory).
  170. try {
  171. if (!configDir.getCanonicalFile().isDirectory()) {
  172. logger.warn("Skipping discovery for JBoss AS process " + processInfo + ", because configuration dir '" + configDir + "' does not exist or is not a directory.");
  173. continue;
  174. }
  175. }
  176. catch (IOException e) {
  177. logger.error("Skipping discovery for JBoss AS process " + processInfo + ", because configuration dir '" + configDir + "' could not be canonicalized.", e);
  178. continue;
  179. }
  180. // Find Mobicents Diameter folder
  181. File mobicentsDiameter = new File(cmdLine.getSystemProperties().getProperty(MobicentsDiameterProperties.DIAMETER_HOME_DIR));
  182. try {
  183. if (!mobicentsDiameter.getCanonicalFile().isDirectory()) {
  184. logger.warn("Skipping discovery for Mobicents Diameter process " + processInfo + ", because Mobicents Diameter dir " + mobicentsDiameter.getCanonicalFile().getAbsolutePath() + " does not exist or is not a directory.");
  185. continue;
  186. }
  187. }
  188. catch (IOException e) {
  189. logger.error("Skipping discovery for Mobicents Diameter process " + processInfo + ", because Mobicents Diameter dir could not be canonicalized.", e);
  190. continue;
  191. }
  192. Configuration pluginConfiguration = discoveryContext.getDefaultPluginConfiguration();
  193. String jnpURL = getJnpURL(cmdLine, installHome, configDir);
  194. // TODO? Set the connection type - local or remote
  195. // Set the required props...
  196. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.NAMING_URL, jnpURL));
  197. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.HOME_DIR, installHome.getAbsolutePath()));
  198. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.SERVER_HOME_DIR, configDir));
  199. pluginConfiguration.put(new PropertySimple(MobicentsDiameterProperties.DIAMETER_HOME_DIR, cmdLine.getSystemProperties().getProperty(MobicentsDiameterProperties.DIAMETER_HOME_DIR)));
  200. pluginConfiguration.put(new PropertySimple(MobicentsDiameterProperties.DIAMETER_VERSION, cmdLine.getSystemProperties().getProperty(MobicentsDiameterProperties.DIAMETER_VERSION)));
  201. // Set the optional props...
  202. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.SERVER_NAME, cmdLine.getSystemProperties().getProperty(JBossProperties.SERVER_NAME)));
  203. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.BIND_ADDRESS, cmdLine.getSystemProperties().getProperty(JBossProperties.BIND_ADDRESS)));
  204. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.SERVER_TMP_DIR, cmdLine.getSystemProperties().getProperty(JBossProperties.SERVER_TEMP_DIR)));
  205. JBossASDiscoveryUtils.UserInfo userInfo = JBossASDiscoveryUtils.getJmxInvokerUserInfo(configDir);
  206. if (userInfo != null) {
  207. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.PRINCIPAL, userInfo.getUsername()));
  208. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.CREDENTIALS, userInfo.getPassword()));
  209. }
  210. String javaHome = processInfo.getEnvironmentVariable(JAVA_HOME_ENV_VAR);
  211. if (javaHome == null && logger.isDebugEnabled()) {
  212. logger.debug("JAVA_HOME environment variable not set in JBoss AS process - defaulting " + ApplicationServerPluginConfigurationProperties.JAVA_HOME + " connection property to the plugin container JRE dir.");
  213. javaHome = System.getenv(JAVA_HOME_ENV_VAR);
  214. }
  215. pluginConfiguration.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.JAVA_HOME, javaHome));
  216. initLogEventSourcesConfigProp(configDir, pluginConfiguration);
  217. // TODO: Init props that have static defaults.
  218. // setPluginConfigurationDefaults(pluginConfiguration);
  219. DiscoveredResourceDetails resourceDetails = createResourceDetails(discoveryContext, pluginConfiguration, processInfo, installInfo);
  220. resources.add(resourceDetails);
  221. }
  222. return resources;
  223. }
  224. private DiscoveredResourceDetails createResourceDetails(ResourceDiscoveryContext discoveryContext,
  225. Configuration pluginConfig, ProcessInfo processInfo, JBossInstallationInfo installInfo) throws Exception {
  226. String serverHomeDir = pluginConfig.getSimple(MobicentsDiameterProperties.DIAMETER_HOME_DIR).getStringValue();
  227. File absoluteConfigPath = resolvePathRelativeToHomeDir(pluginConfig, serverHomeDir);
  228. // Canonicalize the config path, so it's consistent no matter how it's entered.
  229. // This prevents two servers with different forms of the same config path, but
  230. // that are actually the same server, from ending up in inventory.
  231. // JON: fix for JBNADM-2634 - do not resolve symlinks (ips, 12/18/07)
  232. String key = FileUtils.getCanonicalPath(absoluteConfigPath.getPath());
  233. String bindAddress = pluginConfig.getSimple(ApplicationServerPluginConfigurationProperties.BIND_ADDRESS)
  234. .getStringValue();
  235. String namingUrl = pluginConfig.getSimple(ApplicationServerPluginConfigurationProperties.NAMING_URL)
  236. .getStringValue();
  237. // Only include the JNP port in the Resource name if its value is not "***CHANGE_ME***".
  238. String namingPort = getNamingPort(namingUrl);
  239. // TODO: Obtain Diameter Name/Version/Vendor from MBean
  240. /*
  241. ObjectName sleemanagement = new ObjectName(SleeManagementMBean.OBJECT_NAME);
  242. MBeanServerUtils mbeanUtils = new MBeanServerUtils(namingUrl);
  243. MBeanServerConnection connection = mbeanUtils.getConnection();
  244. String sleeName = (String) connection.getAttribute(sleemanagement, "SleeName");
  245. String sleeVersion = (String) connection.getAttribute(sleemanagement, "SleeVersion");
  246. String sleeVendor = (String) connection.getAttribute(sleemanagement, "SleeVendor");
  247. */
  248. String diameterName = "Mobicents Diameter";
  249. String diameterVersion = pluginConfig.getSimple(MobicentsDiameterProperties.DIAMETER_VERSION).getStringValue(); //"1.1.1.GA";
  250. String diameterVendor = "JBoss/Red Hat";
  251. String description = diameterName + " v" + diameterVersion + " by " + diameterVendor;
  252. String name = formatServerName(diameterName + " " + diameterVersion, bindAddress, namingPort);
  253. return new DiscoveredResourceDetails(discoveryContext.getResourceType(), key, name, diameterVersion, description, pluginConfig, processInfo);
  254. }
  255. private String formatServerName(String baseName, String bindingAddress, String jnpPort) {
  256. String details = null;
  257. if ((bindingAddress != null) && (jnpPort != null && !jnpPort.equals(CHANGE_ME))) {
  258. details = bindingAddress + ":" + jnpPort;
  259. }
  260. else if ((bindingAddress == null) && (jnpPort != null && !jnpPort.equals(CHANGE_ME))) {
  261. details = jnpPort;
  262. }
  263. else if (bindingAddress != null) {
  264. details = bindingAddress;
  265. }
  266. return baseName + ((details != null) ? (" (" + details + ")") : "");
  267. }
  268. // Get JNP related info ------------------------------------------------
  269. private String getJnpURL(JBossInstanceInfo cmdLine, File installHome, File configDir) {
  270. File jnpServiceUrlFile = new File(configDir, "data/jnp-service.url");
  271. if (jnpServiceUrlFile.exists() && jnpServiceUrlFile.canRead()) {
  272. try {
  273. BufferedReader br = new BufferedReader(new FileReader(jnpServiceUrlFile));
  274. String jnpUrl = br.readLine();
  275. if (jnpUrl != null) {
  276. if (logger.isDebugEnabled()) {
  277. logger.debug("Read JNP URL from jnp-service.url file: " + jnpUrl);
  278. }
  279. return jnpUrl;
  280. }
  281. } catch (IOException ioe) {
  282. // Nothing to do
  283. }
  284. }
  285. logger.warn("Failed to read JNP URL from '" + jnpServiceUrlFile + "'.");
  286. // Above did not work, so fall back to our previous scheme
  287. JnpConfig jnpConfig = getJnpConfig(installHome, configDir, cmdLine.getSystemProperties());
  288. String jnpAddress = (jnpConfig.getJnpAddress() != null) ? jnpConfig.getJnpAddress() : CHANGE_ME;
  289. if (ANY_ADDRESS.equals(jnpAddress)) {
  290. jnpAddress = LOCALHOST;
  291. }
  292. String jnpPort = (jnpConfig.getJnpPort() != null) ? String.valueOf(jnpConfig.getJnpPort()) : CHANGE_ME;
  293. return "jnp://" + jnpAddress + ":" + jnpPort;
  294. }
  295. private static JnpConfig getJnpConfig(File installHome, File configDir, Properties props) {
  296. File serviceXML = new File(configDir, JBOSS_SERVICE_XML);
  297. JnpConfig config = JnpConfig.getConfig(installHome, serviceXML, props);
  298. if ((config == null) || (config.getJnpPort() == null)) {
  299. File namingServiceFile = new File(configDir, JBOSS_NAMING_SERVICE_XML);
  300. if (namingServiceFile.exists()) {
  301. config = JnpConfig.getConfig(installHome, namingServiceFile, props);
  302. }
  303. }
  304. return config;
  305. }
  306. private String getNamingPort(String namingUrl) {
  307. // Only include the JNP port in the Resource name if its value is not "***CHANGE_ME***".
  308. String namingPort = null;
  309. // noinspection ConstantConditions
  310. int colonIndex = namingUrl.lastIndexOf(':');
  311. if ((colonIndex != -1) && (colonIndex != (namingUrl.length() - 1))) {
  312. // NOTE: We assume the JNP URL does not have a trailing slash.
  313. String port = namingUrl.substring(colonIndex + 1);
  314. if (!port.equals(CHANGE_ME)) {
  315. namingPort = port;
  316. }
  317. }
  318. return namingPort;
  319. }
  320. // Utils ---------------------------------------------------------------
  321. private void initLogEventSourcesConfigProp(File configDir, Configuration pluginConfig) {
  322. File logDir = new File(configDir, "log");
  323. File serverLogFile = new File(logDir, "server.log");
  324. if (serverLogFile.exists() && !serverLogFile.isDirectory()) {
  325. PropertyMap serverLogEventSource = new PropertyMap("serverLog");
  326. serverLogEventSource.put(new PropertySimple(LogFileEventResourceComponentHelper.LogEventSourcePropertyNames.LOG_FILE_PATH, serverLogFile));
  327. serverLogEventSource.put(new PropertySimple(LogFileEventResourceComponentHelper.LogEventSourcePropertyNames.ENABLED, Boolean.FALSE));
  328. PropertyList logEventSources = pluginConfig.getList(LogFileEventResourceComponentHelper.LOG_EVENT_SOURCES_CONFIG_PROP);
  329. // TODO : Not sure why I get this null
  330. if (logEventSources != null) {
  331. logEventSources.add(serverLogEventSource);
  332. }
  333. }
  334. }
  335. private static File resolvePathRelativeToHomeDir(Configuration pluginConfig, String path) {
  336. File configDir = new File(path);
  337. if (!configDir.isAbsolute()) {
  338. String homeDir = pluginConfig.getSimple(ApplicationServerPluginConfigurationProperties.HOME_DIR).getStringValue();
  339. configDir = new File(homeDir, path);
  340. }
  341. return configDir;
  342. }
  343. }