예제 #1
1
  @Override
  public int size(final DatabaseTable table) throws DatabaseException {
    preOperationCheck();

    final StringBuilder sb = new StringBuilder();
    sb.append("SELECT COUNT(" + KEY_COLUMN + ") FROM ").append(table.toString());

    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
      statement = connection.prepareStatement(sb.toString());
      resultSet = statement.executeQuery();
      if (resultSet.next()) {
        return resultSet.getInt(1);
      }
    } catch (SQLException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(
              PwmError.ERROR_DB_UNAVAILABLE, "size operation failed: " + e.getMessage());
      lastError = errorInformation;
      throw new DatabaseException(errorInformation);
    } finally {
      close(statement);
      close(resultSet);
    }

    updateStats(true, false);
    return 0;
  }
예제 #2
0
  private boolean isValid(final Connection connection) {
    if (connection == null) {
      return false;
    }

    if (status != PwmService.STATUS.OPEN) {
      return false;
    }

    try {
      final Method getFreeSpaceMethod = File.class.getMethod("isValid");
      final Object rawResult = getFreeSpaceMethod.invoke(connection, 10);
      return (Boolean) rawResult;
    } catch (NoSuchMethodException e) {
      /* no error, pre java 1.6 doesn't have this method */
    } catch (Exception e) {
      LOGGER.debug(
          "error checking for isValid for " + connection.toString() + ",: " + e.getMessage());
    }

    final StringBuilder sb = new StringBuilder();
    sb.append("SELECT * FROM ")
        .append(DatabaseTable.PWM_META.toString())
        .append(" WHERE " + KEY_COLUMN + " = ?");
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
      statement = connection.prepareStatement(sb.toString());
      statement.setString(1, KEY_ENGINE_START_PREFIX + instanceID);
      statement.setMaxRows(1);
      resultSet = statement.executeQuery();
      if (resultSet.next()) {
        resultSet.getString(VALUE_COLUMN);
      }
    } catch (SQLException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(
              PwmError.ERROR_DB_UNAVAILABLE, "isValid operation failed: " + e.getMessage());
      lastError = errorInformation;
      LOGGER.error(errorInformation.toDebugStr());
      return false;
    } finally {
      close(statement);
      close(resultSet);
    }
    return true;
  }
예제 #3
0
 private static void checkIfTableExists(final Connection connection, final DatabaseTable table)
     throws SQLException {
   final StringBuilder sb = new StringBuilder();
   sb.append("SELECT * FROM  ").append(table.toString()).append(" WHERE " + KEY_COLUMN + " = '0'");
   Statement statement = null;
   ResultSet resultSet = null;
   try {
     statement = connection.createStatement();
     resultSet = statement.executeQuery(sb.toString());
   } finally {
     close(statement);
     close(resultSet);
   }
 }
예제 #4
0
  public void close() {
    status = PwmService.STATUS.CLOSED;
    if (connection != null) {
      try {
        connection.close();
      } catch (Exception e) {
        LOGGER.debug("error while closing DB: " + e.getMessage());
      }
    }

    try {
      driver = null;
    } catch (Exception e) {
      LOGGER.debug("error while de-registering driver: " + e.getMessage());
    }

    connection = null;
  }
예제 #5
0
  @Override
  public String get(final DatabaseTable table, final String key) throws DatabaseException {
    if (traceLogging) {
      LOGGER.trace("attempting get operation for table=" + table + ", key=" + key);
    }
    preOperationCheck();
    final StringBuilder sb = new StringBuilder();
    sb.append("SELECT * FROM ").append(table.toString()).append(" WHERE " + KEY_COLUMN + " = ?");

    PreparedStatement statement = null;
    ResultSet resultSet = null;
    String returnValue = null;
    try {
      statement = connection.prepareStatement(sb.toString());
      statement.setString(1, key);
      statement.setMaxRows(1);
      resultSet = statement.executeQuery();

      if (resultSet.next()) {
        returnValue = resultSet.getString(VALUE_COLUMN);
      }
    } catch (SQLException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(
              PwmError.ERROR_DB_UNAVAILABLE, "get operation failed: " + e.getMessage());
      lastError = errorInformation;
      throw new DatabaseException(errorInformation);
    } finally {
      close(statement);
      close(resultSet);
    }

    if (traceLogging) {
      final LinkedHashMap<String, Object> debugOutput = new LinkedHashMap<>();
      debugOutput.put("table", table);
      debugOutput.put("key", key);
      debugOutput.put("result", returnValue);
      LOGGER.trace(
          "get operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint));
    }

    updateStats(true, false);
    return returnValue;
  }
예제 #6
0
  @Override
  public boolean remove(final DatabaseTable table, final String key) throws DatabaseException {
    if (traceLogging) {
      LOGGER.trace("attempting remove operation for table=" + table + ", key=" + key);
    }

    boolean result = contains(table, key);
    if (result) {
      final StringBuilder sqlText = new StringBuilder();
      sqlText.append("DELETE FROM ").append(table.toString()).append(" WHERE " + KEY_COLUMN + "=?");

      PreparedStatement statement = null;
      try {
        statement = connection.prepareStatement(sqlText.toString());
        statement.setString(1, key);
        statement.executeUpdate();
        LOGGER.trace("remove operation succeeded for table=" + table + ", key=" + key);
      } catch (SQLException e) {
        final ErrorInformation errorInformation =
            new ErrorInformation(
                PwmError.ERROR_DB_UNAVAILABLE, "remove operation failed: " + e.getMessage());
        lastError = errorInformation;
        throw new DatabaseException(errorInformation);
      } finally {
        close(statement);
      }
    }

    if (traceLogging) {
      final Map<String, Object> debugOutput = new LinkedHashMap<>();
      debugOutput.put("table", table);
      debugOutput.put("key", key);
      debugOutput.put("result", result);
      LOGGER.trace(
          "remove operation result: "
              + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint));
    }

    updateStats(true, false);
    return result;
  }
예제 #7
0
 private static Map<PwmAboutProperty, String> getConnectionDebugProperties(
     final Connection connection) {
   if (connection != null) {
     try {
       final Map<PwmAboutProperty, String> returnObj = new LinkedHashMap<>();
       final DatabaseMetaData databaseMetaData = connection.getMetaData();
       returnObj.put(PwmAboutProperty.database_driverName, databaseMetaData.getDriverName());
       returnObj.put(PwmAboutProperty.database_driverVersion, databaseMetaData.getDriverVersion());
       returnObj.put(
           PwmAboutProperty.database_databaseProductName,
           databaseMetaData.getDatabaseProductName());
       returnObj.put(
           PwmAboutProperty.database_databaseProductVersion,
           databaseMetaData.getDatabaseProductVersion());
       return Collections.unmodifiableMap(returnObj);
     } catch (SQLException e) {
       LOGGER.error("error rading jdbc meta data: " + e.getMessage());
     }
   }
   return Collections.emptyMap();
 }
예제 #8
0
  @Override
  public boolean put(final DatabaseTable table, final String key, final String value)
      throws DatabaseException {

    preOperationCheck();
    if (traceLogging) {
      LOGGER.trace("attempting put operation for table=" + table + ", key=" + key);
    }
    if (!contains(table, key)) {
      final String sqlText =
          "INSERT INTO "
              + table.toString()
              + "("
              + KEY_COLUMN
              + ", "
              + VALUE_COLUMN
              + ") VALUES(?,?)";
      PreparedStatement statement = null;

      try {
        statement = connection.prepareStatement(sqlText);
        statement.setString(1, key);
        statement.setString(2, value);
        statement.executeUpdate();
      } catch (SQLException e) {
        final ErrorInformation errorInformation =
            new ErrorInformation(
                PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage());
        lastError = errorInformation;
        throw new DatabaseException(errorInformation);
      } finally {
        close(statement);
      }
      return false;
    }

    final String sqlText =
        "UPDATE " + table.toString() + " SET " + VALUE_COLUMN + "=? WHERE " + KEY_COLUMN + "=?";
    PreparedStatement statement = null;

    try {
      statement = connection.prepareStatement(sqlText);
      statement.setString(1, value);
      statement.setString(2, key);
      statement.executeUpdate();
    } catch (SQLException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(
              PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage());
      lastError = errorInformation;
      throw new DatabaseException(errorInformation);
    } finally {
      close(statement);
    }

    if (traceLogging) {
      final Map<String, Object> debugOutput = new LinkedHashMap<>();
      debugOutput.put("table", table);
      debugOutput.put("key", key);
      debugOutput.put("value", value);
      LOGGER.trace(
          "put operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint));
    }

    updateStats(false, true);
    return true;
  }
예제 #9
0
  private static void initTable(
      final Connection connection, final DatabaseTable table, final DBConfiguration dbConfiguration)
      throws DatabaseException {
    try {
      checkIfTableExists(connection, table);
      LOGGER.trace("table " + table + " appears to exist");
    } catch (SQLException e) { // assume error was due to table missing;
      {
        final StringBuilder sqlString = new StringBuilder();
        sqlString.append("CREATE table ").append(table.toString()).append(" (").append("\n");
        sqlString
            .append("  " + KEY_COLUMN + " ")
            .append(dbConfiguration.getColumnTypeKey())
            .append("(")
            .append(KEY_COLUMN_LENGTH)
            .append(") NOT NULL PRIMARY KEY,")
            .append("\n");
        sqlString
            .append("  " + VALUE_COLUMN + " ")
            .append(dbConfiguration.getColumnTypeValue())
            .append(" ");
        sqlString.append("\n");
        sqlString.append(")").append("\n");

        LOGGER.trace(
            "attempting to execute the following sql statement:\n " + sqlString.toString());

        Statement statement = null;
        try {
          statement = connection.createStatement();
          statement.execute(sqlString.toString());
          LOGGER.debug("created table " + table.toString());
        } catch (SQLException ex) {
          LOGGER.error("error creating new table " + table.toString() + ": " + ex.getMessage());
        } finally {
          close(statement);
        }
      }

      {
        final String indexName = table.toString() + "_IDX";
        final StringBuilder sqlString = new StringBuilder();
        sqlString.append("CREATE index ").append(indexName);
        sqlString.append(" ON ").append(table.toString());
        sqlString.append(" (").append(KEY_COLUMN).append(")");
        Statement statement = null;

        LOGGER.trace(
            "attempting to execute the following sql statement:\n " + sqlString.toString());

        try {
          statement = connection.createStatement();
          statement.execute(sqlString.toString());
          LOGGER.debug("created index " + indexName);
        } catch (SQLException ex) {
          LOGGER.error("error creating new index " + indexName + ": " + ex.getMessage());
        } finally {
          close(statement);
        }
      }
    }
  }
예제 #10
0
  private Connection openDB(final DBConfiguration dbConfiguration) throws DatabaseException {
    final String connectionURL = dbConfiguration.getConnectionString();
    final String jdbcClassName = dbConfiguration.getDriverClassname();

    try {
      final byte[] jdbcDriverBytes = dbConfiguration.getJdbcDriver();
      if (jdbcDriverBytes != null) {
        LOGGER.debug("loading JDBC database driver stored in configuration");
        final JarClassLoader jarClassLoader = new JarClassLoader();
        jarClassLoader.add(new ByteArrayInputStream(jdbcDriverBytes));
        final JclObjectFactory jclObjectFactory = JclObjectFactory.getInstance();

        // Create object of loaded class
        driver = (Driver) jclObjectFactory.create(jarClassLoader, jdbcClassName);

        LOGGER.debug(
            "successfully loaded JDBC database driver '"
                + jdbcClassName
                + "' from application configuration");
      }
    } catch (Throwable e) {
      final String errorMsg =
          "error registering JDBC database driver stored in configuration: " + e.getMessage();
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg);
      LOGGER.error(errorMsg, e);
      throw new DatabaseException(errorInformation);
    }

    if (driver == null) {
      try {
        LOGGER.debug("loading JDBC database driver from classpath: " + jdbcClassName);
        driver = (Driver) Class.forName(jdbcClassName).newInstance();

        LOGGER.debug("successfully loaded JDBC database driver from classpath: " + jdbcClassName);
      } catch (Throwable e) {
        final String errorMsg =
            e.getClass().getName()
                + " error loading JDBC database driver from classpath: "
                + e.getMessage();
        final ErrorInformation errorInformation =
            new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg);
        throw new DatabaseException(errorInformation);
      }
    }

    try {
      LOGGER.debug("opening connection to database " + connectionURL);
      final Properties connectionProperties = new Properties();
      if (dbConfiguration.getUsername() != null && !dbConfiguration.getUsername().isEmpty()) {
        connectionProperties.setProperty("user", dbConfiguration.getUsername());
      }
      if (dbConfiguration.getPassword() != null) {
        connectionProperties.setProperty(
            "password", dbConfiguration.getPassword().getStringValue());
      }
      final Connection connection = driver.connect(connectionURL, connectionProperties);

      final Map<PwmAboutProperty, String> debugProps = getConnectionDebugProperties(connection);
      ;
      LOGGER.debug(
          "successfully opened connection to database "
              + connectionURL
              + ", properties: "
              + JsonUtil.serializeMap(debugProps));

      connection.setAutoCommit(true);
      return connection;
    } catch (Throwable e) {
      final String errorMsg =
          "error connecting to database: " + Helper.readHostileExceptionMessage(e);
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg);
      if (e instanceof IOException) {
        LOGGER.error(errorInformation);
      } else {
        LOGGER.error(errorMsg, e);
      }
      throw new DatabaseException(errorInformation);
    }
  }