blob: 8a3ff44170e88c2c484afc08d283083bb9f911ee [file] [log] [blame]
/*
* 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 );
}
}
}