/* * 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.util.ArrayList; import java.util.HashMap; import java.util.Properties; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.NamedNodeMap; /** * Config parsing intended only for WebLogic Admin server auto discovery. */ public class WeblogicConfig { String version; String domain; String adminPort; boolean adminPortEnabled; HashMap runningNodes = new HashMap(); ArrayList servers = new ArrayList(); class Server { String domain; String name; String version; String url; public Properties getProperties() { Properties props = new Properties(); props.setProperty(WeblogicMetric.PROP_DOMAIN, this.domain); props.setProperty(WeblogicMetric.PROP_ADMIN_URL, this.url); props.setProperty(WeblogicMetric.PROP_SERVER_URL, this.url); props.setProperty(WeblogicMetric.PROP_SERVER, this.name); return props; } public String getVersion() { if (this.version == null) { return WeblogicProductPlugin.VERSION_61; //lousy guess } return this.version; } private void setURL(String protocol, String addr, String port) { this.url = protocol + "://" + addr + ":" + port; } @Override public String toString(){ return "[domain='"+domain+"' name='"+name+"' version='"+version+"' url='"+url+"']"; } } public void read(File file) throws IOException { FileInputStream is = null; try { is = new FileInputStream(file); parse(is); } catch (SAXException e) { throw new IllegalArgumentException(e.getMessage()); } catch (ParserConfigurationException e) { throw new IllegalArgumentException(e.getMessage()); } finally { if (is != null) { try { is.close(); } catch (IOException e) { } } } if ((this.version != null) && majorVersion(this.version) >= 9) { for (int i=0; i<this.servers.size(); i++) { Server server = (Server)this.servers.get(i); if (server.version == null) { server.version = this.version; } } } if (!WeblogicProductPlugin.VERSION_61.equals(this.version)) { return; } //7.0/8.1 has a filesystem layout we can use to //detect the admin server. //6.1 does not so we try to guess. file = new File(file.getParentFile(), "running-managed-servers.xml"); if (!file.exists()) { return; } try { is = new FileInputStream(file); parseRunningServers(is); } finally { if (is != null) { try { is.close(); } catch (IOException e) { } } } } public Server getServer(String name) { for (int i=0; i<this.servers.size(); i++) { Server server = (Server)this.servers.get(i); if (server.name.equals(name)) { return server; } } return null; } public Server guessAdminServer() { for (int i=0; i<this.servers.size(); i++) { Server server = (Server)this.servers.get(i); if (this.runningNodes.get(server.name) != null) { continue; } return server; } return (Server)this.servers.get(0); } private String getAttribute(Node node, String name) { NamedNodeMap attrs = node.getAttributes(); if (attrs == null) { return null; } Node item = attrs.getNamedItem(name); if (item == null) { return null; } return item.getNodeValue(); } private String versionSubstring(String version) { int ix = version.indexOf('.'); if (ix == -1){ return version.substring(0, 3); } else { return version.substring(0, ix+2); } } public static int majorVersion(String version) { int ix = version.indexOf('.'); if (ix == -1) { return Integer.parseInt(version); } else { return Integer.parseInt(version.substring(0, ix)); } } private String getVersion(Node node, String attr) { String vers = getAttribute(node, attr); if ((vers != null) && vers.length() >= 3) { //7.0|8.1 return versionSubstring(vers); } return this.version; } private void parseRunningServers(FileInputStream is) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String line; //XXX somewhat ghetto. xml parser could not resolve // "/weblogic/management/xml/managed-server.dtd" //which is in weblogic.jar, but was being treated as //a file url. had tried turning off dtd validation //but did not work against the 6.1 jar. //wasted enough time on it, this file is always in the //same format since its generated. while ((line = reader.readLine()) != null) { line = line.trim(); if (!line.equals("<server-name>")) { continue; } String name = reader.readLine(); this.runningNodes.put(name.trim(), Boolean.TRUE); } } private void parse(InputStream is) throws IOException, SAXException, ParserConfigurationException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(is); Element domain = doc.getDocumentElement(); this.version = getVersion(domain, "ConfigurationVersion"); this.domain = getAttribute(domain, "Name"); this.adminPort = getAttribute(domain, "AdministrationPort"); this.adminPortEnabled = "true".equals(getAttribute(domain, "AdministrationPortEnabled")); NodeList nodes = domain.getChildNodes(); for (int i=0; i<nodes.getLength(); i++) { Node node = nodes.item(i); String tag = node.getNodeName(); if (tag.equals("Server")) { Server server = new Server(); server.domain = this.domain; server.name = getAttribute(node, "Name"); server.version = getVersion(node, "ServerVersion"); String port = null; if (this.adminPortEnabled) { port = getAttribute(node, "AdministrationPort"); if (port == null) { port = this.adminPort; } } if (port == null) { //config.xml in the examples have //AdministrationPortEnabled=true //but no AdministrationPort set if the //server has never been started. port = getAttribute(node, "ListenPort"); this.adminPortEnabled = false; } String addr = getAttribute(node, "ListenAddress"); if ((addr == null) || //not running "".equals(addr)) //weblogic81 configbuilder bug { addr = "localhost"; } String protocol; if (this.adminPortEnabled) { protocol = "t3s"; } else { protocol = "t3"; } server.setURL(protocol, addr, port); this.servers.add(server); } //9.0 stuff else if (tag.equals("server")) { String protocol = "t3"; String addr="localhost", port="7001"; Server server = new Server(); server.domain = this.domain; server.version = this.version; NodeList srvNodes = node.getChildNodes(); for (int j=0; j<srvNodes.getLength(); j++) { Node srv = srvNodes.item(j); String srvTag = srv.getNodeName(); if (srvTag.equals("name")) { server.name = getText(srv); } else if (srvTag.equals("listen-port")) { String val = getText(srv); if (val != null) { port = val; } } else if (srvTag.equals("listen-address")) { String val = getText(srv); if (val != null) { addr = val; } } } server.setURL(protocol, addr, port); servers.add(server); } else if (tag.equals("configuration-version")) { this.version = versionSubstring(getText(node)); } else if (tag.equals("name")) { this.domain = getText(node); } //end 9.0 stuff else if (tag.equals("StartupClass")) { if (this.version == null) { //6.1 does not have version info //so we guess based on this old tag //that does not exist in 7.0+ this.version = WeblogicProductPlugin.VERSION_61; for (int n=0; n<this.servers.size(); n++) { Server server = (Server)this.servers.get(n); if (server.version == null) { server.version = this.version; } } } } } } private String getText(Node node) { Node child = node.getFirstChild(); if (child == null) { return null; } String value = child.getNodeValue(); if (value == null) { return null; } return value.trim(); } private static void testConfig(String file) throws Exception { WeblogicConfig cfg = new WeblogicConfig(); cfg.read(new File(file)); System.out.println(cfg.version); System.out.println(cfg.domain); System.out.println("admin=" + cfg.guessAdminServer().name); for (int i=0; i<cfg.servers.size(); i++) { Server server = (Server)cfg.servers.get(i); Properties props = server.getProperties(); props.put("version", server.getVersion()); props.list(System.out); } } public static void main(String args[]) throws Exception { for (int i=0; i<args.length; i++) { System.out.println(args[0] + "..."); testConfig(args[0]); } } }