mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Added AuditService.clearAudit(List<Long>)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22980 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -135,14 +135,20 @@
|
|||||||
delete
|
delete
|
||||||
from
|
from
|
||||||
alf_audit_entry
|
alf_audit_entry
|
||||||
where
|
<dynamic prepend="where">
|
||||||
|
<isNotNull property="auditFromTime" prepend="and">
|
||||||
audit_app_id = #auditApplicationId#
|
audit_app_id = #auditApplicationId#
|
||||||
<isNotNull property="auditFromTime">
|
|
||||||
<![CDATA[and audit_time >= #auditFromTime#]]>
|
|
||||||
</isNotNull>
|
</isNotNull>
|
||||||
<isNotNull property="auditFromTime">
|
<isNotNull property="auditFromTime" prepend="and">
|
||||||
<![CDATA[and audit_time < #auditToTime#]]>
|
<![CDATA[audit_time >= #auditFromTime#]]>
|
||||||
</isNotNull>
|
</isNotNull>
|
||||||
|
<isNotNull property="auditFromTime" prepend="and">
|
||||||
|
<![CDATA[audit_time < #auditToTime#]]>
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull property="auditEntryIds" prepend="and">
|
||||||
|
id in <iterate property="auditEntryIds" open="(" close=")" conjunction=", ">#auditEntryIds[]#</iterate>
|
||||||
|
</isNotNull>
|
||||||
|
</dynamic>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<sql id="select_AuditEntriesWhereSnippet">
|
<sql id="select_AuditEntriesWhereSnippet">
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
package org.alfresco.repo.audit;
|
package org.alfresco.repo.audit;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.repo.audit.model.AuditApplication;
|
import org.alfresco.repo.audit.model.AuditApplication;
|
||||||
@@ -89,6 +90,14 @@ public interface AuditComponent
|
|||||||
*/
|
*/
|
||||||
int deleteAuditEntries(String applicationName, Long fromTime, Long toTime);
|
int deleteAuditEntries(String applicationName, Long fromTime, Long toTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a discrete list of audit entries based on ID
|
||||||
|
*
|
||||||
|
* @param auditEntryIds the audit entry IDs to delete
|
||||||
|
* @return Returns the number of entries deleted
|
||||||
|
*/
|
||||||
|
int deleteAuditEntries(List<Long> auditEntryIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an audit path is enabled. The path will be disabled if it or any higher
|
* Check if an audit path is enabled. The path will be disabled if it or any higher
|
||||||
* path has been explicitly disabled. Any disabled path will not be processed when
|
* path has been explicitly disabled. Any disabled path will not be processed when
|
||||||
|
@@ -146,6 +146,21 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
return deleted;
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int deleteAuditEntries(List<Long> auditEntryIds)
|
||||||
|
{
|
||||||
|
// Shortcut, if necessary
|
||||||
|
if (auditEntryIds.size() == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return auditDAO.deleteAuditEntries(auditEntryIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param application the audit application object
|
* @param application the audit application object
|
||||||
* @return Returns a copy of the set of disabled paths associated with the application
|
* @return Returns a copy of the set of disabled paths associated with the application
|
||||||
|
@@ -523,7 +523,7 @@ public class AuditComponentTest extends TestCase
|
|||||||
auditModelRegistry.registerModel(testModelUrl);
|
auditModelRegistry.registerModel(testModelUrl);
|
||||||
auditModelRegistry.loadAuditModels();
|
auditModelRegistry.loadAuditModels();
|
||||||
|
|
||||||
final List<Map<String, Serializable>> results = new ArrayList<Map<String,Serializable>>();
|
final List<Long> results = new ArrayList<Long>(5);
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
AuditQueryCallback auditQueryCallback = new AuditQueryCallback()
|
AuditQueryCallback auditQueryCallback = new AuditQueryCallback()
|
||||||
{
|
{
|
||||||
@@ -539,7 +539,7 @@ public class AuditComponentTest extends TestCase
|
|||||||
long time,
|
long time,
|
||||||
Map<String, Serializable> values)
|
Map<String, Serializable> values)
|
||||||
{
|
{
|
||||||
results.add(values);
|
results.add(entryId);
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug(
|
logger.debug(
|
||||||
@@ -615,11 +615,28 @@ public class AuditComponentTest extends TestCase
|
|||||||
{
|
{
|
||||||
// Expected
|
// Expected
|
||||||
}
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
authenticationService.authenticate("banana", "****".toCharArray());
|
||||||
|
fail("Invalid authentication attempt should fail");
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
results.clear();
|
results.clear();
|
||||||
sb.delete(0, sb.length());
|
sb.delete(0, sb.length());
|
||||||
queryAuditLog(auditQueryCallback, params, -1);
|
queryAuditLog(auditQueryCallback, params, -1);
|
||||||
logger.debug(sb.toString());
|
logger.debug(sb.toString());
|
||||||
assertFalse("Did not get any audit results after failed login", results.isEmpty());
|
assertEquals("Incorrect number of audit entries after failed login", 2, results.size());
|
||||||
|
|
||||||
|
// Check that we can delete explicit entries
|
||||||
|
deleteAuditEntries(results);
|
||||||
|
results.clear();
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
queryAuditLog(auditQueryCallback, params, -1);
|
||||||
|
logger.debug(sb.toString());
|
||||||
|
assertEquals("Explicit audit entries were not deleted", 0, results.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAuditQuery_MaxId() throws Exception
|
public void testAuditQuery_MaxId() throws Exception
|
||||||
@@ -677,6 +694,23 @@ public class AuditComponentTest extends TestCase
|
|||||||
AuthenticationUtil.runAs(work, AuthenticationUtil.getAdminRoleName());
|
AuthenticationUtil.runAs(work, AuthenticationUtil.getAdminRoleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clearn the audit log as 'admin'
|
||||||
|
*/
|
||||||
|
private void deleteAuditEntries(final List<Long> auditEntryIds)
|
||||||
|
{
|
||||||
|
RunAsWork<Void> work = new RunAsWork<Void>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Void doWork() throws Exception
|
||||||
|
{
|
||||||
|
auditService.clearAudit(auditEntryIds);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
AuthenticationUtil.runAs(work, AuthenticationUtil.getAdminRoleName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clearn the audit log as 'admin'
|
* Clearn the audit log as 'admin'
|
||||||
*/
|
*/
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.audit;
|
package org.alfresco.repo.audit;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@@ -133,6 +133,16 @@ public class AuditServiceImpl implements AuditService
|
|||||||
return auditComponent.deleteAuditEntries(applicationName, fromTime, toTime);
|
return auditComponent.deleteAuditEntries(applicationName, fromTime, toTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int clearAudit(List<Long> auditEntryIds)
|
||||||
|
{
|
||||||
|
return auditComponent.deleteAuditEntries(auditEntryIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @since 3.3
|
* @since 3.3
|
||||||
|
@@ -22,11 +22,13 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
@@ -41,6 +43,7 @@ import org.alfresco.service.cmr.repository.ContentWriter;
|
|||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -306,7 +309,39 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
|||||||
return entity.getId();
|
return entity.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int deleteAuditEntries(List<Long> auditEntryIds)
|
||||||
|
{
|
||||||
|
// Ensure that we don't have duplicates
|
||||||
|
Set<Long> ids = new TreeSet<Long>(auditEntryIds);
|
||||||
|
int shouldDelete = ids.size();
|
||||||
|
|
||||||
|
int deleted = 0;
|
||||||
|
List<Long> batch = new ArrayList<Long>(shouldDelete > 512 ? 512 : shouldDelete);
|
||||||
|
for (Long id : ids)
|
||||||
|
{
|
||||||
|
batch.add(id);
|
||||||
|
if (batch.size() >= 512)
|
||||||
|
{
|
||||||
|
deleted += deleteAuditEntriesImpl(batch);
|
||||||
|
batch.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Process remaining
|
||||||
|
if (batch.size() > 0)
|
||||||
|
{
|
||||||
|
deleted += deleteAuditEntriesImpl(batch);
|
||||||
|
}
|
||||||
|
// Check concurrency
|
||||||
|
if (deleted != shouldDelete)
|
||||||
|
{
|
||||||
|
throw new ConcurrencyFailureException(
|
||||||
|
"Deleted " + deleted + " audit entries out of a set of " + shouldDelete + " unique IDs.");
|
||||||
|
}
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId);
|
protected abstract AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId);
|
||||||
|
protected abstract int deleteAuditEntriesImpl(List<Long> auditEntryIds);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Searches
|
* Searches
|
||||||
|
@@ -20,6 +20,7 @@ package org.alfresco.repo.domain.audit;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -166,6 +167,17 @@ public interface AuditDAO
|
|||||||
*/
|
*/
|
||||||
int deleteAuditEntries(Long applicationId, Long from, Long to);
|
int deleteAuditEntries(Long applicationId, Long from, Long to);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a discrete list of audit entries. Duplicate entries are collapsed
|
||||||
|
* and the number of entries deleted will match the count of unique IDs in
|
||||||
|
* the list; otherwise a concurrency condition has occured and an exception
|
||||||
|
* will be generated.
|
||||||
|
*
|
||||||
|
* @param auditEntryIds the IDs of all audit entries to delete
|
||||||
|
* @return Returns the number of entries deleted
|
||||||
|
*/
|
||||||
|
int deleteAuditEntries(List<Long> auditEntryIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new audit entry with the given map of values.
|
* Create a new audit entry with the given map of values.
|
||||||
*
|
*
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
package org.alfresco.repo.domain.audit;
|
package org.alfresco.repo.domain.audit;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletion parameters for <b>alf_audit_entry</b> table.
|
* Deletion parameters for <b>alf_audit_entry</b> table.
|
||||||
@@ -31,6 +32,7 @@ public class AuditDeleteParameters
|
|||||||
private Long auditApplicationId;
|
private Long auditApplicationId;
|
||||||
private Long auditFromTime;
|
private Long auditFromTime;
|
||||||
private Long auditToTime;
|
private Long auditToTime;
|
||||||
|
private List<Long> auditEntryIds;
|
||||||
|
|
||||||
public AuditDeleteParameters()
|
public AuditDeleteParameters()
|
||||||
{
|
{
|
||||||
@@ -44,6 +46,7 @@ public class AuditDeleteParameters
|
|||||||
.append("[ auditApplicationId=").append(auditApplicationId)
|
.append("[ auditApplicationId=").append(auditApplicationId)
|
||||||
.append(", auditFromTime").append(auditFromTime == null ? null : new Date(auditFromTime))
|
.append(", auditFromTime").append(auditFromTime == null ? null : new Date(auditFromTime))
|
||||||
.append(", auditToTime").append(auditToTime == null ? null : new Date(auditToTime))
|
.append(", auditToTime").append(auditToTime == null ? null : new Date(auditToTime))
|
||||||
|
.append(", auditEntryIds").append(auditEntryIds == null ? null : auditEntryIds.size())
|
||||||
.append("]");
|
.append("]");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
@@ -77,4 +80,14 @@ public class AuditDeleteParameters
|
|||||||
{
|
{
|
||||||
this.auditToTime = auditToTime;
|
this.auditToTime = auditToTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Long> getAuditEntryIds()
|
||||||
|
{
|
||||||
|
return auditEntryIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditEntryIds(List<Long> auditEntryIds)
|
||||||
|
{
|
||||||
|
this.auditEntryIds = auditEntryIds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -170,6 +170,14 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
|
|||||||
return template.delete(DELETE_ENTRIES, params);
|
return template.delete(DELETE_ENTRIES, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int deleteAuditEntriesImpl(List<Long> auditEntryIds)
|
||||||
|
{
|
||||||
|
AuditDeleteParameters params = new AuditDeleteParameters();
|
||||||
|
params.setAuditEntryIds(auditEntryIds);
|
||||||
|
return template.delete(DELETE_ENTRIES, params);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId)
|
protected AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId)
|
||||||
{
|
{
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
package org.alfresco.service.cmr.audit;
|
package org.alfresco.service.cmr.audit;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.service.PublicService;
|
import org.alfresco.service.PublicService;
|
||||||
@@ -145,6 +146,19 @@ public interface AuditService
|
|||||||
*/
|
*/
|
||||||
int clearAudit(String applicationName, Long fromTime, Long toTime);
|
int clearAudit(String applicationName, Long fromTime, Long toTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a discrete list of audit entries.
|
||||||
|
* <p/>
|
||||||
|
* This method should not be called <i>while</i> processing
|
||||||
|
* {@link #auditQuery(AuditQueryCallback, AuditQueryParameters, int) query results}.
|
||||||
|
*
|
||||||
|
* @param auditEntryIds the IDs of all audit entries to delete
|
||||||
|
* @return Returns the number of audit entries deleted
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
int clearAudit(List<Long> auditEntryIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface that will be used to give query results to the calling code.
|
* The interface that will be used to give query results to the calling code.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user