예제 #1
0
  public void initConfiguration() {
    if (configuration == null) {
      Properties properties = serverInfo.getServerProperties();
      List<PropertyItem> itemDefs = new ServerProperties().getPropertyItems();
      configuration = new ArrayList<PropertyItemWithValue>();

      for (PropertyItem itemDef : itemDefs) {
        String property = properties.getProperty(itemDef.getPropertyName());
        PropertyItemWithValue value = new PropertyItemWithValue(itemDef, property);
        configuration.add(value);
      }

      // force some hardcoded defaults for IBM JVMs that must have specific values
      boolean isIBM = System.getProperty("java.vendor", "").contains("IBM");
      if (isIBM) {
        String[] algPropNames = {
          ServerProperties.PROP_TOMCAT_SECURITY_ALGORITHM,
          ServerProperties.PROP_SECURITY_CLIENT_KEYSTORE_ALGORITHM,
          ServerProperties.PROP_SECURITY_CLIENT_TRUSTSTORE_ALGORITHM,
          ServerProperties.PROP_SECURITY_SERVER_KEYSTORE_ALGORITHM,
          ServerProperties.PROP_SECURITY_SERVER_TRUSTSTORE_ALGORITHM
        };

        for (String algPropName : algPropNames) {
          PropertyItemWithValue prop = getConfigurationProperty(this.configuration, algPropName);
          if (prop != null) {
            prop.setValue("IbmX509");
          }
        }
      }
    }

    return;
  }
예제 #2
0
 public boolean isDatabaseSchemaExist() {
   try {
     Properties configurationAsProperties = getConfigurationAsProperties(configuration);
     return serverInfo.isDatabaseSchemaExist(configurationAsProperties);
   } catch (Exception e) {
     LOG.info("Could not determine database existence: " + e);
     return false;
   }
 }
예제 #3
0
  public void setHaServerName(String serverName) {
    // handle the case where the user selected the dummy entry in the registered servers drop down
    if (I18Nmsg.getMsg(InstallerI18NResourceKeys.NEW_SERVER_SELECT_ITEM).equals(serverName)) {
      serverName = this.getDefaultServerName();
    }

    this.haServerName = serverName;

    // try pulling info from the database for this server name
    if (isRegisteredServers()) {
      Properties configurationAsProperties = getConfigurationAsProperties(configuration);
      setHaServer(serverInfo.getServerDetail(configurationAsProperties, serverName));
    }

    // if the server was not registered in the database then populate the ha server info with proper
    // defaults
    if (null == getHaServer()) {
      String endpointAddress = "";

      try {
        endpointAddress = InetAddress.getLocalHost().getCanonicalHostName();
      } catch (Exception e) {
        LOG.info("Could not determine default server address: ", e);
      }

      setHaServer(
          new ServerInformation.Server(
              serverName,
              endpointAddress,
              ServerInformation.Server.DEFAULT_ENDPOINT_PORT,
              ServerInformation.Server.DEFAULT_ENDPOINT_SECURE_PORT,
              ServerInformation.Server.DEFAULT_AFFINITY_GROUP));

      // override default settings with current property values
      try {
        getHaServer()
            .setEndpointPortString(
                getConfigurationPropertyFromAll(ServerProperties.PROP_HTTP_PORT).getValue());
      } catch (Exception e) {
        LOG.debug("Could not determine default port: ", e);
      }

      try {
        getHaServer()
            .setEndpointSecurePortString(
                getConfigurationPropertyFromAll(ServerProperties.PROP_HTTPS_PORT).getValue());
      } catch (Exception e) {
        LOG.debug("Could not determine default secure port: ", e);
      }
    } else {
      getHaServer().setName(serverName);
    }
  }
예제 #4
0
  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;
  }
예제 #5
0
  public List<SelectItem> getRegisteredServerNames() {
    List<SelectItem> result = new ArrayList<SelectItem>(0);

    if (!isDatabaseSchemaExist()) return result;

    try {
      Properties configurationAsProperties = getConfigurationAsProperties(configuration);
      for (String serverName : serverInfo.getServerNames(configurationAsProperties)) {
        result.add(new SelectItem(serverName));
      }
      if (!result.isEmpty()) {
        result.add(
            0, new SelectItem(I18Nmsg.getMsg(InstallerI18NResourceKeys.NEW_SERVER_SELECT_ITEM)));
      }
    } catch (Exception e) {
      // Should not be able to get here since we checked for schema above
      LOG.warn("Unexpected Exception getting registered server info: ", e);
    }

    return result;
  }
예제 #6
0
  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;
  }
예제 #7
0
  public StartPageResults createDatabase() {
    Properties config = getConfigurationAsProperties(configuration);
    String dbType = config.getProperty(ServerProperties.PROP_DATABASE_TYPE, "-unknown-");

    Properties adminConfig = new Properties();
    adminConfig.put(ServerProperties.PROP_DATABASE_CONNECTION_URL, adminConnectionUrl);
    adminConfig.put(ServerProperties.PROP_DATABASE_USERNAME, adminUsername);
    adminConfig.put(ServerProperties.PROP_DATABASE_PASSWORD, adminPassword);

    Connection conn = null;
    Statement stmt = null;

    // If we successfully add the user/database, we'll change the values in the UI
    // by modifying the configuration property items that this bean manages.
    PropertyItemWithValue propertyItemUsername = null;
    PropertyItemWithValue propertyItemPassword = null;
    PropertyItemWithValue propertyItemUrl = null;

    for (PropertyItemWithValue item : configuration) {
      String propName = item.getItemDefinition().getPropertyName();
      if (propName.equals(ServerProperties.PROP_DATABASE_USERNAME)) {
        propertyItemUsername = item;
      } else if (propName.equals(ServerProperties.PROP_DATABASE_PASSWORD)) {
        propertyItemPassword = item;
      } else if (propName.equals(ServerProperties.PROP_DATABASE_CONNECTION_URL)) {
        propertyItemUrl = item;
      }
    }

    if (propertyItemUsername == null || propertyItemPassword == null || propertyItemUrl == null) {
      throw new NullPointerException("Missing a property item - this is a bug please report it");
    }

    LOG.info(
        "Will attempt to create user/database 'rhqadmin' using URL ["
            + getAdminConnectionUrl()
            + "] and admin user ["
            + getAdminUsername()
            + "]. Admin password was"
            + (getAdminPassword().length() > 0 ? " not " : " ")
            + "empty");

    try {
      String sql1, sql2;

      conn = serverInfo.getDatabaseConnection(adminConfig);
      conn.setAutoCommit(true);
      stmt = conn.createStatement();

      if (dbType.equalsIgnoreCase("postgresql")) {
        sql1 =
            "CREATE ROLE rhqadmin LOGIN ENCRYPTED PASSWORD 'rhqadmin' NOSUPERUSER NOINHERIT CREATEDB NOCREATEROLE";
        sql2 =
            "CREATE DATABASE rhq WITH OWNER = rhqadmin ENCODING = 'SQL_ASCII' TABLESPACE = pg_default";
      } else if (dbType.equalsIgnoreCase("oracle10g")) {
        sql1 = "CREATE USER rhqadmin IDENTIFIED BY rhqadmin";
        sql2 = "GRANT connect, resource TO rhqadmin";
      } else if (dbType.equalsIgnoreCase("h2")) {
        // I have no idea if these are correct for H2 - I just copied oracle's sql
        sql1 = "CREATE USER rhqadmin IDENTIFIED BY rhqadmin";
        sql2 = "GRANT connect, resource TO rhqadmin";
      } else if (dbType.equalsIgnoreCase("sqlserver")) {
        // I have no idea if these are correct for sql server - I just copied oracle's sql
        sql1 = "CREATE USER rhqadmin IDENTIFIED BY rhqadmin";
        sql2 = "GRANT connect, resource TO rhqadmin";
      } else {
        throw new Exception("Unknown database type: " + dbType);
      }

      stmt.addBatch(sql1);
      stmt.addBatch(sql2);
      int[] results = stmt.executeBatch();

      if (results[0] == Statement.EXECUTE_FAILED) throw new Exception("Failed to execute: " + sql1);
      if (results[1] == Statement.EXECUTE_FAILED) throw new Exception("Failed to execute: " + sql2);

      // success! let's set our properties to the values we just created
      propertyItemUsername.setValue("rhqadmin");
      propertyItemPassword.setValue("rhqadmin");
      if (dbType.equalsIgnoreCase("postgresql") || dbType.equalsIgnoreCase("mysql")) {
        if (!propertyItemUrl.getValue().endsWith("/rhq")) {
          propertyItemUrl.setValue(propertyItemUrl.getValue() + "/rhq");
        }
      }

      testConnection();

      lastCreate = "OK";
    } catch (Exception e) {
      LOG.warn("Installer failed to create database", e);
      lastCreate = ThrowableUtil.getAllMessages(e);
    } finally {
      adminConnectionUrl = null;
      adminUsername = null;
      adminPassword = null;

      if (stmt != null)
        try {
          stmt.close();
        } catch (Exception e) {
        }
      if (conn != null)
        try {
          conn.close();
        } catch (Exception e) {
        }
    }

    return StartPageResults.STAY;
  }