[rhq] Branch 'rhq-on-as7' - .classpath modules/enterprise
mazz
mazz at fedoraproject.org
Tue Aug 7 06:54:13 UTC 2012
.classpath | 1
modules/enterprise/gui/installer/pom.xml | 8
modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClient.java | 232 +++++++++
modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/JBossASClient.java | 17
modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java | 3
modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/client/gwt/InstallerGWTService.java | 9
modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/InstallerGWTServiceImpl.java | 165 +++---
modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/ServerInstallUtil.java | 238 ++++++++++
modules/enterprise/gui/installer/src/test/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClientTest.java | 112 ++++
9 files changed, 712 insertions(+), 73 deletions(-)
New commits:
commit c0241073ca53f3444a727037d376f33536252359
Author: John Mazzitelli <mazz at redhat.com>
Date: Tue Aug 7 02:54:10 2012 -0400
installer now completely deploys datasources and everything they need (security domain, and child connection properties)
diff --git a/.classpath b/.classpath
index 44bf71a..e67c6a5 100644
--- a/.classpath
+++ b/.classpath
@@ -50,6 +50,7 @@
<classpathentry kind="src" path="modules/enterprise/gui/portal-war/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/installer-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/installer/src/main/java"/>
+ <classpathentry kind="src" path="modules/enterprise/gui/installer/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/installer/target/generated-sources/gwt"/>
<classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/content_http-war/src/main/java"/>
diff --git a/modules/enterprise/gui/installer/pom.xml b/modules/enterprise/gui/installer/pom.xml
index 131e893..a48d2b9 100644
--- a/modules/enterprise/gui/installer/pom.xml
+++ b/modules/enterprise/gui/installer/pom.xml
@@ -160,6 +160,14 @@
<scope>provided</scope> <!-- provided by AS7 -->
</dependency>
+ <!-- test deps -->
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.9.0</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<build>
diff --git a/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClient.java b/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClient.java
index fb3135c..5831b38 100644
--- a/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClient.java
+++ b/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClient.java
@@ -18,7 +18,11 @@
*/
package org.rhq.common.jbossas.client.controller;
+import java.util.List;
+import java.util.Map;
+
import org.jboss.as.controller.client.ModelControllerClient;
+import org.jboss.dmr.ModelNode;
/**
* Provides convienence methods associated with datasource management.
@@ -27,8 +31,236 @@ import org.jboss.as.controller.client.ModelControllerClient;
*/
public class DatasourceJBossASClient extends JBossASClient {
+ public static final String SUBSYSTEM_DATASOURCES = "datasources";
+ public static final String DATA_SOURCE = "data-source";
+ public static final String XA_DATA_SOURCE = "xa-data-source";
+ public static final String JDBC_DRIVER = "jdbc-driver";
+ public static final String CONNECTION_PROPERTIES = "connection-properties";
+ public static final String XA_DATASOURCE_PROPERTIES = "xa-datasource-properties";
+
public DatasourceJBossASClient(ModelControllerClient client) {
super(client);
}
+ /**
+ * Checks to see if there is already a JDBC driver with the given name.
+ *
+ * @param jdbcDriverName the name to check
+ * @return true if there is a JDBC driver with the given name already in existence
+ */
+ public boolean isJDBCDriver(String jdbcDriverName) throws Exception {
+ Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_DATASOURCES);
+ ModelNode queryNode = createRequest(READ_RESOURCE, addr);
+ ModelNode results = execute(queryNode);
+ if (isSuccess(results)) {
+ ModelNode drivers = getResults(results).get(JDBC_DRIVER);
+ List<ModelNode> list = drivers.asList();
+ for (ModelNode driver : list) {
+ if (driver.has(jdbcDriverName)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ throw new FailureException(results, "Failed to get JDBC drivers");
+ }
+ }
+
+ /**
+ * Returns a ModelNode that can be used to create a JDBC driver configuration for use by datasources.
+ * Callers are free to tweek the JDBC driver request that is returned,
+ * if they so choose, before asking the client to execute the request.
+ *
+ * NOTE: the JDBC module must have already been installed in the JBossAS's modules/ location.
+ *
+ * @param name the name of the JDBC driver (this is not the name of the JDBC jar or the module name, it is
+ * just a convienence name of the JDBC driver configuration).
+ * @param moduleName the name of the JBossAS module where the JDBC driver is installed
+ * @param driverXaClassName the JDBC driver's XA datasource classname
+ *
+ * @return the request to create the JDBC driver configuration.
+ */
+ public ModelNode createNewJdbcDriverRequest(String name, String moduleName, String driverXaClassName) {
+ String dmrTemplate = "" //
+ + "{" //
+ + "\"driver-module-name\" => \"%s\" " //
+ + ", \"driver-xa-datasource-class-name\" => \"%s\" " //
+ + "}";
+
+ String dmr = String.format(dmrTemplate, moduleName, driverXaClassName);
+
+ Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_DATASOURCES, JDBC_DRIVER, name);
+ final ModelNode request = ModelNode.fromString(dmr);
+ request.get(OPERATION).set(ADD);
+ request.get(ADDRESS).set(addr.getAddressNode());
+
+ return request;
+ }
+
+ /**
+ * Returns a ModelNode that can be used to create a datasource.
+ * Callers are free to tweek the datasource request that is returned,
+ * if they so choose, before asking the client to execute the request.
+ *
+ * @param name
+ * @param blockingTimeoutWaitMillis
+ * @param connectionUrlExpression
+ * @param driverName
+ * @param exceptionSorterClassName
+ * @param idleTimeoutMinutes
+ * @param jta true if this DS should support transactions; false if not
+ * @param minPoolSize
+ * @param maxPoolSize
+ * @param preparedStatementCacheSize
+ * @param securityDomain
+ * @param staleConnectionCheckerClassName
+ * @param transactionIsolation
+ * @param validConnectionCheckerClassName
+ * @param connectionProperties
+ *
+ * @return the request that can be used to create the datasource
+ */
+ public ModelNode createNewDatasourceRequest(String name, int blockingTimeoutWaitMillis,
+ String connectionUrlExpression, String driverName, String exceptionSorterClassName, int idleTimeoutMinutes,
+ boolean jta, int minPoolSize, int maxPoolSize, int preparedStatementCacheSize, String securityDomain,
+ String staleConnectionCheckerClassName, String transactionIsolation, String validConnectionCheckerClassName,
+ Map<String, String> connectionProperties) {
+
+ String jndiName = "java:jboss/datasources/" + name;
+
+ String dmrTemplate = "" //
+ + "{" //
+ + "\"blocking-timeout-wait-millis\" => %dL " //
+ + ", \"connection-url\" => expression \"%s\" " //
+ + ", \"driver-name\" => \"%s\" " //
+ + ", \"exception-sorter-class-name\" => \"%s\" " //
+ + ", \"idle-timeout-minutes\" => %dL " //
+ + ", \"jndi-name\" => \"%s\" " //
+ + ", \"jta\" => %s " //
+ + ", \"min-pool-size\" => %d " //
+ + ", \"max-pool-size\" => %d " //
+ + ", \"prepared-statements-cache-size\" => %dL " //
+ + ", \"security-domain\" => \"%s\" " //
+ + ", \"stale-connection-checker-class-name\" => \"%s\" " //
+ + ", \"transaction-isolation\" => \"%s\" " //
+ + ", \"use-java-context\" => true " //
+ + ", \"valid-connection-checker-class-name\" => \"%s\" " //
+ + "}";
+
+ String dmr = String.format(dmrTemplate, blockingTimeoutWaitMillis, connectionUrlExpression, driverName,
+ exceptionSorterClassName, idleTimeoutMinutes, jndiName, jta, minPoolSize, maxPoolSize,
+ preparedStatementCacheSize, securityDomain, staleConnectionCheckerClassName, transactionIsolation,
+ validConnectionCheckerClassName);
+
+ Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_DATASOURCES, DATA_SOURCE, name);
+ final ModelNode request1 = ModelNode.fromString(dmr);
+ request1.get(OPERATION).set(ADD);
+ request1.get(ADDRESS).set(addr.getAddressNode());
+
+ // if there are no conn properties, no need to create a batch request, there is only one ADD request to make
+ if (connectionProperties == null || connectionProperties.size() == 0) {
+ return request1;
+ }
+
+ // create a batch of requests - the first is the main one, the rest create each conn property
+ ModelNode[] batch = new ModelNode[1 + connectionProperties.size()];
+ batch[0] = request1;
+ int n = 1;
+ for (Map.Entry<String, String> entry : connectionProperties.entrySet()) {
+ addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_DATASOURCES, DATA_SOURCE, name, CONNECTION_PROPERTIES,
+ entry.getKey());
+ final ModelNode requestN = new ModelNode();
+ requestN.get(OPERATION).set(ADD);
+ requestN.get(ADDRESS).set(addr.getAddressNode());
+ if (entry.getValue().indexOf("${") > -1) {
+ requestN.get(VALUE).setExpression(entry.getValue());
+ } else {
+ requestN.get(VALUE).set(entry.getValue());
+ }
+ batch[n++] = requestN;
+ }
+
+ return createBatchRequest(batch);
+ }
+
+ /**
+ * Returns a ModelNode that can be used to create an XA datasource.
+ * Callers are free to tweek the datasource request that is returned,
+ * if they so choose, before asking the client to execute the request.
+ *
+ * @param name
+ * @param blockingTimeoutWaitMillis
+ * @param driverName
+ * @param exceptionSorterClassName
+ * @param idleTimeoutMinutes
+ * @param minPoolSize
+ * @param maxPoolSize
+ * @param preparedStatementCacheSize
+ * @param securityDomain
+ * @param staleConnectionCheckerClassName
+ * @param transactionIsolation
+ * @param validConnectionCheckerClassName
+ * @param xaDatasourceProperties
+ *
+ * @return the request that can be used to create the XA datasource
+ */
+ public ModelNode createNewXADatasourceRequest(String name, int blockingTimeoutWaitMillis, String driverName,
+ String exceptionSorterClassName, int idleTimeoutMinutes, int minPoolSize, int maxPoolSize,
+ int preparedStatementCacheSize, String securityDomain, String staleConnectionCheckerClassName,
+ String transactionIsolation, String validConnectionCheckerClassName, Map<String, String> xaDatasourceProperties) {
+
+ String jndiName = "java:jboss/datasources/" + name;
+
+ String dmrTemplate = "" //
+ + "{" //
+ + "\"blocking-timeout-wait-millis\" => %dL " //
+ + ", \"driver-name\" => \"%s\" " //
+ + ", \"exception-sorter-class-name\" => \"%s\" " //
+ + ", \"idle-timeout-minutes\" => %dL " //
+ + ", \"jndi-name\" => \"%s\" " //
+ + ", \"jta\" => true " //
+ + ", \"min-pool-size\" => %d " //
+ + ", \"max-pool-size\" => %d " //
+ + ", \"prepared-statements-cache-size\" => %dL " //
+ + ", \"security-domain\" => \"%s\" " //
+ + ", \"stale-connection-checker-class-name\" => \"%s\" " //
+ + ", \"transaction-isolation\" => \"%s\" " //
+ + ", \"use-java-context\" => true " //
+ + ", \"valid-connection-checker-class-name\" => \"%s\" " //
+ + "}";
+
+ String dmr = String.format(dmrTemplate, blockingTimeoutWaitMillis, driverName, exceptionSorterClassName,
+ idleTimeoutMinutes, jndiName, minPoolSize, maxPoolSize, preparedStatementCacheSize, securityDomain,
+ staleConnectionCheckerClassName, transactionIsolation, validConnectionCheckerClassName);
+
+ Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_DATASOURCES, XA_DATA_SOURCE, name);
+ final ModelNode request1 = ModelNode.fromString(dmr);
+ request1.get(OPERATION).set(ADD);
+ request1.get(ADDRESS).set(addr.getAddressNode());
+
+ // if there are no xa datasource properties, no need to create a batch request, there is only one ADD request to make
+ if (xaDatasourceProperties == null || xaDatasourceProperties.size() == 0) {
+ return request1;
+ }
+
+ // create a batch of requests - the first is the main one, the rest create each conn property
+ ModelNode[] batch = new ModelNode[1 + xaDatasourceProperties.size()];
+ batch[0] = request1;
+ int n = 1;
+ for (Map.Entry<String, String> entry : xaDatasourceProperties.entrySet()) {
+ addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_DATASOURCES, XA_DATA_SOURCE, name, XA_DATASOURCE_PROPERTIES,
+ entry.getKey());
+ final ModelNode requestN = new ModelNode();
+ requestN.get(OPERATION).set(ADD);
+ requestN.get(ADDRESS).set(addr.getAddressNode());
+ if (entry.getValue().indexOf("${") > -1) {
+ requestN.get(VALUE).setExpression(entry.getValue());
+ } else {
+ requestN.get(VALUE).set(entry.getValue());
+ }
+ batch[n++] = requestN;
+ }
+
+ return createBatchRequest(batch);
+ }
}
diff --git a/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/JBossASClient.java b/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/JBossASClient.java
index c8d040c..576e2d6 100644
--- a/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/JBossASClient.java
+++ b/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/JBossASClient.java
@@ -54,6 +54,7 @@ public class JBossASClient {
public static final String READ_RESOURCE = "read-resource";
public static final String WRITE_ATTRIBUTE = "write-attribute";
public static final String ADD = "add";
+ public static final String SYSTEM_PROPERTY = "system-property";
private ModelControllerClient client;
@@ -301,4 +302,20 @@ public class JBossASClient {
+ "]");
}
}
+
+ /**
+ * Can set a runtime system property in the JVM.
+ *
+ * @param name
+ * @param value
+ * @throws Exception
+ */
+ public void setSystemProperty(String name, String value) throws Exception {
+ ModelNode request = createRequest(ADD, Address.root().add(SYSTEM_PROPERTY, name));
+ request.get(VALUE).set(value);
+ ModelNode response = execute(request);
+ if (!isSuccess(response)) {
+ throw new FailureException(response, "Failed to set system property [" + name + "]");
+ }
+ }
}
diff --git a/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java b/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java
index a73ba79..6f0589f 100644
--- a/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java
+++ b/modules/enterprise/gui/installer/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java
@@ -95,6 +95,9 @@ public class SecurityDomainJBossASClient extends JBossASClient {
loginModule.get(FLAG).set("required");
ModelNode moduleOptions = loginModule.get(MODULE_OPTIONS);
moduleOptions.setEmptyList();
+ // TODO: we really want to use addExpression (e.g. ${rhq.server.database.user-name})
+ // for username and password so rhq-server.properties can be used to set these.
+ // However, AS7.1 doesn't support this yet - see https://issues.jboss.org/browse/AS7-5177
moduleOptions.add(USERNAME, username);
moduleOptions.add(PASSWORD, password);
loginModulesNode.add(loginModule);
diff --git a/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/client/gwt/InstallerGWTService.java b/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/client/gwt/InstallerGWTService.java
index 97e776e..b640b61 100644
--- a/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/client/gwt/InstallerGWTService.java
+++ b/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/client/gwt/InstallerGWTService.java
@@ -102,6 +102,15 @@ public interface InstallerGWTService extends RemoteService {
HashMap<String, String> getServerProperties() throws Exception;
/**
+ * Allows the installer to set runtime system properties in the JBossAS app server container.
+ *
+ * @param name the name of the sysprop to set
+ * @param value the value of the sysprop to set
+ * @throws Exception
+ */
+ void setSystemProperty(String name, String value) throws Exception;
+
+ /**
* Returns the version string for the app server itself (e.g. "7.1.2.Final").
* @return version string of app server
* @throws Exception
diff --git a/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/InstallerGWTServiceImpl.java b/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/InstallerGWTServiceImpl.java
index fcc8a51..afd5a3f 100644
--- a/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/InstallerGWTServiceImpl.java
+++ b/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/InstallerGWTServiceImpl.java
@@ -35,7 +35,6 @@ import org.jboss.as.controller.client.ModelControllerClient;
import org.rhq.common.jbossas.client.controller.Address;
import org.rhq.common.jbossas.client.controller.JBossASClient;
-import org.rhq.common.jbossas.client.controller.SecurityDomainJBossASClient;
import org.rhq.core.db.DatabaseTypeFactory;
import org.rhq.core.util.PropertiesFileUpdate;
import org.rhq.core.util.exception.ThrowableUtil;
@@ -44,6 +43,7 @@ import org.rhq.enterprise.gui.installer.client.shared.ServerDetails;
import org.rhq.enterprise.gui.installer.client.shared.ServerProperties;
import org.rhq.enterprise.gui.installer.server.service.ManagementService;
import org.rhq.enterprise.gui.installer.server.servlet.ServerInstallUtil.ExistingSchemaOption;
+import org.rhq.enterprise.gui.installer.server.servlet.ServerInstallUtil.SupportedDatabaseType;
/**
* Remote RPC API implementation for the GWT Installer.
@@ -55,21 +55,21 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
private static final long serialVersionUID = 1L;
- private static final String RHQ_SECURITY_DOMAIN = "RHQDSSecurityDomain";
-
@Override
- public void install(HashMap<String, String> serverProperties, ServerDetails serverDetails, String existingSchemaOption) throws Exception {
+ public void install(HashMap<String, String> serverProperties, ServerDetails serverDetails,
+ String existingSchemaOption) throws Exception {
+
// make sure the data is at least in the correct format (booleans are true/false, integers are valid numbers)
- StringBuilder dataErrors = new StringBuilder();
+ final StringBuilder dataErrors = new StringBuilder();
for (Map.Entry<String, String> entry : serverProperties.entrySet()) {
- String name = entry.getKey();
+ final String name = entry.getKey();
if (ServerProperties.BOOLEAN_PROPERTIES.contains(name)) {
- String newValue = entry.getValue();
+ final String newValue = entry.getValue();
if (!(newValue.equals("true") || newValue.equals("false"))) {
dataErrors.append("[" + name + "] must be 'true' or 'false' : [" + newValue + "]\n");
}
} else if (ServerProperties.INTEGER_PROPERTIES.contains(name)) {
- String newValue = entry.getValue();
+ final String newValue = entry.getValue();
try {
Integer.parseInt(newValue);
} catch (NumberFormatException e) {
@@ -87,7 +87,7 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
// if we are in auto-install mode, ignore the server details passed in and build our own using the given server properties
// if not in auto-install mode, make sure user gave us the server details that we will need
- boolean autoInstallMode = ServerInstallUtil.isAutoinstallEnabled(serverProperties);
+ final boolean autoInstallMode = ServerInstallUtil.isAutoinstallEnabled(serverProperties);
if (autoInstallMode) {
serverDetails = getServerDetailsFromPropertiesOnly(serverProperties);
} else {
@@ -107,35 +107,33 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
DatabaseTypeFactory.clearDatabaseTypeCache();
// determine the type of database to connect to
- String databaseType = serverProperties.get(ServerProperties.PROP_DATABASE_TYPE);
+ final String databaseType = serverProperties.get(ServerProperties.PROP_DATABASE_TYPE);
if (ServerInstallUtil.isEmpty(databaseType)) {
throw new Exception("Please indicate the type of database to connect to");
}
- boolean isPostgres = databaseType.toLowerCase().indexOf("postgres") > -1;
- boolean isOracle = databaseType.toLowerCase().indexOf("oracle") > -1;
-
- if (isPostgres == false && isOracle == false) {
+ SupportedDatabaseType supportedDbType = ServerInstallUtil.getSupportedDatabaseType(databaseType);
+ if (supportedDbType == null) {
throw new IllegalArgumentException("Invalid database type: " + databaseType);
}
// parse the database connection URL to extract the servername/port/dbname; this is needed for the XA datasource
try {
- String url = serverProperties.get(ServerProperties.PROP_DATABASE_CONNECTION_URL);
+ final String url = serverProperties.get(ServerProperties.PROP_DATABASE_CONNECTION_URL);
Pattern pattern = null;
- if (isPostgres) {
+ if (supportedDbType == SupportedDatabaseType.POSTGRES) {
pattern = Pattern.compile(".*://(.*):([0123456789]+)/(.*)"); // jdbc:postgresql://host.name:5432/rhq
- } else if (isOracle) {
+ } else if (supportedDbType == SupportedDatabaseType.ORACLE) {
// if we ever find that we'll need these props set, uncomment below and it should all work
//pattern = Pattern.compile(".*@(.*):([0123456789]+)[:/](.*)"); // jdbc:oracle:thin:@host.name:1521:rhq (or /rhq)
}
if (pattern != null) {
- Matcher match = pattern.matcher(url);
+ final Matcher match = pattern.matcher(url);
if (match.find() && (match.groupCount() == 3)) {
- String serverName = match.group(1);
- String port = match.group(2);
- String dbName = match.group(3);
+ final String serverName = match.group(1);
+ final String port = match.group(2);
+ final String dbName = match.group(3);
serverProperties.put(ServerProperties.PROP_DATABASE_SERVER_NAME, serverName);
serverProperties.put(ServerProperties.PROP_DATABASE_PORT, port);
serverProperties.put(ServerProperties.PROP_DATABASE_DB_NAME, dbName);
@@ -158,10 +156,10 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
String quartzSelectWithLockSQL = "SELECT * FROM {0}LOCKS ROWLOCK WHERE LOCK_NAME = ? FOR UPDATE";
String quartzLockHandlerClass = "org.quartz.impl.jdbcjobstore.StdRowLockSemaphore";
- if (isPostgres) {
+ if (supportedDbType == SupportedDatabaseType.POSTGRES) {
dialect = "org.hibernate.dialect.PostgreSQLDialect";
quartzDriverDelegateClass = "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate";
- } else if (isOracle) {
+ } else if (supportedDbType == SupportedDatabaseType.ORACLE) {
dialect = "org.hibernate.dialect.Oracle10gDialect";
quartzDriverDelegateClass = "org.quartz.impl.jdbcjobstore.oracle.OracleDelegate";
}
@@ -178,16 +176,19 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
// test the connection to make sure everything is OK - note that if we are in auto-install mode,
// the password will have been obfuscated, so we need to de-obfucate it in order to use it.
// make sure the server properties map itself has an obfuscated password
- String dbUrl = serverProperties.get(ServerProperties.PROP_DATABASE_CONNECTION_URL);
- String dbUsername = serverProperties.get(ServerProperties.PROP_DATABASE_USERNAME);
- String dbPassword = serverProperties.get(ServerProperties.PROP_DATABASE_PASSWORD);
+ final String dbUrl = serverProperties.get(ServerProperties.PROP_DATABASE_CONNECTION_URL);
+ final String dbUsername = serverProperties.get(ServerProperties.PROP_DATABASE_USERNAME);
+ String clearTextDbPassword;
+ String obfuscatedDbPassword;
if (autoInstallMode) {
- dbPassword = ServerInstallUtil.deobfuscatePassword(dbPassword);
+ obfuscatedDbPassword = serverProperties.get(ServerProperties.PROP_DATABASE_PASSWORD);
+ clearTextDbPassword = ServerInstallUtil.deobfuscatePassword(obfuscatedDbPassword);
} else {
- serverProperties.put(ServerProperties.PROP_DATABASE_PASSWORD,
- ServerInstallUtil.obfuscatePassword(dbPassword));
+ clearTextDbPassword = serverProperties.get(ServerProperties.PROP_DATABASE_PASSWORD);
+ obfuscatedDbPassword = ServerInstallUtil.obfuscatePassword(clearTextDbPassword);
+ serverProperties.put(ServerProperties.PROP_DATABASE_PASSWORD, obfuscatedDbPassword);
}
- String testConnectionErrorMessage = testConnection(dbUrl, dbUsername, dbPassword);
+ final String testConnectionErrorMessage = testConnection(dbUrl, dbUsername, clearTextDbPassword);
if (testConnectionErrorMessage != null) {
throw new Exception("Cannot connect to the database: " + testConnectionErrorMessage);
}
@@ -200,7 +201,7 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
// If in auto-install mode, we can be told to overwrite, skip or auto (meaning "keep" if schema exists)
ServerInstallUtil.ExistingSchemaOption existingSchemaOptionEnum;
if (autoInstallMode) {
- String s = serverProperties.get(ServerProperties.PROP_AUTOINSTALL_DATABASE);
+ final String s = serverProperties.get(ServerProperties.PROP_AUTOINSTALL_DATABASE);
if (s == null || s.equalsIgnoreCase("auto")) {
existingSchemaOptionEnum = ServerInstallUtil.ExistingSchemaOption.KEEP;
} else {
@@ -214,26 +215,30 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
}
if (ServerInstallUtil.ExistingSchemaOption.SKIP != existingSchemaOptionEnum) {
- if (isDatabaseSchemaExist(dbUrl, dbUsername, dbPassword)) {
+ if (isDatabaseSchemaExist(dbUrl, dbUsername, clearTextDbPassword)) {
if (ExistingSchemaOption.OVERWRITE == existingSchemaOptionEnum) {
- ServerInstallUtil.createNewDatabaseSchema(serverProperties, serverDetails, dbPassword, getLogDir());
- } else {
- ServerInstallUtil.upgradeExistingDatabaseSchema(serverProperties, serverDetails, dbPassword,
+ ServerInstallUtil.createNewDatabaseSchema(serverProperties, serverDetails, clearTextDbPassword,
getLogDir());
+ } else {
+ ServerInstallUtil.upgradeExistingDatabaseSchema(serverProperties, serverDetails,
+ clearTextDbPassword, getLogDir());
}
} else {
- ServerInstallUtil.createNewDatabaseSchema(serverProperties, serverDetails, dbPassword, getLogDir());
+ ServerInstallUtil.createNewDatabaseSchema(serverProperties, serverDetails, clearTextDbPassword,
+ getLogDir());
}
}
// ensure the server info is up to date and stored in the DB
- ServerInstallUtil.storeServerDetails(serverProperties, dbPassword, serverDetails);
+ ServerInstallUtil.storeServerDetails(serverProperties, clearTextDbPassword, serverDetails);
// create a keystore whose cert has a CN of this server's public endpoint address
ServerInstallUtil.createKeystore(serverDetails, getAppServerConfigDir());
// now create our deployment services and our main EAR
- // TODO: finish this
+ deployServices(serverProperties);
+
+ // TODO: deploy the EAR
return;
}
@@ -251,7 +256,7 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
public ServerDetails getServerDetails(String connectionUrl, String username, String password, String serverName)
throws Exception {
try {
- ServerDetails sd = ServerInstallUtil.getServerDetails(connectionUrl, username, password, serverName);
+ final ServerDetails sd = ServerInstallUtil.getServerDetails(connectionUrl, username, password, serverName);
if (ServerInstallUtil.isEmpty(sd.getName())) {
try {
sd.setEndpointAddress(InetAddress.getLocalHost().getCanonicalHostName());
@@ -285,18 +290,18 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
@Override
public String testConnection(String connectionUrl, String username, String password) throws Exception {
- String results = ServerInstallUtil.testConnection(connectionUrl, username, password);
+ final String results = ServerInstallUtil.testConnection(connectionUrl, username, password);
return results;
}
@Override
public HashMap<String, String> getServerProperties() throws Exception {
- File serverPropertiesFile = getServerPropertiesFile();
- PropertiesFileUpdate propsFile = new PropertiesFileUpdate(serverPropertiesFile.getAbsolutePath());
- Properties props = propsFile.loadExistingProperties();
+ final File serverPropertiesFile = getServerPropertiesFile();
+ final PropertiesFileUpdate propsFile = new PropertiesFileUpdate(serverPropertiesFile.getAbsolutePath());
+ final Properties props = propsFile.loadExistingProperties();
// force some hardcoded defaults for IBM JVMs that must have specific values
- boolean isIBM = System.getProperty("java.vendor", "").contains("IBM");
+ final boolean isIBM = System.getProperty("java.vendor", "").contains("IBM");
if (isIBM) {
for (String algPropName : ServerProperties.IBM_ALGOROTHM_SETTINGS) {
props.setProperty(algPropName, "IbmX509");
@@ -304,13 +309,22 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
}
// GWT can't handle Properties - convert to HashMap
- HashMap<String, String> map = new HashMap<String, String>(props.size());
+ final HashMap<String, String> map = new HashMap<String, String>(props.size());
for (Object property : props.keySet()) {
map.put(property.toString(), props.getProperty(property.toString()));
}
return map;
}
+ @Override
+ public void setSystemProperty(String name, String value) throws Exception {
+ try {
+ new JBossASClient(getClient()).setSystemProperty(name, value);
+ } catch (Exception e) {
+ throw new Exception(ThrowableUtil.getAllMessages(e));
+ }
+ }
+
/**
* Save the given properties to the server's .properties file.
*
@@ -322,11 +336,11 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
* @throws Exception if failed to save the properties to the .properties file
*/
private void saveServerProperties(HashMap<String, String> serverProperties) throws Exception {
- File serverPropertiesFile = getServerPropertiesFile();
- PropertiesFileUpdate propsFile = new PropertiesFileUpdate(serverPropertiesFile.getAbsolutePath());
+ final File serverPropertiesFile = getServerPropertiesFile();
+ final PropertiesFileUpdate propsFile = new PropertiesFileUpdate(serverPropertiesFile.getAbsolutePath());
// GWT can't handle Properties - so we use HashMap but convert to Properties internally
- Properties props = new Properties();
+ final Properties props = new Properties();
for (Map.Entry<String, String> entry : serverProperties.entrySet()) {
props.setProperty(entry.getKey(), entry.getValue());
}
@@ -336,7 +350,7 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
// we need to put them as system properties now so when we hot deploy,
// the replacement variables in the config files pick up the new values
for (Map.Entry<String, String> entry : serverProperties.entrySet()) {
- System.setProperty(entry.getKey(), entry.getValue());
+ setSystemProperty(entry.getKey(), entry.getValue());
}
return;
@@ -344,43 +358,43 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
@Override
public String getAppServerVersion() throws Exception {
- JBossASClient client = new JBossASClient(getClient());
- String version = client.getStringAttribute("release-version", Address.root());
+ final JBossASClient client = new JBossASClient(getClient());
+ final String version = client.getStringAttribute("release-version", Address.root());
return version;
}
@Override
public String getOperatingSystem() throws Exception {
- JBossASClient client = new JBossASClient(getClient());
- String[] address = { "core-service", "platform-mbean", "type", "operating-system" };
- String osName = client.getStringAttribute("name", Address.root().add(address));
+ final JBossASClient client = new JBossASClient(getClient());
+ final String[] address = { "core-service", "platform-mbean", "type", "operating-system" };
+ final String osName = client.getStringAttribute("name", Address.root().add(address));
return osName;
}
private String getAppServerHomeDir() throws Exception {
- JBossASClient client = new JBossASClient(getClient());
- String[] address = { "core-service", "server-environment" };
- String dir = client.getStringAttribute(true, "home-dir", Address.root().add(address));
+ final JBossASClient client = new JBossASClient(getClient());
+ final String[] address = { "core-service", "server-environment" };
+ final String dir = client.getStringAttribute(true, "home-dir", Address.root().add(address));
return dir;
}
private String getAppServerConfigDir() throws Exception {
- JBossASClient client = new JBossASClient(getClient());
- String[] address = { "core-service", "server-environment" };
- String dir = client.getStringAttribute(true, "config-dir", Address.root().add(address));
+ final JBossASClient client = new JBossASClient(getClient());
+ final String[] address = { "core-service", "server-environment" };
+ final String dir = client.getStringAttribute(true, "config-dir", Address.root().add(address));
return dir;
}
private String getLogDir() throws Exception {
- File asHomeDir = new File(getAppServerHomeDir());
- File logDir = new File(asHomeDir, "../logs"); // this is RHQ's log dir, not JBossAS's log dir
+ final File asHomeDir = new File(getAppServerHomeDir());
+ final File logDir = new File(asHomeDir, "../logs"); // this is RHQ's log dir, not JBossAS's log dir
logDir.mkdirs(); // create it in case it doesn't yet exist
return logDir.getAbsolutePath();
}
private File getServerPropertiesFile() throws Exception {
- File appServerHomeDir = new File(getAppServerHomeDir());
- File serverPropertiesFile = new File(appServerHomeDir, "../bin/rhq-server.properties");
+ final File appServerHomeDir = new File(getAppServerHomeDir());
+ final File serverPropertiesFile = new File(appServerHomeDir, "../bin/rhq-server.properties");
return serverPropertiesFile;
}
@@ -470,18 +484,23 @@ public class InstallerGWTServiceImpl extends RemoteServiceServlet implements Ins
}
private ModelControllerClient getClient() {
- ModelControllerClient client = ManagementService.getClient();
+ final ModelControllerClient client = ManagementService.getClient();
return client;
}
- private void createDatasourceSecurityDomain(String username, String password) throws Exception {
- final SecurityDomainJBossASClient client = new SecurityDomainJBossASClient(getClient());
- final String securityDomain = RHQ_SECURITY_DOMAIN;
- if (!client.isSecurityDomain(securityDomain)) {
- client.createNewSecureIdentitySecurityDomainRequest(securityDomain, username, password);
- log("Security domain [" + securityDomain + "] created");
- } else {
- log("Security domain [" + securityDomain + "] already exists, skipping the creation request");
+ private void deployServices(HashMap<String, String> serverProperties) throws Exception {
+ try {
+ // create the security domain needed by the datasources
+ ServerInstallUtil.createDatasourceSecurityDomain(getClient(), serverProperties);
+
+ // create the JDBC driver configurations for use by datasources
+ ServerInstallUtil.createNewJdbcDrivers(getClient(), serverProperties);
+
+ // create the datasources
+ ServerInstallUtil.createNewDatasources(getClient(), serverProperties);
+ } catch (Exception e) {
+ log("deployServices failed", e);
+ throw new Exception("Failed to deploy services: " + ThrowableUtil.getAllMessages(e));
}
}
}
diff --git a/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/ServerInstallUtil.java b/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/ServerInstallUtil.java
index 15ed1a7..b4c8bef 100644
--- a/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/ServerInstallUtil.java
+++ b/modules/enterprise/gui/installer/src/main/java/org/rhq/enterprise/gui/installer/server/servlet/ServerInstallUtil.java
@@ -42,6 +42,13 @@ import org.apache.commons.logging.LogFactory;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.helper.ProjectHelper2;
+import org.jboss.as.controller.client.ModelControllerClient;
+import org.jboss.dmr.ModelNode;
+
+import org.rhq.common.jbossas.client.controller.DatasourceJBossASClient;
+import org.rhq.common.jbossas.client.controller.FailureException;
+import org.rhq.common.jbossas.client.controller.JBossASClient;
+import org.rhq.common.jbossas.client.controller.SecurityDomainJBossASClient;
import org.rhq.core.db.DatabaseType;
import org.rhq.core.db.DatabaseTypeFactory;
import org.rhq.core.db.DbUtil;
@@ -66,6 +73,236 @@ public class ServerInstallUtil {
OVERWRITE, KEEP, SKIP
};
+ public enum SupportedDatabaseType {
+ POSTGRES, ORACLE
+ };
+
+ private static final String RHQ_DATASOURCE_NAME_NOTX = "NoTxRHQDS";
+ private static final String RHQ_DATASOURCE_NAME_XA = "RHQDS";
+ private static final String RHQ_SECURITY_DOMAIN = "RHQDSSecurityDomain";
+ private static final String JDBC_DRIVER_POSTGRES = "postgres";
+ private static final String JDBC_DRIVER_ORACLE = "oracle";
+
+ /**
+ * Give the server properties, this returns the type of database that will be connected to.
+ *
+ * @param serverProperties
+ * @return the type of DB
+ */
+ public static SupportedDatabaseType getSupportedDatabaseType(HashMap<String, String> serverProperties) {
+ return getSupportedDatabaseType(serverProperties.get(ServerProperties.PROP_DATABASE_TYPE));
+ }
+
+ /**
+ * Give the database type string, this returns the type of database that it refers to.
+ *
+ * @param dbType the database type string
+ * @return the type of DB
+ */
+ public static SupportedDatabaseType getSupportedDatabaseType(String dbType) {
+ if (dbType == null) {
+ return null;
+ }
+ if (dbType.toLowerCase().indexOf("postgres") > -1) {
+ return SupportedDatabaseType.POSTGRES;
+ } else if (dbType.toLowerCase().indexOf("oracle") > -1) {
+ return SupportedDatabaseType.ORACLE;
+ }
+ return null;
+ }
+
+ /**
+ * Creates the security domain for the datasources. This is needed to support
+ * obfuscation of the password in the configuration file.
+ *
+ * @param mcc the JBossAS management client
+ * @param serverProperties contains the obfuscated password to store in the security domain
+ * @throws Exception
+ */
+ public static void createDatasourceSecurityDomain(ModelControllerClient mcc,
+ HashMap<String, String> serverProperties) throws Exception {
+
+ final String dbUsername = serverProperties.get(ServerProperties.PROP_DATABASE_USERNAME);
+ final String obfuscatedPassword = serverProperties.get(ServerProperties.PROP_DATABASE_PASSWORD);
+ final SecurityDomainJBossASClient client = new SecurityDomainJBossASClient(mcc);
+ final String securityDomain = RHQ_SECURITY_DOMAIN;
+ if (!client.isSecurityDomain(securityDomain)) {
+ client.createNewSecureIdentitySecurityDomainRequest(securityDomain, dbUsername, obfuscatedPassword);
+ LOG.info("Security domain [" + securityDomain + "] created");
+ } else {
+ LOG.info("Security domain [" + securityDomain + "] already exists, skipping the creation request");
+ }
+ }
+
+ /**
+ * Creates JDBC driver configurations so the datasources can properly connect to the backend databases.
+ * This will attempt to create drivers for all supported databases, not just for the database type that
+ * is currently configured.
+ *
+ * @param mcc
+ * @param serverProperties
+ * @throws Exception
+ */
+ public static void createNewJdbcDrivers(ModelControllerClient mcc, HashMap<String, String> serverProperties)
+ throws Exception {
+
+ final DatasourceJBossASClient client = new DatasourceJBossASClient(mcc);
+
+ final ModelNode postgresDriverRequest = client.createNewJdbcDriverRequest(JDBC_DRIVER_POSTGRES,
+ "org.rhq.postgres", "org.postgresql.xa.PGXADataSource");
+ final ModelNode oracleDriverRequest = client.createNewJdbcDriverRequest(JDBC_DRIVER_ORACLE, "org.rhq.oracle",
+ "oracle.jdbc.xa.client.OracleXADataSource");
+
+ // if we are to use Oracle, we throw an exception if we can't create the Oracle datasource. We also try to
+ // create the Postgres datasource but because it isn't needed, we don't throw exceptions if that fails, we
+ // just log a warning.
+ // The reverse is true if we are to use Postgres (that is, we ensure Postgres driver is created, but not Oracle).
+ ModelNode results;
+ final SupportedDatabaseType supportedDbType = getSupportedDatabaseType(serverProperties);
+ switch (supportedDbType) {
+ case POSTGRES: {
+ if (client.isJDBCDriver(JDBC_DRIVER_POSTGRES)) {
+ LOG.info("Postgres JDBC driver is already deployed");
+ } else {
+ results = client.execute(postgresDriverRequest);
+ if (!DatasourceJBossASClient.isSuccess(results)) {
+ throw new FailureException(results, "Failed to create postgres database driver");
+ } else {
+ LOG.info("Deployed Postgres JDBC driver");
+ }
+ }
+
+ if (client.isJDBCDriver(JDBC_DRIVER_ORACLE)) {
+ LOG.info("Oracle JDBC driver is already deployed");
+ } else {
+ results = client.execute(oracleDriverRequest);
+ if (!DatasourceJBossASClient.isSuccess(results)) {
+ LOG.warn("Could not create Oracle JDBC Driver - you will not be able to switch to an Oracle DB later: "
+ + JBossASClient.getFailureDescription(results));
+ } else {
+ LOG.info("Deployed Oracle JDBC driver for future use");
+ }
+ }
+ break;
+ }
+ case ORACLE: {
+ if (client.isJDBCDriver(JDBC_DRIVER_ORACLE)) {
+ LOG.info("Oracle JDBC driver is already deployed");
+ } else {
+ results = client.execute(oracleDriverRequest);
+ if (!DatasourceJBossASClient.isSuccess(results)) {
+ throw new FailureException(results, "Failed to create oracle database driver");
+ } else {
+ LOG.info("Deployed Oracle JDBC driver");
+ }
+ }
+ if (client.isJDBCDriver(JDBC_DRIVER_POSTGRES)) {
+ LOG.info("Postgres JDBC driver is already deployed");
+ } else {
+ results = client.execute(postgresDriverRequest);
+ if (!DatasourceJBossASClient.isSuccess(results)) {
+ LOG.warn("Could not create Postgres JDBC Driver - you will not be able to switch to a Postgres DB later: "
+ + JBossASClient.getFailureDescription(results));
+ } else {
+ LOG.info("Deployed Postgres JDBC driver for future use");
+ }
+ }
+ break;
+ }
+ default:
+ throw new RuntimeException("bad db type"); // this should never happen; should have never gotten to this point with a bad type
+ }
+
+ }
+
+ /**
+ * Creates the datasources needed by the RHQ Server.
+ *
+ * @param mcc the JBossAS management client
+ * @param serverProperties properties to help determine the properties of the datasources to be created
+ * @throws Exception
+ */
+ public static void createNewDatasources(ModelControllerClient mcc, HashMap<String, String> serverProperties)
+ throws Exception {
+
+ final SupportedDatabaseType supportedDbType = getSupportedDatabaseType(serverProperties);
+ switch (supportedDbType) {
+ case POSTGRES: {
+ createNewDatasources_Postgres(mcc);
+ break;
+ }
+ case ORACLE: {
+ createNewDatasources_Oracle(mcc);
+ break;
+ }
+ default:
+ throw new RuntimeException("bad db type"); // this should never happen; should have never gotten to this point with a bad type
+ }
+
+ LOG.info("Created datasources");
+ }
+
+ private static void createNewDatasources_Postgres(ModelControllerClient mcc) throws Exception {
+ final HashMap<String, String> props = new HashMap<String, String>(4);
+ final DatasourceJBossASClient client = new DatasourceJBossASClient(mcc);
+
+ props.put("char.encoding", "UTF-8");
+
+ ModelNode noTxDsRequest = client.createNewDatasourceRequest(RHQ_DATASOURCE_NAME_NOTX, 30000,
+ "${rhq.server.database.connection-url:jdbc:postgres://127.0.0.1:5432/rhq}", JDBC_DRIVER_POSTGRES,
+ "org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter", 15, false, 2, 5, 75,
+ RHQ_SECURITY_DOMAIN, "-unused-stale-conn-checker-", "TRANSACTION_READ_COMMITTED",
+ "org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker", props);
+ noTxDsRequest.remove("stale-connection-checker-class-name"); // we don't have one of these for postgres
+
+ props.clear();
+ props.put("ServerName", "${rhq.server.database.server-name:127.0.0.1}");
+ props.put("PortNumber", "${rhq.server.database.port:5432}");
+ props.put("DatabaseName", "${rhq.server.database.db-name:rhq}");
+
+ ModelNode xaDsRequest = client.createNewXADatasourceRequest(RHQ_DATASOURCE_NAME_XA, 30000,
+ JDBC_DRIVER_POSTGRES, "org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter", 15, 5,
+ 50, 75, RHQ_SECURITY_DOMAIN, "-unused-stale-conn-checker-", "TRANSACTION_READ_COMMITTED",
+ "org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker", props);
+ xaDsRequest.remove("stale-connection-checker-class-name"); // we don't have one of these for postgres
+
+ ModelNode batch = DatasourceJBossASClient.createBatchRequest(noTxDsRequest, xaDsRequest);
+ ModelNode results = client.execute(batch);
+ if (!DatasourceJBossASClient.isSuccess(results)) {
+ throw new FailureException(results, "Failed to create Postgres datasources");
+ }
+ }
+
+ private static void createNewDatasources_Oracle(ModelControllerClient mcc) throws Exception {
+ final HashMap<String, String> props = new HashMap<String, String>(2);
+ final DatasourceJBossASClient client = new DatasourceJBossASClient(mcc);
+
+ props.put("char.encoding", "UTF-8");
+ props.put("SetBigStringTryClob", "true");
+
+ ModelNode noTxDsRequest = client.createNewDatasourceRequest(RHQ_DATASOURCE_NAME_NOTX, 30000,
+ "${rhq.server.database.connection-url:jdbc:oracle:thin:@127.0.0.1:1521:rhq}", JDBC_DRIVER_ORACLE,
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter", 15, false, 2, 5, 75,
+ RHQ_SECURITY_DOMAIN, "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker",
+ "TRANSACTION_READ_COMMITTED", "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker",
+ props);
+
+ props.clear();
+ props.put("URL", "${rhq.server.database.connection-url:jdbc:oracle:thin:@127.0.0.1:1521:rhq}");
+ props.put("ConnectionProperties", "SetBigStringTryClob=true");
+
+ ModelNode xaDsRequest = client.createNewXADatasourceRequest(RHQ_DATASOURCE_NAME_XA, 30000, JDBC_DRIVER_ORACLE,
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter", 15, 5, 50, 75, RHQ_SECURITY_DOMAIN,
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker", "TRANSACTION_READ_COMMITTED",
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker", props);
+
+ ModelNode batch = DatasourceJBossASClient.createBatchRequest(noTxDsRequest, xaDsRequest);
+ ModelNode results = client.execute(batch);
+ if (!DatasourceJBossASClient.isSuccess(results)) {
+ throw new FailureException(results, "Failed to create Oracle datasources");
+ }
+ }
+
/**
* Determines if we are in auto-install mode. This means the properties file is
* fully configured and the installation can begin without asking the user
@@ -377,6 +614,7 @@ public class ServerInstallUtil {
updateOrInsertServer(db, conn, serverDetails);
} catch (SQLException e) {
+ // TODO: should we throw an exception here? This would abort the rest of the installation
LOG.info("Unable to store server entry in the database: " + ThrowableUtil.getAllMessages(e));
} finally {
if (null != db) {
diff --git a/modules/enterprise/gui/installer/src/test/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClientTest.java b/modules/enterprise/gui/installer/src/test/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClientTest.java
new file mode 100644
index 0000000..708b673
--- /dev/null
+++ b/modules/enterprise/gui/installer/src/test/java/org/rhq/common/jbossas/client/controller/DatasourceJBossASClientTest.java
@@ -0,0 +1,112 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.common.jbossas.client.controller;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.testng.annotations.Test;
+
+import org.jboss.as.controller.client.ModelControllerClient;
+import org.jboss.as.controller.client.OperationMessageHandler;
+import org.jboss.dmr.ModelNode;
+
+import org.rhq.enterprise.gui.installer.client.shared.ServerProperties;
+import org.rhq.enterprise.gui.installer.server.servlet.ServerInstallUtil;
+
+ at Test
+public class DatasourceJBossASClientTest {
+ private static final ModelNode mockSuccess;
+ static {
+ mockSuccess = new ModelNode();
+ mockSuccess.get(JBossASClient.OUTCOME).set(JBossASClient.OUTCOME_SUCCESS);
+ }
+
+ public void testCreateDatasourcesDMR() throws Exception {
+ ModelControllerClient mcc = mock(ModelControllerClient.class);
+
+ // note that this doesn't test actually creating anything - it just tests the DMR can be parsed successfully
+ when(mcc.execute(any(ModelNode.class), any(OperationMessageHandler.class))).thenAnswer(new Answer<ModelNode>() {
+ public ModelNode answer(InvocationOnMock invocation) throws Throwable {
+ System.out.println("~~~~~~~\n" + invocation.getArguments()[0]);
+ return mockSuccess;
+ }
+ });
+
+ HashMap<String, String> serverProperties = new HashMap<String, String>();
+ serverProperties.put(ServerProperties.PROP_DATABASE_TYPE, "Oracle");
+ ServerInstallUtil.createNewDatasources(mcc, serverProperties);
+
+ serverProperties.put(ServerProperties.PROP_DATABASE_TYPE, "PostgreSQL");
+ ServerInstallUtil.createNewDatasources(mcc, serverProperties);
+ }
+
+ public void testCreateNewDatasourceDMR() throws Exception {
+ ModelControllerClient mcc = mock(ModelControllerClient.class);
+
+ // note that this doesn't test actually creating anything - it just tests the DMR can be parsed successfully
+ when(mcc.execute(any(ModelNode.class), any(OperationMessageHandler.class))).thenReturn(mockSuccess);
+
+ DatasourceJBossASClient client = new DatasourceJBossASClient(mcc);
+
+ HashMap<String, String> connProps = new HashMap<String, String>(2);
+ connProps.put("char.encoding", "UTF-8");
+ connProps.put("SetBigStringTryClob", "true");
+
+ ModelNode request = client.createNewDatasourceRequest("NoTxRHQDS", 30000,
+ "${rhq.server.database.connection-url:jdbc:oracle:thin:@127.0.0.1:1521:rhq}", "oracle",
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter", 15, false, 2, 5, 75,
+ "RHQDSSecurityDomain", "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker",
+ "TRANSACTION_READ_COMMITTED", "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker",
+ connProps);
+
+ System.out.println("==============\n" + request);
+
+ ModelNode results = client.execute(request);
+ assert JBossASClient.isSuccess(results);
+ }
+
+ public void testCreateNewXADatasourceDMR() throws Exception {
+ ModelControllerClient mcc = mock(ModelControllerClient.class);
+
+ // note that this doesn't test actually creating anything - it just tests the DMR can be parsed successfully
+ when(mcc.execute(any(ModelNode.class), any(OperationMessageHandler.class))).thenReturn(mockSuccess);
+
+ DatasourceJBossASClient client = new DatasourceJBossASClient(mcc);
+
+ HashMap<String, String> xaDSProps = new HashMap<String, String>(2);
+ xaDSProps.put("URL", "${rhq.server.database.connection-url:jdbc:oracle:thin:@127.0.0.1:1521:rhq}");
+ xaDSProps.put("ConnectionProperties", "SetBigStringTryClob=true");
+
+ ModelNode request = client.createNewXADatasourceRequest("RHQDS", 30000, "oracle",
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter", 15, 2, 5, 75, "RHQDSSecurityDomain",
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker", "TRANSACTION_READ_COMMITTED",
+ "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker", xaDSProps);
+
+ System.out.println("==============\n" + request);
+
+ ModelNode results = client.execute(request);
+ assert JBossASClient.isSuccess(results);
+ }
+}
More information about the rhq-commits
mailing list