public StartPageResults testConnection() { Properties configurationAsProperties = getConfigurationAsProperties(configuration); // its possible the JDBC URL was changed, clear the factory cache in case the DB version is // different now DatabaseTypeFactory.clearDatabaseTypeCache(); try { serverInfo.ensureDatabaseIsSupported(configurationAsProperties); lastTest = "OK"; } catch (Exception e) { LOG.warn("Installer failed to test connection", e); lastTest = e.toString(); } return StartPageResults.STAY; }
public StartPageResults save() { LOG.info("Installer raw values: " + configuration); // if auto-install is enabled, the db password will be encrypted - decrypt it internally and // we'll re-encrypt later if (isAutoinstallEnabled()) { try { PropertyItemWithValue prop = getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_PASSWORD); String pass = prop.getValue(); pass = decodePassword(pass); prop.setValue(pass); // log the unencrypted pw, but only at the trace level so it isn't put in the log file // unless someone explicitly enables the trace level so they can see the pass that is to be // used for debugging LOG.trace(">" + pass); } catch (Exception e) { LOG.fatal("Could not decrypt the password for some reason - auto-installation failed", e); lastError = I18Nmsg.getMsg(InstallerI18NResourceKeys.SAVE_ERROR, ThrowableUtil.getAllMessages(e)); return StartPageResults.ERROR; } } // its possible the JDBC URL was changed, clear the factory cache in case the DB version is // different now DatabaseTypeFactory.clearDatabaseTypeCache(); try { // update server properties with the latest ha info to keep the form and server properties // file up to date getConfigurationPropertyFromAll(ServerProperties.PROP_HIGH_AVAILABILITY_NAME) .setValue(getHaServer().getName()); getConfigurationPropertyFromAll(ServerProperties.PROP_HTTP_PORT) .setValue(getHaServer().getEndpointPortString()); getConfigurationPropertyFromAll(ServerProperties.PROP_HTTPS_PORT) .setValue(getHaServer().getEndpointSecurePortString()); // the comm bind port is a special setting - it is allowed to be blank; // if it was originally blank, it will have been set to 0 because its an integer property; // but we do not want it to be 0, so make sure we switch it back to empty PropertyItemWithValue portConfig = getConfigurationPropertyFromAll(ServerProperties.PROP_CONNECTOR_BIND_PORT); if ("0".equals(portConfig.getValue())) { portConfig.setRawValue(""); } } catch (Exception e) { LOG.fatal("Could not save the settings for some reason", e); lastError = I18Nmsg.getMsg(InstallerI18NResourceKeys.SAVE_ERROR, ThrowableUtil.getAllMessages(e)); return StartPageResults.ERROR; } try { String url = getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_CONNECTION_URL).getValue(); String db = getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_TYPE).getValue(); Pattern pattern = null; if (db.toLowerCase().indexOf("postgres") > -1) { pattern = Pattern.compile( ".*://(.*):([0123456789]+)/(.*)"); // jdbc:postgresql://host.name:5432/rhq } else if (db.toLowerCase().indexOf("oracle") > -1) { LOG.info( "Oracle does not need to have server-name, port and db-name individually set, skipping"); // 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 } else if (db.toLowerCase().indexOf("h2") > -1) { LOG.info( "H2 does not need to have server-name, port and db-name individually set, skipping"); } else if (db.toLowerCase().indexOf("sqlserver") > -1) { pattern = Pattern.compile( "(?i).*://(.*):([0123456789]+).*databaseName=([^;]*)"); // jdbc:jtds:sqlserver://localhost:7777;databaseName=rhq } else { LOG.info("Unknown database type - will not set server-name, port and db-name"); // don't bother throwing error; these three extra settings may not be necessary anyway } if (pattern != null) { 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); getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_SERVER_NAME) .setValue(serverName); getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_PORT).setValue(port); getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_DB_NAME).setValue(dbName); } else { throw new Exception("Cannot get server, port or db name from connection URL: " + url); } } else { getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_SERVER_NAME).setValue(""); getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_PORT).setValue(""); getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_DB_NAME).setValue(""); } } catch (Exception e) { LOG.fatal("JDBC connection URL seems to be invalid", e); lastError = I18Nmsg.getMsg(InstallerI18NResourceKeys.SAVE_ERROR, ThrowableUtil.getAllMessages(e)); return StartPageResults.ERROR; } try { String db = getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_TYPE).getValue(); String dialect; String quartzDriverDelegateClass = "org.quartz.impl.jdbcjobstore.StdJDBCDelegate"; String quartzSelectWithLockSQL = "SELECT * FROM {0}LOCKS ROWLOCK WHERE LOCK_NAME = ? FOR UPDATE"; String quartzLockHandlerClass = "org.quartz.impl.jdbcjobstore.StdRowLockSemaphore"; if (db.toLowerCase().indexOf("postgres") > -1) { dialect = "org.hibernate.dialect.PostgreSQLDialect"; quartzDriverDelegateClass = "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"; } else if (db.toLowerCase().indexOf("oracle") > -1) { dialect = "org.hibernate.dialect.Oracle10gDialect"; quartzDriverDelegateClass = "org.quartz.impl.jdbcjobstore.oracle.OracleDelegate"; } else if (db.toLowerCase().indexOf("h2") > -1) { dialect = "org.rhq.core.server.H2CustomDialect"; } else if (db.toLowerCase().indexOf("sqlserver") > -1) { dialect = "org.hibernate.dialect.SQLServerDialect"; quartzDriverDelegateClass = "org.quartz.impl.jdbcjobstore.MSSQLDelegate"; quartzSelectWithLockSQL = "SELECT * FROM {0}LOCKS ROWLOCK WITH (HOLDLOCK,XLOCK) WHERE LOCK_NAME = ?"; quartzLockHandlerClass = "org.quartz.impl.jdbcjobstore.UpdateLockRowSemaphore"; } else if (db.toLowerCase().indexOf("mysql") > -1) { dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"; quartzDriverDelegateClass = "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"; } else { throw new Exception("Unknown db type: " + db); } getConfigurationPropertyFromAll(ServerProperties.PROP_DATABASE_HIBERNATE_DIALECT) .setValue(dialect); getConfigurationPropertyFromAll(ServerProperties.PROP_QUARTZ_DRIVER_DELEGATE_CLASS) .setValue(quartzDriverDelegateClass); getConfigurationPropertyFromAll(ServerProperties.PROP_QUARTZ_SELECT_WITH_LOCK_SQL) .setValue(quartzSelectWithLockSQL); getConfigurationPropertyFromAll(ServerProperties.PROP_QUARTZ_LOCK_HANDLER_CLASS) .setValue(quartzLockHandlerClass); } catch (Exception e) { LOG.fatal("Invalid database type", e); lastError = I18Nmsg.getMsg(InstallerI18NResourceKeys.SAVE_ERROR, ThrowableUtil.getAllMessages(e)); return StartPageResults.ERROR; } Properties configurationAsProperties = getConfigurationAsProperties(configuration); testConnection(); // so our lastTest gets set and the user will be able to get the error in the // UI if (lastTest == null || !lastTest.equals("OK")) { lastError = lastTest; return StartPageResults.ERROR; } // Ensure server info has been set if ((null == haServer) || (null == haServer.getName()) || "".equals(haServer.getName().trim())) { lastError = I18Nmsg.getMsg( InstallerI18NResourceKeys.INVALID_STRING, I18Nmsg.getMsg(InstallerI18NResourceKeys.PROP_HIGH_AVAILABILITY_NAME)); return StartPageResults.ERROR; } for (PropertyItemWithValue newValue : configuration) { if (Integer.class.isAssignableFrom(newValue.getItemDefinition().getPropertyType())) { try { Integer.parseInt(newValue.getValue()); } catch (Exception e) { // there is one special property - the connector bind port - that is allowed to be empty // ignore this error if we are looking at that property and its empty; otherwise, this is // an error if (!(newValue .getItemDefinition() .getPropertyName() .equals(ServerProperties.PROP_CONNECTOR_BIND_PORT) && newValue.getValue().length() == 0)) { lastError = I18Nmsg.getMsg( InstallerI18NResourceKeys.INVALID_NUMBER, newValue.getItemDefinition().getPropertyLabel(), newValue.getValue()); return StartPageResults.ERROR; } } } else if (Boolean.class.isAssignableFrom(newValue.getItemDefinition().getPropertyType())) { try { if (newValue.getValue() == null) { newValue.setValue(Boolean.FALSE.toString()); } Boolean.parseBoolean(newValue.getValue()); } catch (Exception e) { lastError = I18Nmsg.getMsg( InstallerI18NResourceKeys.INVALID_BOOLEAN, newValue.getItemDefinition().getPropertyLabel(), newValue.getValue()); return StartPageResults.ERROR; } } } try { // indicate that no errors occurred lastError = null; // save the properties serverInfo.setServerProperties(configurationAsProperties); // prepare the db schema if (!ExistingSchemaOption.SKIP.name().equals(existingSchemaOption)) { if (serverInfo.isDatabaseSchemaExist(configurationAsProperties)) { if (existingSchemaOption == null) { if (!isAutoinstallEnabled()) { return StartPageResults .STAY; // user didn't tell us what to do, re-display the page with the question } // we are supposed to auto-install but wasn't explicitly told what to do - the default // is "auto" // and since we know the database schema exists, that means we upgrade it } if (ExistingSchemaOption.OVERWRITE.name().equals(existingSchemaOption)) { serverInfo.createNewDatabaseSchema(configurationAsProperties); } else { serverInfo.upgradeExistingDatabaseSchema(configurationAsProperties); } } else { serverInfo.createNewDatabaseSchema(configurationAsProperties); } } // Ensure the install server info is up to date and stored in the DB serverInfo.storeServer(configurationAsProperties, haServer); // encode database password and set updated properties String pass = configurationAsProperties.getProperty(ServerProperties.PROP_DATABASE_PASSWORD); pass = encryptPassword(pass); configurationAsProperties.setProperty(ServerProperties.PROP_DATABASE_PASSWORD, pass); serverInfo.setServerProperties(configurationAsProperties); // We have changed the password of the database connection, so we need to // tell the login config about it serverInfo.restartLoginConfig(); // build a keystore whose cert has a CN of this server's public endpoint address serverInfo.createKeystore(haServer); // now deploy RHQ Server fully serverInfo.moveDeploymentArtifacts(true); } catch (Exception e) { LOG.fatal( "Failed to updated properties and fully deploy - RHQ Server will not function properly", e); lastError = I18Nmsg.getMsg(InstallerI18NResourceKeys.SAVE_FAILURE, ThrowableUtil.getAllMessages(e)); return StartPageResults.ERROR; } LOG.info("Installer: final submitted values: " + configurationAsProperties); return StartPageResults.SUCCESS; }