/* * JBoss, Home of Professional Open Source * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * 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, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2008, * @author JBoss Inc. */ package org.jboss.test.jbossts.taskdefs; import java.io.File; import java.io.IOException; import java.io.FileWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.TransformerFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import org.w3c.dom.*; import org.xml.sax.SAXException; /** * Helper class to read a JBoss AS bindings file */ public class ServerBindingConfig { private static final String BINDING_MANAGER_NAME = "jboss.system:service=ServiceBindingManager"; private static final String BINDING_MANAGER_CLASS = "org.jboss.services.binding.ServiceBindingManager"; private static final String STORE_FACTORY_CLASS = "org.jboss.services.binding.XMLServicesStoreFactory"; public static final String DEFAULT_BINDING = "ports-01"; /** * Configure an AS to start up with a non-default set of bindings. * * An mbean entry will be inserted into xmlFile with a name specified by bindingName. * The file bindingXml will contain an entry with the name bindingName. * * @param xmlFile The file that is to recieve the binding service specification * @param bindingName The name of the binding definition to use * @param bindingXml file name of the file that contains a group of binding definitions * @throws IOException * @throws ParserConfigurationException * @throws org.xml.sax.SAXException * @throws TransformerException */ public static void setBinding(String xmlFile, String bindingName, String bindingXml) throws IOException, ParserConfigurationException, org.xml.sax.SAXException, TransformerException { String xmlFileName = Utils.toFile(xmlFile).getAbsolutePath(); System.out.println("update bindings:"); System.out.println("\tConf File: " + xmlFileName); System.out.println("\tBinding File: " + bindingXml); System.out.println("\tBinding Name: " + bindingName); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setValidating(false); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document doc1 = documentBuilder.parse(xmlFileName); Document doc2 = documentBuilder.newDocument(); doc2.appendChild(doc2.createElement("server")); NodeList children = doc1.getDocumentElement().getChildNodes(); Node server2 = doc2.getDocumentElement(); // add an mbean entry for the server binding server2.appendChild(createBinding(doc2, bindingName, bindingXml)); for (int i=0; i< children.getLength(); i++) { Node child = children.item(i); if ("mbean".equals(child.getNodeName())) { String name = ((Element) child).getAttribute("name"); // ignore the original binding since we are creating a new one if (BINDING_MANAGER_NAME.equals(name)) continue; } // take a detached copy of the node and add it to the new document Node copy = doc2.importNode(child, true).cloneNode(true); server2.appendChild(copy); } printDocument(doc2, xmlFileName); } private static Element createBinding(Document document, String binding, String bindingXml) { Element mbean = document.createElement("mbean"); mbean.setAttribute("code", BINDING_MANAGER_CLASS); mbean.setAttribute("name", BINDING_MANAGER_NAME); mbean.appendChild(createMbeanAttribute(document, "ServerName", binding)); mbean.appendChild(createMbeanAttribute(document, "StoreURL", bindingXml)); mbean.appendChild(createMbeanAttribute(document, "StoreFactoryClassName", STORE_FACTORY_CLASS)); return mbean; } private static Element createMbeanAttribute(Document document, String name, String cdata) { Element element = document.createElement("attribute"); element.setAttribute("name", name); element.setTextContent(cdata); return element; } public static void printDocument(Document document, String fname){ try{ TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); DOMSource source = new DOMSource(document); StreamResult result; if (fname == null) result = new StreamResult(System.out); else result = new StreamResult(new FileWriter(fname)); transformer.transform(source, result); } catch(Exception e) { e.printStackTrace(); } } private static Document getDocument(String xmlFile) { Document doc = null; DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setValidating(false); try { DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); doc = documentBuilder.parse(xmlFile); } catch (ParserConfigurationException e) { System.out.println("Unable to locate an XML doc builder: " + e.getMessage()); } catch (Exception e) { System.out.println("Error parsing " + xmlFile + ' ' + e.getMessage()); } return doc; } public static Node findServiceConfig(String bindingsFile, String server, String service) { Document doc = getDocument(bindingsFile); if (doc == null) return null; Node node = findNode(doc.getDocumentElement(), "server", "name", server); return (node != null ? findNode(node, "service-config", "name", service) : null); } public static String findBindingPort(Node node) { node = findNode(node, "binding", "port", null); return (node != null ? ((Element) node).getAttribute("port") : null); } private static int parseInt(String intValue, int defValue, String errMsg) { try { return (intValue != null ? Integer.parseInt(intValue) : defValue); } catch (NumberFormatException e) { if (errMsg != null) System.out.println(errMsg); return defValue; } } public static int lookupHttpPort(String bindingsFile, String server, int defValue) { Node node = findServiceConfig(bindingsFile, server, "jboss:service=invoker,type=http"); String port = findBindingPort(node); return parseInt(port, defValue, "Invalid port found in service-config for binding " + server); } public static int lookupRmiPort(String bindingsFile, String server, int defValue) { Node node = findServiceConfig(bindingsFile, server, "jboss:service=Naming"); String port = findBindingPort(node); return parseInt(port, defValue, "Invalid port found in service-config for binding " + server); } /** * Find a node with a given name and having a specified attribute * @param node the node to start the search from * @param nodeName the name of the xml node to look for the attribute * @param attrName the name of the attribute to match against * @param attrValue the value of the attribute to match against. If null * the first matching node with an attribute called attrName is returned * @return the matching node */ private static Node findNode(Node node, String nodeName, String attrName, String attrValue) { if (node != null) { NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (nodeName.equals(child.getNodeName())) { // found a node of the correct type - now see if it has the given attribute String value = ((Element) child).getAttribute(attrName); if (attrName == null || attrValue == null || value.equals(attrValue)) return child; } } System.out.println("Node of type " + nodeName + " with " + attrName + '=' + attrValue + " not found"); } return null; } public static void main(String[] args) throws IOException, ParserConfigurationException, org.xml.sax.SAXException, TransformerException { if (args.length >= 3) { setBinding(args[0], args[1], args[2]); } else if (args.length == 2) { System.out.println("Rmi port: " + lookupRmiPort(args[0], args[1], -1)); System.out.println("Http port: " + lookupHttpPort(args[0], args[1], -1)); } else { System.out.println("syntax: ServerBindingConfig <conf file path> <server binding name> <path of bindings file>"); } } }