| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.kalumet.controller.jboss; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.kalumet.FileManipulator; |
| import org.apache.kalumet.controller.core.AbstractJEEApplicationServerController; |
| import org.apache.kalumet.controller.core.ControllerException; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import javax.management.MBeanServerConnection; |
| import javax.management.MalformedObjectNameException; |
| import javax.management.ObjectName; |
| import javax.management.remote.JMXConnector; |
| import javax.management.remote.JMXConnectorFactory; |
| import javax.management.remote.JMXServiceURL; |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.Reader; |
| import java.io.StringWriter; |
| import java.net.URL; |
| import java.text.MessageFormat; |
| import java.util.Date; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| /** |
| * JBoss 6 controller. |
| */ |
| public class JBoss6Controller |
| extends AbstractJEEApplicationServerController |
| { |
| |
| private final static transient Logger LOGGER = LoggerFactory.getLogger( JBoss6Controller.class ); |
| |
| private JMXServiceURL jmxServiceURL; |
| |
| private URL deployURL; |
| |
| /** |
| * Default constructor. |
| * NB: the JBoss application server should accept remote JMX connection. To do so,in the run.conf/run.bat of the JBoss application server, |
| * you have to add: |
| * JAVA_OPTS="$JAVA_OPTS |
| * -Djboss.platform.mbeanserver |
| * -Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl |
| * -Dcom.sun.management.jmxremote.port=12345 |
| * -Dcom.sun.management.jmxremote.authenticate=false |
| * -Dcom.sun.management.jmxremote.ssl=false |
| * -Djava.util.logging.manager=org.jboss.logmanager.LogManager |
| * -Djava.util.logging.manager=org.jboss.logmanager.LogManager" |
| * -Dorg.jboss.logging.Logger.pluginClass=org.jboss.logging.logmanager.LoggerPluginImpl" |
| * JBOSS_CLASSPATH="/absolute/path/to/lib/jboss-logmanager.jar" |
| * |
| * @param url the JMX URL to connect to the JBoss application server (both pure JMX URL and JNP URLs are supported). |
| * @param username the username to connect to the JBoss MBean server. |
| * @param password the password to connect to the JBoss MBean server. |
| * @param serverName the server name to manage (not used with JBoss). |
| * @param cluster true to use a cluster topology, false else (not used with JBoss). |
| * @throws ControllerException in case of connection failure. |
| */ |
| public JBoss6Controller( String url, String username, String password, String serverName, Boolean cluster ) |
| throws ControllerException |
| { |
| super( url, username, password, serverName, cluster ); |
| if ( url.startsWith( "jnp://" ) ) |
| { |
| url = url.substring( 6 ); |
| url = "service:jmx:rmi:///jndi/rmi://" + url + "/jmxrmi"; |
| this.setUrl( url ); |
| } |
| } |
| |
| /** |
| * Initialize the connection to the JBoss application server. |
| * |
| * @throws ControllerException |
| */ |
| protected void init() |
| throws ControllerException |
| { |
| try |
| { |
| this.jmxServiceURL = new JMXServiceURL( this.getUrl() ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't connect to the JBoss application server", e ); |
| throw new ControllerException( "Can't connect to the JBoss application server", e ); |
| } |
| // disable the deployment scanner and get the deploy folder |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName deploymentScannerMBean = new ObjectName( "jboss.deployment:flavor=URL,type=DeploymentScanner" ); |
| server.invoke( deploymentScannerMBean, "stop", null, null ); |
| ObjectName serverConfigMBean = new ObjectName( "jboss.system:type=ServerConfig" ); |
| String deployFolder = |
| ( (URL) server.getAttribute( serverConfigMBean, "ServerHomeLocation" ) ).toString() + "/deploy"; |
| this.deployURL = new URL( deployFolder ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't stop the JBoss deployment scanner or get the deploy folder", e ); |
| throw new ControllerException( "Can't stop the JBoss deployment scanner or get the deploy folder", e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public void shutdown() |
| throws ControllerException |
| { |
| LOGGER.info( "Shutting down JBoss application server" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| ObjectName serverMBean = new ObjectName( "jboss.system:type=Server" ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| server.invoke( serverMBean, "shutdown", null, null ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't shutdown JBoss application server", e ); |
| throw new ControllerException( "Can't shutdown JBoss application server", e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public String status() |
| throws ControllerException |
| { |
| LOGGER.info( "Checking status of JBoss application server" ); |
| boolean stopped = isStopped(); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| ObjectName serverMBean = new ObjectName( "jboss.system:type=Server" ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| if ( !stopped ) |
| { |
| LOGGER.debug( "JBoss application server started" ); |
| return "JBoss application server started since " + (Date) server.getAttribute( serverMBean, |
| "StartDate" ); |
| } |
| else |
| { |
| LOGGER.debug( "JBoss application server stopped" ); |
| return "JBoss application server stopped"; |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.warn( "Can't check status of the JBoss application server", e ); |
| return "N/A"; |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public boolean isStopped() |
| throws ControllerException |
| { |
| LOGGER.info( "Checking if JBoss application server is stopped" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| ObjectName serverMBean = new ObjectName( "jboss.system:type=Server" ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| return !( ( (Boolean) server.getAttribute( serverMBean, "Started" ) ).booleanValue() ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.warn( "Can't check if JBoss application server is stopped. The server is probably down.", e ); |
| return true; |
| } |
| } |
| |
| /** |
| * Format an application path in a JBoss compliant URL. |
| * |
| * @param path the JEE application path. |
| * @return the JBoss application URL. |
| */ |
| private static String formatPathToUrl( String path ) |
| { |
| String trimmed = path.trim(); |
| if ( trimmed.startsWith( "http:" ) || trimmed.startsWith( "file:" ) ) |
| { |
| LOGGER.debug( "The path is already in a JBoss compliant URL" ); |
| return trimmed; |
| } |
| else |
| { |
| LOGGER.debug( "Prefixing path with file: protocol" ); |
| return "file:" + trimmed; |
| } |
| } |
| |
| public boolean isJEEApplicationDeployed( String path, String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Checking if JEE application {} is deployed in the JBoss application server", name ); |
| String applicationUrl = JBoss6Controller.formatPathToUrl( path ); |
| boolean deployed = false; |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| deployed = ( (Boolean) server.invoke( mainDeployerMBean, "isDeployed", new Object[]{ applicationUrl }, |
| new String[]{ "java.lang.String" } ) ).booleanValue(); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't check if JEE application {} is deployed", name, e ); |
| throw new ControllerException( "Can't check if JEE application " + name + " is deployed", e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| return deployed; |
| } |
| |
| public void deployJEEApplication( String path, String name, String classloaderorder, String classloaderpolicy, |
| String vhost ) |
| throws ControllerException |
| { |
| LOGGER.info( "Deploying JEE application {} located {}", name, path ); |
| String applicationUrl = JBoss6Controller.formatPathToUrl( path ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ applicationUrl }, |
| new String[]{ "java.lang.String" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't deploy JEE application {}", name, e ); |
| throw new ControllerException( "Can't deploy JEE application " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public void undeployJEEApplication( String path, String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Undeploying JEE application {} located {}", name, path ); |
| String applicationUrl = JBoss6Controller.formatPathToUrl( path ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "undeploy", new Object[]{ applicationUrl }, |
| new String[]{ "java.lang.String" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't undeploy JEE application {}", name, e ); |
| throw new ControllerException( "Can't undeploy JEE application " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public void redeployJEEApplication( String path, String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Redeploying JEE application {} located {}", name, path ); |
| String applicationUrl = JBoss6Controller.formatPathToUrl( path ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "redeploy", new Object[]{ applicationUrl }, |
| new String[]{ "java.lang.String" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't redeploy JEE application {}", name, e ); |
| throw new ControllerException( "Can't redeploy JEE application " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public boolean isJDBCConnectionPoolDeployed( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Checking if JDBC connection pool {} is deployed", name ); |
| boolean deployed = false; |
| File file = new File( deployURL.getPath() + "/" + name + "-ds.xml" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| deployed = ( (Boolean) server.invoke( mainDeployerMBean, "isDeployed", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ) ).booleanValue(); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't check if JDBC connection pool {} is deployed", name, e ); |
| throw new ControllerException( "Can't check if JDBC connection pool " + name + " is deployed", e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| return deployed; |
| } |
| |
| public boolean isJDBCConnectionPoolUpToDate( String name, String driver, int increment, int initial, int maximal, |
| String user, String password, String url, String classpath ) |
| throws ControllerException |
| { |
| LOGGER.info( "Checking if JDBC connection pool {} is up to date", name ); |
| if ( !this.isJDBCConnectionPoolDeployed( name ) ) |
| { |
| LOGGER.debug( "JDBC connection pool {} is not deployed", name ); |
| return false; |
| } |
| File tempFile = new File( deployURL.getPath() + "/" + name + "-ds.xml.temp" ); |
| this.jdbcConnectionPoolWriteFile( tempFile, name, driver, increment, initial, maximal, user, password, url ); |
| FileManipulator fileManipulator = null; |
| try |
| { |
| fileManipulator = new FileManipulator(); |
| if ( fileManipulator.contentEquals( deployURL.getPath() + "/" + name + "-ds.xml", |
| deployURL.getPath() + "/" + name + "-ds.xml.temp" ) ) |
| { |
| LOGGER.debug( "JDBC connection pool {} is already up to date", name ); |
| return true; |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't check status of JDBC connection pool {}", name, e ); |
| throw new ControllerException( "Can't check status of JDBC connection pool " + name, e ); |
| } |
| finally |
| { |
| if ( fileManipulator != null ) |
| { |
| try |
| { |
| fileManipulator.delete( tempFile.getAbsolutePath() ); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| return false; |
| } |
| |
| public boolean updateJDBCConnectionPool( String name, String driver, int increment, int initial, int maximal, |
| String user, String password, String url, String classpath ) |
| throws ControllerException |
| { |
| LOGGER.info( "Updating JDBC connection pool {}", name ); |
| if ( !this.isJDBCConnectionPoolUpToDate( name, driver, increment, initial, maximal, user, password, url, |
| classpath ) ) |
| { |
| LOGGER.debug( "JDBC connection pool {} must be updated, redeploy it", name ); |
| this.undeployJDBCConnectionPool( name ); |
| this.deployJDBCConnectionPool( name, driver, increment, initial, maximal, user, password, url, classpath ); |
| return true; |
| } |
| return false; |
| } |
| |
| public void deployJDBCConnectionPool( String name, String driver, int increment, int initial, int maximal, |
| String user, String password, String url, String classpath ) |
| throws ControllerException |
| { |
| LOGGER.info( "Deploying JDBC connection pool {}", name ); |
| LOGGER.debug( "Creating the JBoss datasource XML file" ); |
| File file = new File( deployURL.getPath() + "/" + name + "-ds.xml" ); |
| this.jdbcConnectionPoolWriteFile( file, name, driver, increment, initial, maximal, user, password, url ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ file.toURL() }, new String[]{ "java.net.URL" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't deploy JDBC connection pool {}", name, e ); |
| throw new ControllerException( "Can't deploy JDBC connection pool " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public void undeployJDBCConnectionPool( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Undeploying JDBC connection pool {}", name ); |
| File file = new File( deployURL.getPath() + "/" + name + "-ds.xml" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "undeploy", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't undeploy JDBC connection pool {}", name, e ); |
| throw new ControllerException( "Can't undeploy JDBC connection pool " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public boolean isJDBCDataSourceDeployed( String name ) |
| throws ControllerException |
| { |
| LOGGER.warn( "JDBC data source is not available with JBoss server. Use JDBC connection pool instead." ); |
| return true; |
| } |
| |
| public boolean isJDBCDataSourceUpToDate( String name, String jdbcConnectionPool, String jdbcUrl, |
| String helperClassname ) |
| throws ControllerException |
| { |
| LOGGER.warn( "JDBC data source is not available with JBoss server. Use JDBC connection pool instead." ); |
| return true; |
| } |
| |
| public void deployJDBCDataSource( String name, String jdbcConnectionPool, String jdbcUrl, String helperClassname ) |
| throws ControllerException |
| { |
| LOGGER.warn( "JDBC data source is not available with JBoss server. Use JDBC connection pool instead." ); |
| } |
| |
| public void undeployJDBCDataSource( String name ) |
| throws ControllerException |
| { |
| LOGGER.warn( "JDBC data source is not available with JBoss server. Use JDBC connection pool instead." ); |
| } |
| |
| public boolean updateJDBCDataSource( String name, String jdbcConnectionPool, String jdbcUrl, |
| String helperClassname ) |
| throws ControllerException |
| { |
| LOGGER.warn( "JDBC data source is not available with JBoss server. Use JDBC connection pool instead." ); |
| return false; |
| } |
| |
| public boolean isJMSConnectionFactoryDeployed( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Checking if the JMS connection factory {} is already deployed" ); |
| boolean deployed = false; |
| File file = new File( deployURL.getPath() + "/jms/" + name + "-ds.xml" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| deployed = ( (Boolean) server.invoke( mainDeployerMBean, "isDeployed", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ) ).booleanValue(); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't check if the JMS connection {} is deployed", name, e ); |
| throw new ControllerException( "Can't check if the JMS connection " + name + " is deployed", e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| return deployed; |
| } |
| |
| public void deployJMSConnectionFactory( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Deploying JMS connection factory {}", name ); |
| File file = new File( deployURL.getPath() + "/jms/" + name + "-ds.xml" ); |
| jmsConnectionFactoryWriteFile( file, name ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ file.toURL() }, new String[]{ "java.net.URL" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't deploy JMS connection factory {}", name, e ); |
| throw new ControllerException( "Can't deploy JMS connection factory " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public void undeployJMSConnectionFactory( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Undeploying JMS connection factory {}", name ); |
| File file = new File( deployURL.getPath() + "/jms/" + name + "-ds.xml" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "undeploy", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't undeploy JMS connection factory {}", name, e ); |
| throw new ControllerException( "Can't undeploy JMS connection factory " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public boolean isJMSServerDeployed( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Checking if JMS server {} is deployed", name ); |
| LOGGER.warn( "JMS server is embedded in the JBoss application server" ); |
| return true; |
| } |
| |
| public void deployJMSServer( String name, List queues, List topics ) |
| throws ControllerException |
| { |
| LOGGER.info( "Deploying JMS server {}", name ); |
| LOGGER.warn( "JMS server is embedded in the JBoss application server" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| LOGGER.info( "Deploying JMS queues" ); |
| for ( Iterator queueIterator = queues.iterator(); queueIterator.hasNext(); ) |
| { |
| String queue = (String) queueIterator.next(); |
| LOGGER.info( "Deploying JMS queue {}", queue ); |
| File file = new File( deployURL.getPath() + "/jms/" + queue + "-service.xml" ); |
| this.jmsQueueWriteFile( file, queue ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ); |
| } |
| LOGGER.info( "Deploying JMS topics" ); |
| for ( Iterator topicIterator = topics.iterator(); topicIterator.hasNext(); ) |
| { |
| String topic = (String) topicIterator.next(); |
| LOGGER.info( "Deploying JMS topic {}", topic ); |
| File file = new File( deployURL.getPath() + "/jms/" + topic + "-service.xml" ); |
| this.jmsTopicWriteFile( file, topic ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ); |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't deploy JMS server {}", name, e ); |
| throw new ControllerException( "Can't deploy JMS server " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public boolean isJMSServerUpToDate( String name, List queues, List topics ) |
| throws ControllerException |
| { |
| LOGGER.info( "Checking if the JMS server {} is up to date", name ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| for ( Iterator queueIterator = queues.iterator(); queueIterator.hasNext(); ) |
| { |
| String queue = (String) queueIterator.next(); |
| ObjectName queueMBean = new ObjectName( "jboss.mq.destination:name=" + queue + ",service=Queue" ); |
| boolean started = ( (Boolean) server.getAttribute( queueMBean, "Started" ) ).booleanValue(); |
| if ( !started ) |
| { |
| return false; |
| } |
| } |
| for ( Iterator topicIterator = queues.iterator(); topicIterator.hasNext(); ) |
| { |
| String topic = (String) topicIterator.next(); |
| ObjectName topicMBean = new ObjectName( "jboss.mq.destination:name=" + topic + ",service=Topic" ); |
| boolean started = ( (Boolean) server.getAttribute( topicMBean, "Started" ) ).booleanValue(); |
| if ( !started ) |
| { |
| return false; |
| } |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't check if JMS server {} is up to date", name, e ); |
| throw new ControllerException( "Can't check if JMS server " + name + " is up to date", e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| return true; |
| } |
| |
| public boolean updateJMSServer( String name, List queues, List topics ) |
| throws ControllerException |
| { |
| LOGGER.info( "Updating JMS server {}", name ); |
| boolean updated = false; |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| LOGGER.info( "Checking JMS queues" ); |
| for ( Iterator queueIterator = queues.iterator(); queueIterator.hasNext(); ) |
| { |
| String queue = (String) queueIterator.next(); |
| boolean started = false; |
| LOGGER.debug( "Checking if JMS queue {} is deployed", queue ); |
| ObjectName queueMBean = null; |
| try |
| { |
| queueMBean = new ObjectName( "jboss.mq.destination:name=" + queue + ",service=Queue" ); |
| } |
| catch ( MalformedObjectNameException malformedObjectNameException ) |
| { |
| LOGGER.debug( "JMS queue {} doesn't seem to be deployed, deploy it", queue ); |
| try |
| { |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| File file = new File( deployURL.getPath() + "/jms/" + queue + "-service.xml" ); |
| this.jmsQueueWriteFile( file, queue ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ); |
| updated = true; |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't deploy JMS queue {}", name, e ); |
| throw new ControllerException( "Can't deploy JMS queue " + name, e ); |
| } |
| } |
| try |
| { |
| started = ( (Boolean) server.getAttribute( queueMBean, "Started" ) ).booleanValue(); |
| if ( !started ) |
| { |
| server.invoke( queueMBean, "start", null, null ); |
| updated = true; |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't start JMS queue {}", name, e ); |
| throw new ControllerException( "Can't start JMS queu " + name, e ); |
| } |
| } |
| LOGGER.info( "Checking JMS topics" ); |
| for ( Iterator topicIterator = topics.iterator(); topicIterator.hasNext(); ) |
| { |
| String topic = (String) topicIterator.next(); |
| boolean started = false; |
| LOGGER.debug( "Check if JMS topic {} is deployed", topic ); |
| ObjectName topicMBean = null; |
| try |
| { |
| topicMBean = new ObjectName( "jboss.mq.destination:name=" + topic + ",service=Topic" ); |
| } |
| catch ( MalformedObjectNameException malformedObjectNameException ) |
| { |
| LOGGER.debug( "JMS topic {} doesn't seem to be deployed, deploy it", topic ); |
| try |
| { |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| File file = new File( deployURL.getPath() + "/jms/" + topic + "-service.xml" ); |
| this.jmsTopicWriteFile( file, topic ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ file.toURL() }, |
| new String[]{ "java.net.URL" } ); |
| updated = true; |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't deploy JMS topic {}", topic, e ); |
| throw new ControllerException( "Can't deploy JMS topic " + name, e ); |
| } |
| } |
| try |
| { |
| started = ( (Boolean) server.getAttribute( topicMBean, "Started" ) ).booleanValue(); |
| if ( !started ) |
| { |
| server.invoke( topicMBean, "start", null, null ); |
| updated = true; |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't start JMS topic {}", topic, e ); |
| throw new ControllerException( "Can't start JMS topic " + topic, e ); |
| } |
| } |
| } |
| catch ( IOException e ) |
| { |
| LOGGER.error( "Can't connect to the JBoss application server", e ); |
| throw new ControllerException( "Can't connect to the JBoss application server", e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| return updated; |
| } |
| |
| public void undeployJMSServer( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Undeploying the JMS server {}", name ); |
| LOGGER.warn( "The JMS server is embedded in JBoss application server" ); |
| } |
| |
| public boolean isJNDIBindingDeployed( String name ) |
| { |
| LOGGER.info( "Checking if JNDI binding {} is deployed", name ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName jndiViewMBean = new ObjectName( "jboss:service=JNDIView" ); |
| String output = (String) server.invoke( jndiViewMBean, "list", new Object[]{ new Boolean( false ) }, |
| new String[]{ "java.lang.Boolean" } ); |
| if ( StringUtils.containsIgnoreCase( output, name ) ) |
| { |
| LOGGER.debug( "JNDI binding {} found", name ); |
| return true; |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.warn( "Can't check if JNDI binding {} is deployed", name, e ); |
| return false; |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| return false; |
| } |
| |
| public void deployJNDIBinding( String name, String jndiName, String jndiAlias, String providerUrl ) |
| throws ControllerException |
| { |
| LOGGER.info( "Deploying JNDI binding {}", name ); |
| File file = new File( deployURL.getPath() + "/" + name + "-service.xml" ); |
| this.jndiAliasWriteFile( file, name, jndiName, jndiAlias ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName mainDeployerMBean = new ObjectName( "jboss.system:service=MainDeployer" ); |
| server.invoke( mainDeployerMBean, "deploy", new Object[]{ file.toURL() }, new String[]{ "java.net.URL" } ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't deploy JNDI binding {}", name, e ); |
| throw new ControllerException( "Can't deploy JNDI binding " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public void undeployJNDIBinding( String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Undeploying JNDI binding {}", name ); |
| File file = new File( deployURL.getPath() + "/" + name + "-service.xml" ); |
| JMXConnector connector = null; |
| try |
| { |
| connector = JMXConnectorFactory.connect( jmxServiceURL, null ); |
| MBeanServerConnection server = connector.getMBeanServerConnection(); |
| ObjectName namingMBean = new ObjectName( "jboss:service=Naming" ); |
| server.invoke( namingMBean, "removeAlias", new Object[]{ name }, new String[]{ "java.lang.String" } ); |
| file.delete(); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't undeploy JNDI binding {}", name, e ); |
| throw new ControllerException( "Can't undeploy JNDI binding " + name, e ); |
| } |
| finally |
| { |
| if ( connector != null ) |
| { |
| try |
| { |
| connector.close(); |
| } |
| catch ( Exception e ) |
| { |
| // nothing to do |
| } |
| } |
| } |
| } |
| |
| public boolean isJNDIBindingUpToDate( String name, String jndiName, String jndiAlias, String providerUrl ) |
| throws ControllerException |
| { |
| LOGGER.info( "Checking status of JNDI binding {}", name ); |
| if ( isJNDIBindingDeployed( name ) ) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| public boolean updateJNDIBinding( String name, String jndiName, String jndiAlias, String providerUrl ) |
| throws ControllerException |
| { |
| LOGGER.info( "Updating JNDI binding {}", name ); |
| if ( isJNDIBindingDeployed( name ) ) |
| { |
| this.undeployJNDIBinding( name ); |
| this.deployJNDIBinding( name, jndiName, jndiAlias, providerUrl ); |
| return true; |
| } |
| return false; // return false either if the name space binding is always updated |
| } |
| |
| public boolean isSharedLibraryDeployed( String name ) |
| throws ControllerException |
| { |
| LOGGER.warn( "Shared libraries are not supported with JBoss application server" ); |
| return true; |
| } |
| |
| public void deploySharedLibrary( String name, String classpath ) |
| throws ControllerException |
| { |
| LOGGER.warn( "Shared libraries are not supported with JBoss application server" ); |
| } |
| |
| public void undeploySharedLibrary( String name ) |
| throws ControllerException |
| { |
| LOGGER.warn( "Shared libraries are not supported with JBoss application server" ); |
| } |
| |
| public boolean isSharedLibraryUpToDate( String name, String classpath ) |
| throws ControllerException |
| { |
| LOGGER.warn( "Shared libraries are not supported with JBoss application server" ); |
| return false; |
| } |
| |
| public boolean updateSharedLibrary( String name, String classpath ) |
| throws ControllerException |
| { |
| LOGGER.warn( "Shared libraries are not supported with JBoss application server" ); |
| return false; |
| } |
| |
| /** |
| * Create a JBoss connection pool/data source XML file. |
| * |
| * @param file the JBoss connection pool/data source XML file. |
| * @param name the JDBC connection pool name. |
| * @param driver the JDBC connection pool JDBC driver. |
| * @param increment the JDBC connection pool capacity increment. |
| * @param initial the JDBC connection pool initial capacity. |
| * @param maximal the JDBC connection pool maximal capacity. |
| * @param user the JDBC connection pool database user name. |
| * @param password the JDBC connection pool database password. |
| * @param url the JDBC connection pool JDBC URL. |
| */ |
| private void jdbcConnectionPoolWriteFile( File file, String name, String driver, int increment, int initial, |
| int maximal, String user, String password, String url ) |
| throws ControllerException |
| { |
| LOGGER.info( "Writing the JBoss JDBC connection pool/datasource XML file" ); |
| InputStreamReader connectionPoolTemplate = null; |
| Object[] values = new Object[7]; |
| values[0] = name; |
| values[1] = driver; |
| values[2] = url; |
| values[3] = user; |
| values[4] = password; |
| values[5] = new Integer( initial ).toString(); |
| values[6] = new Integer( maximal ).toString(); |
| if ( StringUtils.containsIgnoreCase( driver, "xa" ) ) |
| { |
| LOGGER.debug( "XA connection pool detected" ); |
| connectionPoolTemplate = |
| new InputStreamReader( JBoss6Controller.class.getResourceAsStream( "/jboss/template-xa-ds.xml" ) ); |
| } |
| else |
| { |
| LOGGER.debug( "Non XA connection pool detected" ); |
| connectionPoolTemplate = |
| new InputStreamReader( JBoss6Controller.class.getResourceAsStream( "/jboss/template-ds.xml" ) ); |
| } |
| String connectionPoolContent = JBoss6Controller.format( connectionPoolTemplate, values ); |
| try |
| { |
| FileUtils.writeStringToFile( file, connectionPoolContent ); |
| } |
| catch ( IOException ioException ) |
| { |
| LOGGER.error( "Can't write JBoss JDBC connection pool descriptor file", ioException ); |
| throw new ControllerException( "Can't write JBoss JDBC connection pool descriptor file", ioException ); |
| } |
| } |
| |
| /** |
| * Format a JBoss configuration file template (JDBC connection |
| * pool/datasource, JMS connection factory, etc) with given values. |
| * |
| * @param templateReader the template reader. |
| * @param values the <code>Object[]</code> values. |
| * @return the formatted string. |
| */ |
| private static String format( Reader templateReader, Object[] values ) |
| throws ControllerException |
| { |
| try |
| { |
| BufferedReader templateBufferedReader = new BufferedReader( templateReader ); |
| StringWriter writer = new StringWriter(); |
| BufferedWriter buffer = new BufferedWriter( writer ); |
| String templateLine = templateBufferedReader.readLine(); |
| while ( templateLine != null ) |
| { |
| buffer.write( MessageFormat.format( templateLine, values ) ); |
| buffer.newLine(); |
| templateLine = templateBufferedReader.readLine(); |
| } |
| buffer.flush(); |
| return writer.toString(); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't format JBoss XML configuration file template", e ); |
| throw new ControllerException( "Can't format JBoss XML configuration file template", e ); |
| } |
| } |
| |
| /** |
| * Write a JBoss JMS connection factory XML file. |
| * |
| * @param file the JMS connection factory <code>File</code>. |
| * @param name the JMS connection factory name. |
| */ |
| private void jmsConnectionFactoryWriteFile( File file, String name ) |
| throws ControllerException |
| { |
| LOGGER.info( "Writing JBoss JMS connection factory XML file" ); |
| LOGGER.debug( "Constructing the replacement values" ); |
| InputStreamReader connectionFactoryTemplate = |
| new InputStreamReader( JBoss4Controller.class.getResourceAsStream( "/jboss/template-jms-ds.xml" ) ); |
| Object[] values = new Object[1]; |
| values[0] = name; |
| String connectionPoolContent = JBoss6Controller.format( connectionFactoryTemplate, values ); |
| try |
| { |
| FileUtils.writeStringToFile( file, connectionPoolContent ); |
| } |
| catch ( IOException ioException ) |
| { |
| LOGGER.error( "Can't write JBoss JMS connection factory descriptor file", ioException ); |
| throw new ControllerException( "Can't write JBoss JMS connection factory descriptor file", ioException ); |
| } |
| } |
| |
| /** |
| * Write a JBoss JMS queue service file from the template. |
| * |
| * @param file the target file. |
| * @param name the queue name. |
| * @throws ControllerException in case of writing failure. |
| */ |
| private void jmsQueueWriteFile( File file, String name ) |
| throws ControllerException |
| { |
| InputStreamReader jmsQueueTemplate = new InputStreamReader( |
| JBoss4Controller.class.getResourceAsStream( "/jboss/template-jms-queue-service.xml" ) ); |
| Object[] values = new Object[1]; |
| values[0] = name; |
| String jmsQueueContent = JBoss6Controller.format( jmsQueueTemplate, values ); |
| try |
| { |
| FileUtils.writeStringToFile( file, jmsQueueContent ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't write JBoss JMS queue service file", e ); |
| throw new ControllerException( "Can't write JBoss JMS queue service file", e ); |
| } |
| } |
| |
| /** |
| * Write a JBoss JMS topic service file from the template. |
| * |
| * @param file the target file. |
| * @param name the topic name. |
| * @throws ControllerException in case of writing failure. |
| */ |
| private void jmsTopicWriteFile( File file, String name ) |
| throws ControllerException |
| { |
| InputStreamReader jmsTopicTemplate = new InputStreamReader( |
| JBoss4Controller.class.getResourceAsStream( "/jboss/template-jms-topic-service.xml" ) ); |
| Object[] values = new Object[1]; |
| values[0] = name; |
| String jmsTopicContent = JBoss6Controller.format( jmsTopicTemplate, values ); |
| try |
| { |
| FileUtils.writeStringToFile( file, jmsTopicContent ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't write JBoss JMS topic service file.", e ); |
| throw new ControllerException( "Can't write JBoss JMS topic service file", e ); |
| } |
| } |
| |
| /** |
| * Write a JBoss JNDI alias service file. |
| * |
| * @param file the target service file. |
| * @param name the JNDI binding name. |
| * @param from the JNDI alias from name. |
| * @param to the JNDI alias to name. |
| * @throws ControllerException in case of file writing failure. |
| */ |
| private void jndiAliasWriteFile( File file, String name, String from, String to ) |
| throws ControllerException |
| { |
| InputStreamReader jmsQueueTemplate = new InputStreamReader( |
| JBoss4Controller.class.getResourceAsStream( "/jboss/template-jndi-alias-service.xml" ) ); |
| Object[] values = new Object[3]; |
| values[0] = name; |
| values[1] = from; |
| values[2] = to; |
| String jndiAliasContent = JBoss6Controller.format( jmsQueueTemplate, values ); |
| try |
| { |
| FileUtils.writeStringToFile( file, jndiAliasContent ); |
| } |
| catch ( Exception e ) |
| { |
| LOGGER.error( "Can't write JBoss JNDI binding service file", e ); |
| throw new ControllerException( "Can't write JBoss JNDI binding service file", e ); |
| } |
| } |
| |
| } |