org.apereo.inspektr.audit.support.JdbcAuditTrailManager Maven / Gradle / Ivy
/**
* Licensed to Apereo under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Apereo licenses this file to you 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 the following location:
*
* 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.
*/
/**
* Copyright (C) 2010 Rutgers, the State University of New Jersey.
*
* 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.apereo.inspektr.audit.support;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apereo.inspektr.audit.AuditActionContext;
import org.apereo.inspektr.audit.AuditTrailManager;
import org.apereo.inspektr.common.Cleanable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* Implementation of {@link AuditTrailManager} to persist the
* audit trail to the AUDIT_TRAIL table in the Oracle data base.
*
*
* CREATE TABLE COM_AUDIT_TRAIL
* (
* AUD_USER VARCHAR2(100) NOT NULL,
* AUD_CLIENT_IP VARCHAR(15) NOT NULL,
* AUD_SERVER_IP VARCHAR(15) NOT NULL,
* AUD_RESOURCE VARCHAR2(100) NOT NULL,
* AUD_ACTION VARCHAR2(100) NOT NULL,
* APPLIC_CD VARCHAR2(5) NOT NULL,
* AUD_DATE TIMESTAMP NOT NULL
* )
*
*
* @author Scott Battaglia
* @author Marvin S. Addison
* @version $Revision: 1.7 $ $Date: 2007/12/03 22:02:41 $
* @since 1.0
*/
public class JdbcAuditTrailManager extends NamedParameterJdbcDaoSupport implements AuditTrailManager, Cleanable, DisposableBean {
private static final String INSERT_SQL_TEMPLATE = "INSERT INTO %s " +
"(AUD_USER, AUD_CLIENT_IP, AUD_SERVER_IP, AUD_RESOURCE, AUD_ACTION, APPLIC_CD, AUD_DATE) " +
"VALUES (?, ?, ?, ?, ?, ?, ?)";
private static final String DELETE_SQL_TEMPLATE = "DELETE FROM %s %s";
private static final int DEFAULT_COLUMN_LENGTH = 100;
/**
* Logger instance
*/
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* Instance of TransactionTemplate to manually execute a transaction since
* threads are not in the same transaction.
*/
@NotNull
private final TransactionTemplate transactionTemplate;
@NotNull
@Size(min = 1)
private String tableName = "COM_AUDIT_TRAIL";
@Min(50)
private int columnLength = DEFAULT_COLUMN_LENGTH;
/**
* ExecutorService that has one thread to asynchronously save requests.
*
* You can configure one with an {@link org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean}.
*/
@NotNull
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private boolean defaultExecutorService = true;
/**
* Criteria used to determine records that should be deleted on cleanup
*/
private WhereClauseMatchCriteria cleanupCriteria = new NoMatchWhereClauseMatchCriteria();
public JdbcAuditTrailManager(final TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void record(final AuditActionContext auditActionContext) {
this.executorService.execute(new LoggingTask(auditActionContext, this.transactionTemplate, this.columnLength));
}
protected class LoggingTask implements Runnable {
private final AuditActionContext auditActionContext;
private final TransactionTemplate transactionTemplate;
private final int columnLength;
public LoggingTask(final AuditActionContext auditActionContext, final TransactionTemplate transactionTemplate, final int columnLength) {
this.auditActionContext = auditActionContext;
this.transactionTemplate = transactionTemplate;
this.columnLength = columnLength;
}
public void run() {
this.transactionTemplate
.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(final TransactionStatus transactionStatus) {
final String userId = auditActionContext.getPrincipal().length() <= columnLength ? auditActionContext.getPrincipal() : auditActionContext.getPrincipal().substring(0, columnLength);
final String resource = auditActionContext.getResourceOperatedUpon().length() <= columnLength ? auditActionContext.getResourceOperatedUpon() : auditActionContext.getResourceOperatedUpon().substring(0, columnLength);
final String action = auditActionContext.getActionPerformed().length() <= columnLength ? auditActionContext.getActionPerformed() : auditActionContext.getActionPerformed().substring(0, columnLength);
getJdbcTemplate()
.update(
String.format(INSERT_SQL_TEMPLATE, tableName),
userId,
auditActionContext.getClientIpAddress(),
auditActionContext.getServerIpAddress(),
resource,
action,
auditActionContext.getApplicationCode(),
auditActionContext.getWhenActionWasPerformed());
}
});
}
}
public void setTableName(final String tableName) {
this.tableName = tableName;
}
public void setCleanupCriteria(final WhereClauseMatchCriteria criteria) {
this.cleanupCriteria = criteria;
}
public void setExecutorService(final ExecutorService executorService) {
this.executorService = executorService;
this.defaultExecutorService = false;
}
public void setColumnLength(final int columnLength) {
this.columnLength = columnLength;
}
/**
* We only shut down the default executor service. We assume, that if you've injected one, its being managed elsewhere.
*/
public void destroy() throws Exception {
if (this.defaultExecutorService) {
this.executorService.shutdown();
}
}
public void clean() {
this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(final TransactionStatus transactionStatus) {
final String sql = String.format(DELETE_SQL_TEMPLATE, tableName, cleanupCriteria);
final List> params = cleanupCriteria.getParameterValues();
JdbcAuditTrailManager.this.logger.info("Cleaning audit records with query " + sql);
JdbcAuditTrailManager.this.logger.debug("Query parameters: " + params);
final int count = getJdbcTemplate().update(sql, params.toArray());
JdbcAuditTrailManager.this.logger.info(count + " records deleted.");
}
});
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy