diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml
index 5d822884be..a42f26a4a1 100644
--- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml
+++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml
@@ -201,6 +201,14 @@
sp_mpl.value_prop_id = #searchValueId#
+
+ order by
+ entry.id asc
+
+
+ order by
+ entry.id desc
+
@@ -242,6 +250,14 @@
sp_mpl.value_prop_id = #searchValueId#
+
+ order by
+ entry.id asc
+
+
+ order by
+ entry.id desc
+
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/AuditComponent.java b/source/java/org/alfresco/repo/audit/AuditComponent.java
index 7af005e1b6..93c581944a 100644
--- a/source/java/org/alfresco/repo/audit/AuditComponent.java
+++ b/source/java/org/alfresco/repo/audit/AuditComponent.java
@@ -188,6 +188,8 @@ public interface AuditComponent
* Get the audit entries that match the given criteria.
*
* @param callback the callback that will handle results
+ * @param forward true for results to ordered from first to last,
+ * or false to order from last to first
* @param applicationName if not null, find entries logged against this application
* @param user if not null, find entries logged against this user
* @param from the start search time (null to start at the beginning)
@@ -198,6 +200,7 @@ public interface AuditComponent
*/
void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
int maxResults);
@@ -205,6 +208,8 @@ public interface AuditComponent
* Get the audit entries that match the given criteria.
*
* @param callback the callback that will handle results
+ * @param forward true for results to ordered from first to last,
+ * or false to order from last to first
* @param applicationName if not null, find entries logged against this application
* @param user if not null, find entries logged against this user
* @param from the start search time (null to start at the beginning)
@@ -217,6 +222,7 @@ public interface AuditComponent
*/
void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
String searchKey, Serializable searchValue,
int maxResults);
diff --git a/source/java/org/alfresco/repo/audit/AuditComponentImpl.java b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java
index 0457e34cb0..919ed9c85a 100644
--- a/source/java/org/alfresco/repo/audit/AuditComponentImpl.java
+++ b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java
@@ -1323,6 +1323,7 @@ public class AuditComponentImpl implements AuditComponent
*/
public void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName,
String user,
Long from,
@@ -1338,7 +1339,8 @@ public class AuditComponentImpl implements AuditComponent
return;
}
- auditDAO.findAuditEntries(callback, applicationName, user, from, to, maxResults);
+ auditDAO.findAuditEntries(
+ callback, forward, applicationName, user, from, to, maxResults);
}
/**
@@ -1346,6 +1348,7 @@ public class AuditComponentImpl implements AuditComponent
*/
public void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName,
String user,
Long from,
@@ -1362,6 +1365,7 @@ public class AuditComponentImpl implements AuditComponent
return;
}
- auditDAO.findAuditEntries(callback, applicationName, user, from, to, searchKey, searchValue, maxResults);
+ auditDAO.findAuditEntries(
+ callback, forward, applicationName, user, from, to, searchKey, searchValue, maxResults);
}
}
diff --git a/source/java/org/alfresco/repo/audit/AuditComponentTest.java b/source/java/org/alfresco/repo/audit/AuditComponentTest.java
index e01667fbeb..9c46fa6238 100644
--- a/source/java/org/alfresco/repo/audit/AuditComponentTest.java
+++ b/source/java/org/alfresco/repo/audit/AuditComponentTest.java
@@ -35,6 +35,7 @@ import java.util.Map;
import junit.framework.TestCase;
+import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.audit.model.AuditApplication;
import org.alfresco.repo.audit.model.AuditModelException;
import org.alfresco.repo.audit.model.AuditModelRegistry;
@@ -328,11 +329,16 @@ public class AuditComponentTest extends TestCase
rowCount.setValue(rowCount.intValue() + 1);
return true;
}
+
+ public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
+ {
+ throw new AlfrescoRuntimeException(errorMsg, error);
+ }
};
sb.delete(0, sb.length());
rowCount.setValue(0);
- auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, null, null, -1);
+ auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, null, null, null, -1);
assertTrue("Expected some data", rowCount.intValue() > 0);
logger.debug(sb.toString());
int allResults = rowCount.intValue();
@@ -340,21 +346,21 @@ public class AuditComponentTest extends TestCase
// Limit by count
sb.delete(0, sb.length());
rowCount.setValue(0);
- auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, null, null, 1);
+ auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, null, null, null, 1);
assertEquals("Expected to limit data", 1, rowCount.intValue());
logger.debug(sb.toString());
// Limit by time and query up to and excluding the 'before' time
sb.delete(0, sb.length());
rowCount.setValue(0);
- auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, null, beforeTime, -1);
+ auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, null, null, beforeTime, -1);
logger.debug(sb.toString());
int resultsBefore = rowCount.intValue();
// Limit by time and query from and including the 'before' time
sb.delete(0, sb.length());
rowCount.setValue(0);
- auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, beforeTime, null, -1);
+ auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, null, beforeTime, null, -1);
logger.debug(sb.toString());
int resultsAfter = rowCount.intValue();
@@ -364,13 +370,13 @@ public class AuditComponentTest extends TestCase
sb.delete(0, sb.length());
rowCount.setValue(0);
- auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, user, null, null, -1);
+ auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, user, null, null, -1);
assertTrue("Expected some data for specific user", rowCount.intValue() > 0);
logger.debug(sb.toString());
sb.delete(0, sb.length());
rowCount.setValue(0);
- auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, "Numpty", null, null, -1);
+ auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, "Numpty", null, null, -1);
assertTrue("Expected no data for bogus user", rowCount.intValue() == 0);
logger.debug(sb.toString());
@@ -483,12 +489,17 @@ public class AuditComponentTest extends TestCase
;
return true;
}
+
+ public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
+ {
+ throw new AlfrescoRuntimeException(errorMsg, error);
+ }
};
auditService.clearAudit(APPLICATION_API_TEST);
results.clear();
sb.delete(0, sb.length());
- auditService.auditQuery(auditQueryCallback, APPLICATION_API_TEST, null, null, null, -1);
+ auditService.auditQuery(auditQueryCallback, true, APPLICATION_API_TEST, null, null, null, -1);
logger.debug(sb.toString());
assertTrue("There should be no audit entries for the API test after a clear", results.isEmpty());
@@ -522,7 +533,7 @@ public class AuditComponentTest extends TestCase
// Check that the call was audited
results.clear();
sb.delete(0, sb.length());
- auditService.auditQuery(auditQueryCallback, APPLICATION_API_TEST, null, null, null, -1);
+ auditService.auditQuery(auditQueryCallback, true, APPLICATION_API_TEST, null, null, null, -1);
logger.debug(sb.toString());
assertFalse("Did not get any audit results after successful login", results.isEmpty());
@@ -539,7 +550,7 @@ public class AuditComponentTest extends TestCase
}
results.clear();
sb.delete(0, sb.length());
- auditService.auditQuery(auditQueryCallback, APPLICATION_API_TEST, null, null, null, -1);
+ auditService.auditQuery(auditQueryCallback, true, APPLICATION_API_TEST, null, null, null, -1);
logger.debug(sb.toString());
assertFalse("Did not get any audit results after failed login", results.isEmpty());
}
diff --git a/source/java/org/alfresco/repo/audit/AuditServiceImpl.java b/source/java/org/alfresco/repo/audit/AuditServiceImpl.java
index 57e8168b15..5f494dd4cf 100644
--- a/source/java/org/alfresco/repo/audit/AuditServiceImpl.java
+++ b/source/java/org/alfresco/repo/audit/AuditServiceImpl.java
@@ -173,13 +173,15 @@ public class AuditServiceImpl implements AuditService
*/
public void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
int maxResults)
{
ParameterCheck.mandatory("callback", callback);
- auditComponent.auditQuery(callback, applicationName, user, from, to, maxResults);
+ auditComponent.auditQuery(
+ callback, forward, applicationName, user, from, to, maxResults);
}
/**
@@ -188,6 +190,7 @@ public class AuditServiceImpl implements AuditService
*/
public void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
String searchKey, Serializable searchValue,
int maxResults)
@@ -195,6 +198,7 @@ public class AuditServiceImpl implements AuditService
{
ParameterCheck.mandatory("callback", callback);
- auditComponent.auditQuery(callback, applicationName, user, from, to, searchKey, searchValue, maxResults);
+ auditComponent.auditQuery(
+ callback, forward, applicationName, user, from, to, searchKey, searchValue, maxResults);
}
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java
index 092612f318..2808904585 100644
--- a/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java
+++ b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java
@@ -740,6 +740,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
*/
public void findAuditEntries(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
int maxResults)
{
@@ -754,6 +755,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
*/
public void findAuditEntries(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
String searchKey, Serializable searchValue,
int maxResults)
diff --git a/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java b/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java
index d08c096708..839a5699f5 100644
--- a/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java
@@ -383,7 +383,10 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
if (auditValuesPair == null)
{
// Ignore
- logger.warn("Audit entry not joined to audit properties: " + row);
+ more = callback.handleAuditEntryError(
+ row.getAuditEntryId(),
+ "Audit entry not joined to audit properties: " + row,
+ null);
return;
}
auditValues = (Map) auditValuesPair.getSecond();
@@ -397,17 +400,26 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
}
catch (ClassCastException e)
{
- logger.warn("Audit entry not linked to a Map value: " + row);
+ more = callback.handleAuditEntryError(
+ row.getAuditEntryId(),
+ "Audit entry not linked to a Map value: " + row,
+ e);
return;
}
catch (Throwable e)
{
- logger.warn("Audit entry unable to extract audited values: " + row, e);
+ more = callback.handleAuditEntryError(
+ row.getAuditEntryId(),
+ "Audit entry unable to extract audited values: " + row,
+ e);
return;
}
if (auditValues == null)
{
- logger.warn("Audit entry incompletely joined to audit properties: " + row);
+ more = callback.handleAuditEntryError(
+ row.getAuditEntryId(),
+ "Audit entry incompletely joined to audit properties: " + row,
+ null);
return;
}
}
@@ -430,25 +442,28 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
public void findAuditEntries(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
int maxResults)
{
AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback);
- findAuditEntries(rowHandler, applicationName, user, from, to, maxResults, null, null);
+ findAuditEntries(rowHandler, forward, applicationName, user, from, to, maxResults, null, null);
}
public void findAuditEntries(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
String searchKey, Serializable searchValue,
int maxResults)
{
AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback);
- findAuditEntries(rowHandler, applicationName, user, from, to, maxResults, searchKey, searchValue);
+ findAuditEntries(rowHandler, forward, applicationName, user, from, to, maxResults, searchKey, searchValue);
}
protected abstract void findAuditEntries(
AuditQueryRowHandler rowHandler,
+ boolean forward,
String applicationName, String user, Long from, Long to, int maxResults,
String searchKey, Serializable searchValue);
}
diff --git a/source/java/org/alfresco/repo/domain/audit/AuditDAO.java b/source/java/org/alfresco/repo/domain/audit/AuditDAO.java
index e35d29573b..9f2e01b9e1 100644
--- a/source/java/org/alfresco/repo/domain/audit/AuditDAO.java
+++ b/source/java/org/alfresco/repo/domain/audit/AuditDAO.java
@@ -207,6 +207,8 @@ public interface AuditDAO
* Find audit entries using the given parameters, any of which may be null
*
* @param callback the data callback per entry
+ * @param forward true for results to ordered from first to last,
+ * or false to order from last to first
* @param applicationName the name of the application to search against (optional)
* @param user the user to search for (optional)
* @param from the minimum entry time (optional)
@@ -215,6 +217,7 @@ public interface AuditDAO
*/
void findAuditEntries(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to, int maxResults);
/**
@@ -230,6 +233,7 @@ public interface AuditDAO
*/
void findAuditEntries(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
String searchKey, Serializable searchValue,
int maxResults);
diff --git a/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java b/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java
index 6ca982ede9..28e7062de3 100644
--- a/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java
+++ b/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java
@@ -28,10 +28,12 @@ import java.io.File;
import java.io.Serializable;
import java.net.URL;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.Map;
import junit.framework.TestCase;
+import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.domain.audit.AuditDAO.AuditApplicationInfo;
import org.alfresco.repo.domain.contentdata.ContentDataDAO;
@@ -43,6 +45,7 @@ import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.Pair;
+import org.apache.commons.lang.mutable.MutableInt;
import org.springframework.context.ConfigurableApplicationContext;
/**
@@ -182,11 +185,13 @@ public class AuditDAOTest extends TestCase
return appName;
}
- public void testAuditQuery() throws Exception
+ public synchronized void testAuditQuery() throws Exception
{
// Some entries
doAuditEntryImpl(1);
+ final MutableInt count = new MutableInt(0);
+ final LinkedList timestamps = new LinkedList();
// Find everything, but look for a specific key
final AuditQueryCallback callback = new AuditQueryCallback()
{
@@ -197,20 +202,55 @@ public class AuditDAOTest extends TestCase
long time,
Map values)
{
- System.out.println(values);
+ count.setValue(count.intValue() + 1);
+ timestamps.add(time);
return true;
}
+
+ public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
+ {
+ throw new AlfrescoRuntimeException(errorMsg, error);
+ }
};
RetryingTransactionCallback findCallback = new RetryingTransactionCallback()
{
public Void execute() throws Throwable
{
- auditDAO.findAuditEntries(callback, null, null, null, null, "/a/b/c", null, -1);
+ auditDAO.findAuditEntries(callback, true, null, null, null, null, "/a/b/c", null, 2);
return null;
}
};
+ count.setValue(0);
+ timestamps.clear();
txnHelper.doInTransaction(findCallback);
+ assertTrue("Expected at least one result", count.intValue() > 0);
+
+ // Make sure that the last two entries are in forward order (ascending time)
+ Long lastTimestamp = timestamps.removeLast();
+ Long secondLastTimeStamp = timestamps.removeLast();
+ assertTrue("The timestamps should be in ascending order", lastTimestamp.compareTo(secondLastTimeStamp) > 0);
+
+ // Make sure that the last two entries differ in time
+ wait(1000L);
+
+ // Search in reverse order
+ doAuditEntryImpl(1);
+ RetryingTransactionCallback findReverseCallback = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ auditDAO.findAuditEntries(callback, false, null, null, null, null, "/a/b/c", null, 2);
+ return null;
+ }
+ };
+ timestamps.clear();
+ txnHelper.doInTransaction(findReverseCallback);
+
+ // Make sure that the last two entries are in reverse order (descending time)
+ lastTimestamp = timestamps.removeLast();
+ secondLastTimeStamp = timestamps.removeLast();
+ assertTrue("The timestamps should be in descending order", lastTimestamp.compareTo(secondLastTimeStamp) < 0);
}
public void testAuditDeleteEntries() throws Exception
@@ -227,6 +267,11 @@ public class AuditDAOTest extends TestCase
fail("Expected no results. All entries should have been removed.");
return false;
}
+
+ public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
+ {
+ throw new AlfrescoRuntimeException(errorMsg, error);
+ }
};
// Some entries
@@ -239,7 +284,7 @@ public class AuditDAOTest extends TestCase
Long appId = auditDAO.getAuditApplication(appName).getId();
auditDAO.deleteAuditEntries(appId, null, null);
// There should be no entries
- auditDAO.findAuditEntries(noResultsCallback, appName, null, null, null, -1);
+ auditDAO.findAuditEntries(noResultsCallback, true, appName, null, null, null, -1);
return null;
}
};
diff --git a/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java b/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java
index ea200ab562..1a6f5adbee 100644
--- a/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java
+++ b/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java
@@ -34,7 +34,7 @@ import java.util.Date;
*/
public class AuditQueryParameters
{
- private Long auditEntryId;
+ private boolean forward;
private Long auditAppNameId;
private Long auditUserId;
private Long auditFromTime;
@@ -51,25 +51,30 @@ public class AuditQueryParameters
{
StringBuilder sb = new StringBuilder(512);
sb.append("AuditEntryParameters")
- .append("[ auditEntryId=").append(auditEntryId)
+ .append("[ forward=").append(forward)
.append(", auditAppNameId=").append(auditAppNameId)
.append(", auditUserId=").append(auditUserId)
- .append(", auditFromTime").append(auditFromTime == null ? null : new Date(auditFromTime))
- .append(", auditToTime").append(auditToTime == null ? null : new Date(auditToTime))
- .append(", searchKeyId").append(searchKeyId)
- .append(", searchValueId").append(searchValueId)
+ .append(", auditFromTime=").append(auditFromTime == null ? null : new Date(auditFromTime))
+ .append(", auditToTime=").append(auditToTime == null ? null : new Date(auditToTime))
+ .append(", searchKeyId=").append(searchKeyId)
+ .append(", searchValueId=").append(searchValueId)
.append("]");
return sb.toString();
}
- public Long getAuditEntryId()
+ public boolean isForward()
{
- return auditEntryId;
+ return forward;
}
- public void setAuditEntryId(Long entryId)
+ public void setForward(boolean forward)
{
- this.auditEntryId = entryId;
+ this.forward = forward;
+ }
+
+ public boolean isForwardTrue()
+ {
+ return true;
}
public Long getAuditAppNameId()
diff --git a/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java b/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java
index db92801fd9..c64ebb19fc 100644
--- a/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java
@@ -29,7 +29,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import org.alfresco.ibatis.RollupRowHandler;
import org.alfresco.repo.domain.audit.AbstractAuditDAOImpl;
@@ -194,6 +193,7 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
@Override
protected void findAuditEntries(
final AuditQueryRowHandler rowHandler,
+ boolean forward,
String appName, String user, Long from, Long to, int maxResults,
String searchKey, Serializable searchValue)
{
@@ -244,12 +244,13 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
}
params.setSearchValueId(searchValuePair.getFirst());
}
+ params.setForward(forward);
if (maxResults > 0)
{
// Query without getting the values. We gather all the results and batch-fetch the audited
// values afterwards.
- final TreeMap resultsByValueId = new TreeMap();
+ final Map resultsByValueId = new HashMap(173);
PropertyFinderCallback propertyFinderCallback = new PropertyFinderCallback()
{
public void handleProperty(Long id, Serializable value)
@@ -264,7 +265,6 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
{
// The handler will deal with the entry
}
- rowHandler.processResult(row);
}
};
@@ -288,6 +288,11 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
List valueIds = new ArrayList(resultsByValueId.keySet());
propertyValueDAO.getPropertiesByIds(valueIds, propertyFinderCallback);
}
+ // Now pass the filled-out results to the row handler (order-preserved)
+ for (AuditQueryResult row : rows)
+ {
+ rowHandler.processResult(row);
+ }
}
else
{
diff --git a/source/java/org/alfresco/service/cmr/audit/AuditService.java b/source/java/org/alfresco/service/cmr/audit/AuditService.java
index b173e37b93..037a397538 100644
--- a/source/java/org/alfresco/service/cmr/audit/AuditService.java
+++ b/source/java/org/alfresco/service/cmr/audit/AuditService.java
@@ -168,12 +168,24 @@ public interface AuditService
String user,
long time,
Map values);
+
+ /**
+ * Handle audit entry failures
+ *
+ * @param entryId the entry ID
+ * @param errorMsg the error message
+ * @param error the exception causing the error (may be null)
+ * @return Return true to continue processing rows or false to stop
+ */
+ boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error);
}
/**
* Get the audit entries that match the given criteria.
*
* @param callback the callback that will handle results
+ * @param forward true for results to ordered from first to last,
+ * or false to order from last to first
* @param applicationName if not null, find entries logged against this application
* @param user if not null, find entries logged against this user
* @param from the start search time (null to start at the beginning)
@@ -184,6 +196,7 @@ public interface AuditService
*/
void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
int maxResults);
@@ -191,6 +204,8 @@ public interface AuditService
* Get the audit entries that match the given criteria.
*
* @param callback the callback that will handle results
+ * @param forward true for results to ordered from first to last,
+ * or false to order from last to first
* @param applicationName if not null, find entries logged against this application
* @param user if not null, find entries logged against this user
* @param from the start search time (null to start at the beginning)
@@ -203,6 +218,7 @@ public interface AuditService
*/
void auditQuery(
AuditQueryCallback callback,
+ boolean forward,
String applicationName, String user, Long from, Long to,
String searchKey, Serializable searchValue,
int maxResults);