/* * Copyright (c) 2014-2015 Janith Bandara, This source is a part of * Audit4j - An open source auditing framework. * http://audit4j.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.audit4j.handler.db; import static org.audit4j.handler.db.Utils.checkNotEmpty; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import javax.sql.DataSource; import org.audit4j.core.ErrorGuide; import org.audit4j.core.exception.HandlerException; import org.audit4j.core.exception.InitializationException; import org.audit4j.core.handler.Handler; import org.audit4j.core.util.Log; import com.google.common.base.Throwables; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; /** * The Class GeneralDatabaseAuditHandler. * * @author <a href="mailto:janith3000@gmail.com">Janith Bandara</a> * @author Thebora Kompanioni https://github.com/theborakompanioni */ public class DatabaseAuditHandler extends Handler { /** * The Constant serialVersionUID. */ private static final long serialVersionUID = -4994028889410866952L; private static final String DEFAULT_TABLE_NAME = "audit"; /** * Creating cache for Data access objects for different tables. */ private final LoadingCache<String, AuditLogDao> daos = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterAccess(15, TimeUnit.MINUTES) .build(new CacheLoader<String, AuditLogDao>() { @Override public AuditLogDao load(String tableName) throws HandlerException { return new AuditLogDaoImpl(tableName); } }); /** * The embeded. */ private String embedded; /** * The db_driver. */ private String db_driver; /** * The db_url. */ private String db_url; /** * The db_user. */ private String db_user; /** * The db_password. */ private String db_password; /** * The db_connection_type. */ private String db_connection_type; /** * The db_datasource class. */ private String db_datasourceClass; /** * The db_jndi_datasource. */ private String db_jndi_datasource; /** * The auto commit. */ private boolean db_pool_autoCommit = true; /** * The connection timeout. */ private Long db_pool_connectionTimeout; /** * The idle timeout. */ private Integer db_pool_idleTimeout; /** * The max lifetime. */ private Integer db_pool_maxLifetime; /** * The minimum idle. */ private Integer db_pool_minimumIdle; /** * The maximum pool size. */ private Integer db_pool_maximumPoolSize; /** * The Constant POOLED_CONNECTION. */ private static final String POOLED_CONNECTION = "pooled"; /** * The Constant JNDI_CONNECTION. */ private static final String JNDI_CONNECTION = "jndi"; /** * The server. */ private EmbededDBServer server; /** * The factory. */ private ConnectionFactory factory; /** * The separate. */ private boolean separate = false; /** * The data source. */ private DataSource dataSource; /** * The table_prefix. */ private String table_prefix; /** * The table_suffix. */ private String table_suffix = "audit"; /** * The default_table_suffix. */ private String default_table_name = DEFAULT_TABLE_NAME; /** * Instantiates a new database audit handler. */ public DatabaseAuditHandler() { } /** * Initialize database handler. * * @throws InitializationException the initialization exception */ @Override public void init() throws InitializationException { if (null == embedded || "true".equalsIgnoreCase(embedded)) { Log.warn("Audit4j Database Handler runs on embedded mode. See " + ErrorGuide.ERROR_URL + "embeddeddb for further details."); server = HSQLEmbededDBServer.getInstance(); db_driver = server.getDriver(); db_url = server.getNetworkProtocol() + ":file:audit4jdb"; if (db_user == null) { db_user = Utils.EMBEDED_DB_USER; } if (db_password == null) { db_password = Utils.EMBEDED_DB_PASSWORD; } server.setUname(db_user); server.setPassword(db_password); server.start(); } factory = ConnectionFactory.getInstance(); factory.setDataSource(dataSource); factory.setDriver(getDb_driver()); factory.setUrl(getDb_url()); factory.setUser(getDb_user()); factory.setPassword(getDb_password()); factory.setDataSourceClass(db_datasourceClass); factory.setAutoCommit(db_pool_autoCommit); if (db_pool_connectionTimeout != null) { factory.setConnectionTimeout(db_pool_connectionTimeout); } if (db_pool_idleTimeout != null) { factory.setIdleTimeout(db_pool_idleTimeout); } if (db_pool_maximumPoolSize != null) { factory.setMaximumPoolSize(db_pool_maximumPoolSize); } if (db_pool_maxLifetime != null) { factory.setMaxLifetime(db_pool_maxLifetime); } if (db_pool_minimumIdle != null) { factory.setMinimumIdle(db_pool_minimumIdle); } if (getDb_connection_type() != null && getDb_connection_type().equals(POOLED_CONNECTION)) { factory.setConnectionType(ConnectionType.POOLED); } else if (getDb_connection_type() != null && getDb_connection_type().equals(JNDI_CONNECTION)) { factory.setConnectionType(ConnectionType.JNDI); factory.setJndiDataSource(getDb_jndi_datasource()); } else { factory.setConnectionType(ConnectionType.SINGLE); } factory.init(); try { getDaoForTable(default_table_name); } catch (HandlerException e) { throw new InitializationException("Unable to create tables", e); } } /** * Handle event. * <p> * {@inheritDoc} * * @see org.audit4j.core.handler.Handler#handle() */ @Override public void handle() throws HandlerException { String repository = getAuditEvent().getRepository(); boolean writeInDefaultTable = !separate || repository == null; String tableName = writeInDefaultTable ? default_table_name : generateTableName(repository); getDaoForTable(tableName).writeEvent(getAuditEvent()); } /** * Shutdown database handler. */ @Override public void stop() { factory.stop(); if (server != null) { server.shutdown(); } } /** * Generate table name. * * @param repository * @return the string */ private String generateTableName(String repository) { if (table_prefix == null) { return repository + "_" + table_suffix; } return table_prefix + "_" + repository + "_" + table_suffix; } private AuditLogDao getDaoForTable(String tableName) throws HandlerException { try { return daos.get(tableName); } catch (ExecutionException e) { Throwables.propagateIfInstanceOf(e.getCause(), HandlerException.class); throw new HandlerException("Execution Exception", DatabaseAuditHandler.class, e); } } /** * Gets the db_connection_type. * * @return the db_connection_type */ public String getDb_connection_type() { return db_connection_type; } /** * Sets the db_connection_type. * * @param db_connection_type the new db_connection_type */ public void setDb_connection_type(String db_connection_type) { this.db_connection_type = db_connection_type; } /** * Gets the embedded. * * @return the embedded */ public String getEmbedded() { return embedded; } /** * Sets the embedded. * * @param embedded the new embedded */ public void setEmbedded(String embedded) { this.embedded = embedded; } /** * Gets the db_driver. * * @return the db_driver */ public String getDb_driver() { return db_driver; } /** * Sets the db_driver. * * @param db_driver the new db_driver */ public void setDb_driver(String db_driver) { this.db_driver = db_driver; } /** * Gets the db_url. * * @return the db_url */ public String getDb_url() { return db_url; } /** * Sets the db_url. * * @param db_url the new db_url */ public void setDb_url(String db_url) { this.db_url = db_url; } /** * Gets the db_user. * * @return the db_user */ public String getDb_user() { return db_user; } /** * Sets the db_user. * * @param db_user the new db_user */ public void setDb_user(String db_user) { this.db_user = db_user; } /** * Gets the db_password. * * @return the db_password */ public String getDb_password() { return db_password; } /** * Sets the db_password. * * @param db_password the new db_password */ public void setDb_password(String db_password) { this.db_password = db_password; } /** * Gets the db_jndi_datasource. * * @return the db_jndi_datasource */ public String getDb_jndi_datasource() { return db_jndi_datasource; } /** * Sets the db_jndi_datasource. * * @param db_jndi_datasource the new db_jndi_datasource */ public void setDb_jndi_datasource(String db_jndi_datasource) { this.db_jndi_datasource = db_jndi_datasource; } /** * Sets the separate. * * @param separate the new separate */ public void setSeparate(boolean separate) { this.separate = separate; } /** * Sets the data source. * * @param dataSource the new data source */ public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * Sets the table_prefix. * * @param table_prefix the new table_prefix */ public void setTable_prefix(String table_prefix) { this.table_prefix = table_prefix; } /** * Sets the table_suffix. * * @param table_suffix the new table_suffix */ public void setTable_suffix(String table_suffix) { this.table_suffix = table_suffix; } /** * Sets the default_table_name. * * @param default_table_name the new default_table_name */ public void setDefault_table_name(String default_table_name) { this.default_table_name = checkNotEmpty(default_table_name, "Table name must not be empty"); } /** * Sets the db_pool_auto commit. * * @param db_pool_autoCommit the new db_pool_auto commit */ public void setDb_pool_autoCommit(boolean db_pool_autoCommit) { this.db_pool_autoCommit = db_pool_autoCommit; } /** * Sets the db_pool_connection timeout. * * @param db_pool_connectionTimeout the new db_pool_connection timeout */ public void setDb_pool_connectionTimeout(Long db_pool_connectionTimeout) { this.db_pool_connectionTimeout = db_pool_connectionTimeout; } /** * Sets the db_pool_idle timeout. * * @param db_pool_idleTimeout the new db_pool_idle timeout */ public void setDb_pool_idleTimeout(Integer db_pool_idleTimeout) { this.db_pool_idleTimeout = db_pool_idleTimeout; } /** * Sets the db_pool_max lifetime. * * @param db_pool_maxLifetime the new db_pool_max lifetime */ public void setDb_pool_maxLifetime(Integer db_pool_maxLifetime) { this.db_pool_maxLifetime = db_pool_maxLifetime; } /** * Sets the db_pool_minimum idle. * * @param db_pool_minimumIdle the new db_pool_minimum idle */ public void setDb_pool_minimumIdle(Integer db_pool_minimumIdle) { this.db_pool_minimumIdle = db_pool_minimumIdle; } /** * Sets the db_pool_maximum pool size. * * @param db_pool_maximumPoolSize the new db_pool_maximum pool size */ public void setDb_pool_maximumPoolSize(Integer db_pool_maximumPoolSize) { this.db_pool_maximumPoolSize = db_pool_maximumPoolSize; } /** * Sets the db_datasource class. * * @param db_datasourceClass the new db_datasource class */ public void setDb_datasourceClass(String db_datasourceClass) { this.db_datasourceClass = db_datasourceClass; } }