You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kalumet-commits@incubator.apache.org by jb...@apache.org on 2011/12/08 18:37:45 UTC
svn commit: r1212024 - in /incubator/kalumet/trunk/controller/jboss: README
src/main/java/org/apache/kalumet/controller/jboss/JBoss6Controller.java
src/main/java/org/apache/kalumet/controller/jboss/JBossController.java
Author: jbonofre
Date: Thu Dec 8 18:37:45 2011
New Revision: 1212024
URL: http://svn.apache.org/viewvc?rev=1212024&view=rev
Log:
Add controller for JBoss 6.x
Added:
incubator/kalumet/trunk/controller/jboss/README
incubator/kalumet/trunk/controller/jboss/src/main/java/org/apache/kalumet/controller/jboss/JBoss6Controller.java
Removed:
incubator/kalumet/trunk/controller/jboss/src/main/java/org/apache/kalumet/controller/jboss/JBossController.java
Added: incubator/kalumet/trunk/controller/jboss/README
URL: http://svn.apache.org/viewvc/incubator/kalumet/trunk/controller/jboss/README?rev=1212024&view=auto
==============================================================================
--- incubator/kalumet/trunk/controller/jboss/README (added)
+++ incubator/kalumet/trunk/controller/jboss/README Thu Dec 8 18:37:45 2011
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+Apache Kalumet JBoss Controller
+===============================
+
+Apache Kalumet provides two JBoss controllers:
+- one for the JBoss 4.x version (which use the JBoss RMIAdaptor)
+- one for the JBoss 6.x
+
+ JBoss 4.x Controller Installation
+ ---------------------------------
+Copy the following jar file to <kalumet_agent_home>/lib/extras:
+ * <jboss_home>/client/jbossall-client.jar
+
+ JBoss 6.x Controller Installation
+ ---------------------------------
+Setup your JBoss application server to allow remote JMX connection.
+To do that in the bin/run.conf (on Unix) or bin/run.bat (on Windows), add:
+
+ JAVA_OPTS="$JAVA_OPTS -Djboss.platform.mbeanserver -Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl -Dcom.sun.management.jmxremote.port=myport -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="$JBOSS_HOME/lib/jboss-logmanager.jar
+
+NB: JBOSS_HOME should be defined and contains the absolute path to the jboss-logmanager.jar file.
+NB: replace myport by your port. This port will be used in the AutoDeploy Console in the JMX URL, which should looks like service:jmx:rmi:///jndi/rmi://host:myport/jmxrmi
+
Added: incubator/kalumet/trunk/controller/jboss/src/main/java/org/apache/kalumet/controller/jboss/JBoss6Controller.java
URL: http://svn.apache.org/viewvc/incubator/kalumet/trunk/controller/jboss/src/main/java/org/apache/kalumet/controller/jboss/JBoss6Controller.java?rev=1212024&view=auto
==============================================================================
--- incubator/kalumet/trunk/controller/jboss/src/main/java/org/apache/kalumet/controller/jboss/JBoss6Controller.java (added)
+++ incubator/kalumet/trunk/controller/jboss/src/main/java/org/apache/kalumet/controller/jboss/JBoss6Controller.java Thu Dec 8 18:37:45 2011
@@ -0,0 +1,945 @@
+/*
+ * 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.AbstractJ2EEApplicationServerController;
+import org.apache.kalumet.controller.core.ControllerException;
+import org.jboss.mx.util.propertyeditor.ObjectNameEditor;
+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.*;
+import java.lang.reflect.MalformedParameterizedTypeException;
+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 AbstractJ2EEApplicationServerController {
+
+ 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 = ((String) server.getAttribute(serverConfigMBean, "ServerHomeLocation")) + "/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 J2EE 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 isJ2EEApplicationDeployed(String path, String name) throws ControllerException {
+ LOGGER.info("Checking if J2EE 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 J2EE application {} is deployed", name, e);
+ throw new ControllerException("Can't check if J2EE application " + name + " is deployed", e);
+ } finally {
+ if (connector != null) {
+ try {
+ connector.close();
+ } catch (Exception e) {
+ // nothing to do
+ }
+ }
+ }
+ return deployed;
+ }
+
+ public void deployJ2EEApplication(String path, String name, String classloaderorder, String classloaderpolicy, String vhost) throws ControllerException {
+ LOGGER.info("Deploying J2EE 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 J2EE application {}", name, e);
+ throw new ControllerException("Can't deploy J2EE application " + name, e);
+ } finally {
+ if (connector != null) {
+ try {
+ connector.close();
+ } catch (Exception e) {
+ // nothing to do
+ }
+ }
+ }
+ }
+
+ public void undeployJ2EEApplication(String path, String name) throws ControllerException {
+ LOGGER.info("Undeploying J2EE 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 J2EE application {}", name, e);
+ throw new ControllerException("Can't undeploy J2EE application " + name, e);
+ } finally {
+ if (connector != null) {
+ try {
+ connector.close();
+ } catch (Exception e) {
+ // nothing to do
+ }
+ }
+ }
+ }
+
+ public void redeployJ2EEApplication(String path, String name) throws ControllerException {
+ LOGGER.info("Redeploying J2EE 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 J2EE application {}", name, e);
+ throw new ControllerException("Can't redeploy J2EE 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 = FileManipulator.getInstance();
+ 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);
+ }
+ }
+
+}