Exemple #1
0
  protected <T> T executeInTransaction(
      boolean rollback, TransactionCallbackReturnable<T> callback) {
    try {
      startTransaction();
      T result = callback.execute();
      return result;

    } catch (Throwable t) {
      rollback = true;
      RuntimeException re = new RuntimeException(ThrowableUtil.getAllMessages(t), t);
      throw re;

    } finally {
      try {
        if (!rollback) {
          commitTransaction();
        } else {
          rollbackTransaction();
        }
      } catch (Exception e) {
        throw new RuntimeException(
            "Failed to " + (rollback ? "rollback" : "commit") + " transaction", e);
      }
    }
  }
Exemple #2
0
 @Timeout
 // does AS7 EJB3 container allow this? We do not want a tx here!
 @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
 public void scanForPlugins(final Timer timer) {
   try {
     PluginDeploymentScannerMBean deployer = getPluginDeploymentScanner();
     deployer.scanAndRegister();
   } catch (Throwable t) {
     log.error("Plugin scan failed. Cause: " + ThrowableUtil.getAllMessages(t));
     if (log.isDebugEnabled()) {
       log.debug("Plugin scan failure stack trace follows:", t);
     }
   }
 }
  @Override
  public boolean mergeAvailabilityReport(AvailabilityReport availabilityReport) {
    AvailabilityReportSerializer.getSingleton().lock(availabilityReport.getAgentName());
    try {
      String reportToString = availabilityReport.toString(false);
      if (log.isDebugEnabled()) log.debug("Processing " + reportToString);

      long start = System.currentTimeMillis();
      AvailabilityManagerLocal availabilityManager = LookupUtil.getAvailabilityManager();
      boolean ok = availabilityManager.mergeAvailabilityReport(availabilityReport);

      long elapsed = (System.currentTimeMillis() - start);
      if (elapsed > 20000L) {
        log.warn(
            "Performance: processed "
                + reportToString
                + " - needFull=["
                + !ok
                + "] in ("
                + elapsed
                + ")ms");
      } else {
        if (log.isDebugEnabled()) {
          log.debug(
              "Performance: processed "
                  + reportToString
                  + " - needFull=["
                  + !ok
                  + "] in ("
                  + elapsed
                  + ")ms");
        }
      }

      return ok;
    } catch (Exception e) {
      log.info(
          "Error processing availability report from ["
              + availabilityReport.getAgentName()
              + "]: "
              + ThrowableUtil.getAllMessages(e));
      return true; // not sure what happened, but avoid infinite recursion during error conditions;
                   // do not ask for a full report
    } finally {
      AvailabilityReportSerializer.getSingleton().unlock(availabilityReport.getAgentName());
    }
  }
  /** @see ContainerService#shutdown() */
  public void shutdown() {
    // Inform the plugins we are shutting them down.
    // We want to shut them down in the reverse order that we initialized them.
    Collections.reverse(this.loadedPlugins);
    for (Plugin plugin : loadedPlugins) {
      PluginLifecycleListener listener = pluginLifecycleListenerMgr.getListener(plugin.getName());
      if (listener != null) {
        try {
          ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
          Thread.currentThread()
              .setContextClassLoader(
                  this.classLoaderManager.obtainPluginClassLoader(plugin.getName()));
          try {
            listener.shutdown();
          } finally {
            Thread.currentThread().setContextClassLoader(originalCL);
          }
        } catch (Throwable t) {
          log.warn(
              "Failed to get lifecycle listener to shutdown ["
                  + plugin.getName()
                  + "]. Cause: "
                  + ThrowableUtil.getAllMessages(t));
        }
      }
    }

    // Clean up the plugin environment and the temp dirs that were used by the plugin classloaders.
    for (PluginEnvironment pluginEnvironment : this.loadedPluginEnvironments.values()) {
      pluginEnvironment.destroy();
    }
    this.classLoaderManager.destroy();

    this.loadedPluginEnvironments.clear();
    this.loadedPlugins.clear();

    pluginLifecycleListenerMgr.shutdown();
  }
  /**
   * Returns a mapping of rows as key-value pairs where the key is the first column (a string) and
   * the second column is a value numeric.
   *
   * @param databaseComponent the component to execute on
   * @param query the sql query to run
   * @param parameters any parameters to bind first
   * @return a Map<String,Double> of the keys against the value
   */
  @Deprecated
  public static Map<String, Double> getNumericQueryValueMap(
      DatabaseComponent databaseComponent, String query, Object... parameters) {
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
      Connection c = databaseComponent.getConnection();
      statement = c.prepareStatement(query);
      bindParameters(statement, parameters);

      resultSet = statement.executeQuery();

      Map<String, Double> map = new HashMap<String, Double>();

      while (resultSet.next()) {
        try {
          map.put(resultSet.getString(1), resultSet.getDouble(2));
        } catch (SQLException e) {
          // Ignore columns that can't be read as doubles
          if (LOG.isTraceEnabled()) {
            LOG.trace(
                "A query column value is not a double, ignoring:"
                    + ThrowableUtil.getAllMessages(e));
          }
        }
      }

      return map;
    } catch (SQLException e) {
      LOG.info("Unable to read value", e);
      databaseComponent.removeConnection();
    } finally {
      close(statement, resultSet);
    }

    return Collections.emptyMap();
  }
Exemple #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;
  }
Exemple #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;
  }
Exemple #8
0
  public void doInstall(String[] args) throws Exception {

    WhatToDo[] thingsToDo = processArguments(args);

    for (WhatToDo whatToDo : thingsToDo) {
      switch (whatToDo) {
        case DISPLAY_USAGE:
          {
            displayUsage();
            continue;
          }
        case LIST_SERVERS:
          {
            new InstallerServiceImpl(installerConfig).listServers();
            continue;
          }
        case TEST:
          {
            try {
              new InstallerServiceImpl(installerConfig).test();
            } catch (AutoInstallDisabledException e) {
              LOG.error(e.getMessage());
              System.exit(EXIT_CODE_AUTOINSTALL_DISABLED);
            } catch (AlreadyInstalledException e) {
              LOG.info(e.getMessage());
              System.exit(EXIT_CODE_ALREADY_INSTALLED);
            }
            continue;
          }
        case SETUPDB:
          {
            try {
              final InstallerService installerService = new InstallerServiceImpl(installerConfig);
              final HashMap<String, String> serverProperties =
                  installerService.getServerProperties();
              installerService.prepareDatabase(serverProperties, null, null);
              LOG.info("Database setup is complete.");
            } catch (Exception e) {
              LOG.error(ThrowableUtil.getAllMessages(e));
              System.exit(EXIT_CODE_INSTALLATION_ERROR);
            }
            continue;
          }
        case RECONFIGURE:
          {
            try {
              final InstallerService installerService = new InstallerServiceImpl(installerConfig);
              final HashMap<String, String> serverProperties =
                  installerService.getServerProperties();
              installerService.reconfigure(serverProperties);
              LOG.info("Reconfiguration is complete.");
            } catch (Exception e) {
              LOG.error(ThrowableUtil.getAllMessages(e));
              System.exit(EXIT_CODE_INSTALLATION_ERROR);
            }
            continue;
          }
        case INSTALL:
          {
            try {
              final InstallerService installerService = new InstallerServiceImpl(installerConfig);
              final HashMap<String, String> serverProperties = installerService.preInstall();
              installerService.install(serverProperties, null, null);
              LOG.info("Installation is complete. The server should be ready shortly.");
            } catch (AutoInstallDisabledException e) {
              LOG.error(e.getMessage());
              System.exit(EXIT_CODE_AUTOINSTALL_DISABLED);
            } catch (AlreadyInstalledException e) {
              LOG.info(e.getMessage());
              System.exit(EXIT_CODE_ALREADY_INSTALLED);
            }
            continue;
          }
        case DO_NOTHING:
          {
            continue; // this will occur if processArguments() already did the work
          }
        default:
          {
            throw new IllegalStateException("Please report this bug: " + whatToDo);
          }
      }
    }

    return;
  }
Exemple #9
0
  @Override
  public DeployPackagesResponse deployPackages(
      Set<ResourcePackageDetails> packages, ContentServices contentServices) {
    // You can only update the one application file referenced by this
    // resource, so punch out if multiple are
    // specified.
    if (packages.size() != 1) {
      log.warn(
          "Request to update a VDB file contained multiple packages: " //$NON-NLS-1$
              + packages);
      DeployPackagesResponse response = new DeployPackagesResponse(ContentResponseResult.FAILURE);
      response.setOverallRequestErrorMessage(
          "When updating a VDB, only one VDB can be updated at a time."); //$NON-NLS-1$
      return response;
    }

    ResourcePackageDetails packageDetails = packages.iterator().next();

    log.debug(
        "Updating VDB file '"
            + this.deploymentFile
            + "' using [" //$NON-NLS-1$ //$NON-NLS-2$
            + packageDetails
            + "]..."); //$NON-NLS-1$

    log.debug("Writing new VDB bits to temporary file..."); // $NON-NLS-1$
    File tempFile;
    try {
      tempFile = writeNewAppBitsToTempFile(contentServices, packageDetails);
    } catch (Exception e) {
      return failApplicationDeployment(
          "Error writing new application bits to temporary file - cause: " //$NON-NLS-1$
              + e,
          packageDetails);
    }
    log.debug(
        "Wrote new VDB bits to temporary file '"
            + tempFile //$NON-NLS-1$
            + "'."); //$NON-NLS-1$

    boolean deployExploded = this.deploymentFile.isDirectory();

    // Backup the original app file/dir to <filename>.rej.
    File backupOfOriginalFile = new File(this.deploymentFile.getPath() + BACKUP_FILE_EXTENSION);
    log.debug(
        "Backing up existing VDB '"
            + this.deploymentFile // $NON-NLS-1$
            + "' to '"
            + backupOfOriginalFile
            + "'..."); //$NON-NLS-1$ //$NON-NLS-2$
    try {
      if (backupOfOriginalFile.exists()) FileUtils.forceDelete(backupOfOriginalFile);
      if (this.deploymentFile.isDirectory())
        FileUtils.copyDirectory(this.deploymentFile, backupOfOriginalFile, true);
      else FileUtils.copyFile(this.deploymentFile, backupOfOriginalFile, true);
    } catch (Exception e) {
      throw new RuntimeException(
          "Failed to backup existing EAR/WAR '" //$NON-NLS-1$
              + this.deploymentFile
              + "' to '"
              + backupOfOriginalFile //$NON-NLS-1$
              + "'."); //$NON-NLS-1$
    }

    // Now stop the original app.
    try {
      DeploymentManager deploymentManager = getConnection().getDeploymentManager();
      DeploymentProgress progress = deploymentManager.stop(this.deploymentUrl);
      DeploymentUtils.run(progress);
    } catch (Exception e) {
      throw new RuntimeException(
          "Failed to stop deployment [" //$NON-NLS-1$
              + this.deploymentUrl
              + "].",
          e); //$NON-NLS-1$
    }

    // And then remove it (this will delete the physical file/dir from the
    // deploy dir).
    try {
      DeploymentManager deploymentManager = getConnection().getDeploymentManager();
      DeploymentProgress progress = deploymentManager.remove(this.deploymentUrl);
      DeploymentUtils.run(progress);
    } catch (Exception e) {
      throw new RuntimeException(
          "Failed to remove deployment [" //$NON-NLS-1$
              + this.deploymentUrl
              + "].",
          e); //$NON-NLS-1$
    }

    // Deploy away!
    log.debug("Deploying '" + tempFile + "'..."); // $NON-NLS-1$ //$NON-NLS-2$
    DeploymentManager deploymentManager = getConnection().getDeploymentManager();
    try {
      DeploymentUtils.deployArchive(deploymentManager, tempFile, deployExploded);
    } catch (Exception e) {
      // Deploy failed - rollback to the original app file...
      log.debug(
          "Redeploy failed - rolling back to original archive...", //$NON-NLS-1$
          e);
      String errorMessage = ThrowableUtil.getAllMessages(e);
      try {
        // Delete the new app, which failed to deploy.
        FileUtils.forceDelete(this.deploymentFile);
        // Need to re-deploy the original file - this generally should
        // succeed.
        DeploymentUtils.deployArchive(deploymentManager, backupOfOriginalFile, deployExploded);
        errorMessage += " ***** ROLLED BACK TO ORIGINAL APPLICATION FILE. *****"; // $NON-NLS-1$
      } catch (Exception e1) {
        log.debug("Rollback failed!", e1); // $NON-NLS-1$
        errorMessage +=
            " ***** FAILED TO ROLLBACK TO ORIGINAL APPLICATION FILE. *****: " //$NON-NLS-1$
                + ThrowableUtil.getAllMessages(e1);
      }
      log.info(
          "Failed to update VDB file '"
              + this.deploymentFile // $NON-NLS-1$
              + "' using ["
              + packageDetails
              + "]."); //$NON-NLS-1$ //$NON-NLS-2$
      return failApplicationDeployment(errorMessage, packageDetails);
    }

    // Deploy was successful!

    deleteBackupOfOriginalFile(backupOfOriginalFile);
    persistApplicationVersion(packageDetails, this.deploymentFile);

    DeployPackagesResponse response = new DeployPackagesResponse(ContentResponseResult.SUCCESS);
    DeployIndividualPackageResponse packageResponse =
        new DeployIndividualPackageResponse(packageDetails.getKey(), ContentResponseResult.SUCCESS);
    response.addPackageResponse(packageResponse);

    log.debug(
        "Updated VDB file '"
            + this.deploymentFile // $NON-NLS-1$
            + "' successfully - returning response ["
            + response
            + "]..."); //$NON-NLS-1$ //$NON-NLS-2$

    return response;
  }
  @Override
  public void updateResourceConfiguration(
      final ConfigurationUpdateReport configurationUpdateReport) {
    ResourceType resourceType = context.getResourceType();
    ConfigurationDefinition configDef = resourceType.getResourceConfigurationDefinition();
    Configuration newConfig = configurationUpdateReport.getConfiguration();

    // remove special property being possibly sent from server in case EAP requires reload/restart
    newConfig.remove("__OOB");

    // 1. First of all, read the current configuration
    ConfigurationLoadDelegate readDelegate =
        new ConfigurationLoadDelegate(configDef, getASConnection(), address, includeRuntime);
    Configuration currentConfig;
    try {
      currentConfig = readDelegate.loadResourceConfiguration();
    } catch (Exception e) {
      getLog().error("Could not read current configuration before update", e);
      configurationUpdateReport.setStatus(FAILURE);
      configurationUpdateReport.setErrorMessage(
          "Could not read current configuration before update: " + ThrowableUtil.getRootMessage(e));
      return;
    }

    // 2. We will wrap all property-simple and connection properties changes in a composite
    // operation
    CompositeOperation updateOperation = new CompositeOperation();

    // 3. Capture property-simple changes
    Map<String, PropertySimple> newConfigSimpleProperties = newConfig.getSimpleProperties();
    Map<String, PropertySimple> currentConfigSimpleProperties = currentConfig.getSimpleProperties();

    Set<String> allSimplePropertyNames =
        new HashSet<String>(
            newConfigSimpleProperties.size() + currentConfigSimpleProperties.size());
    allSimplePropertyNames.addAll(newConfigSimpleProperties.keySet());
    allSimplePropertyNames.addAll(currentConfigSimpleProperties.keySet());
    // Read-only
    allSimplePropertyNames.remove(ENABLED_ATTRIBUTE);

    for (String simplePropertyName : allSimplePropertyNames) {
      PropertySimple newConfigPropertySimple = newConfigSimpleProperties.get(simplePropertyName);
      String newConfigPropertySimpleValue =
          newConfigPropertySimple == null ? null : newConfigPropertySimple.getStringValue();
      PropertySimple currentConfigPropertySimple =
          currentConfigSimpleProperties.get(simplePropertyName);
      String currentConfigPropertySimpleValue =
          currentConfigPropertySimple == null ? null : currentConfigPropertySimple.getStringValue();
      boolean canUnset = !UNSET_FORBIDDEN_ATTRIBUTES.contains(simplePropertyName);

      if (newConfigPropertySimpleValue == null) {
        if (currentConfigPropertySimpleValue != null) {
          String val;
          if (canUnset) {
            val = null;
          } else {
            val = configDef.getPropertyDefinitionSimple(simplePropertyName).getDefaultValue();
          }
          updateOperation.addStep(new WriteAttribute(getAddress(), simplePropertyName, val));
        }
      } else if (!newConfigPropertySimpleValue.equals(currentConfigPropertySimpleValue)) {
        updateOperation.addStep(
            new WriteAttribute(getAddress(), simplePropertyName, newConfigPropertySimpleValue));
      }
    }

    // 4. Capture connection property changes
    String connPropAttributeNameOnServer, connPropPluginConfigPropertyName, keyName;
    if (isXADatasourceResource(resourceType)) {
      connPropAttributeNameOnServer = "xa-datasource-properties";
      connPropPluginConfigPropertyName = XA_DATASOURCE_PROPERTIES_ATTRIBUTE;
      keyName = "key";
    } else {
      connPropAttributeNameOnServer = "connection-properties";
      connPropPluginConfigPropertyName = CONNECTION_PROPERTIES_ATTRIBUTE;
      keyName = "pname";
    }

    Map<String, String> newConfigConnectionProperties =
        getConnectionPropertiesAsMap(newConfig.getList(connPropPluginConfigPropertyName), keyName);
    Map<String, String> currentConfigConnectionProperties =
        getConnectionPropertiesAsMap(
            currentConfig.getList(connPropPluginConfigPropertyName), keyName);
    Set<String> allConnectionPropertyNames =
        new HashSet<String>(
            newConfigConnectionProperties.size() + currentConfigConnectionProperties.size());
    allConnectionPropertyNames.addAll(newConfigConnectionProperties.keySet());
    allConnectionPropertyNames.addAll(currentConfigConnectionProperties.keySet());

    for (String connectionPropertyName : allConnectionPropertyNames) {
      Address propertyAddress = new Address(getAddress());
      propertyAddress.add(connPropAttributeNameOnServer, connectionPropertyName);

      String newConfigConnectionPropertyValue =
          newConfigConnectionProperties.get(connectionPropertyName);
      String currentConfigConnectionPropertyValue =
          currentConfigConnectionProperties.get(connectionPropertyName);

      if (newConfigConnectionPropertyValue == null) {
        updateOperation.addStep(new Operation("remove", propertyAddress));
      } else if (currentConfigConnectionPropertyValue == null) {
        Operation addOperation = new Operation("add", propertyAddress);
        addOperation.addAdditionalProperty("value", newConfigConnectionPropertyValue);
        updateOperation.addStep(addOperation);
      } else if (!newConfigConnectionPropertyValue.equals(currentConfigConnectionPropertyValue)) {
        updateOperation.addStep(new Operation("remove", propertyAddress));
        Operation addOperation = new Operation("add", propertyAddress);
        addOperation.addAdditionalProperty("value", newConfigConnectionPropertyValue);
        updateOperation.addStep(addOperation);
      }
    }

    // 5. Update config if needed
    if (updateOperation.numberOfSteps() > 0) {
      Result res = getASConnection().execute(updateOperation);
      if (res.isSuccess()) {
        configurationUpdateReport.setStatus(SUCCESS);
      } else {
        configurationUpdateReport.setStatus(FAILURE);
        configurationUpdateReport.setErrorMessage(res.getFailureDescription());
      }
    } else {
      configurationUpdateReport.setStatus(NOCHANGE);
    }
  }