use of org.nuxeo.ecm.platform.audit.api.AuditReader in project nuxeo-drive-server by nuxeo.
the class AuditChangeFinder method getUpperBound.
/**
* Return the last available log id in the audit log table (primary key) to be used as the upper bound of the event
* log id range clause in the change query.
*/
@Override
@SuppressWarnings("unchecked")
public long getUpperBound() {
AuditReader auditService = Framework.getService(AuditReader.class);
String auditQuery = "from LogEntry log order by log.id desc";
if (log.isDebugEnabled()) {
log.debug("Querying audit log for greatest id: " + auditQuery);
}
List<LogEntry> entries = (List<LogEntry>) auditService.nativeQuery(auditQuery, 1, 1);
if (entries.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("Found no audit log entries, returning -1");
}
return -1;
}
return entries.get(0).getId();
}
use of org.nuxeo.ecm.platform.audit.api.AuditReader in project nuxeo-drive-server by nuxeo.
the class AuditChangeFinder method queryAuditEntries.
@SuppressWarnings("unchecked")
protected List<LogEntry> queryAuditEntries(CoreSession session, SynchronizationRoots activeRoots, Set<String> collectionSyncRootMemberIds, long lowerBound, long upperBound, boolean integerBounds, int limit) {
AuditReader auditService = Framework.getService(AuditReader.class);
// Set fixed query parameters
Map<String, Object> params = new HashMap<String, Object>();
params.put("repositoryId", session.getRepositoryName());
// Build query and set dynamic parameters
StringBuilder auditQuerySb = new StringBuilder("from LogEntry log where ");
auditQuerySb.append("log.repositoryId = :repositoryId");
auditQuerySb.append(" and ");
auditQuerySb.append("(");
if (!activeRoots.getPaths().isEmpty()) {
// detect changes under the currently active roots for the
// current user
auditQuerySb.append("(");
auditQuerySb.append("log.category = 'eventDocumentCategory'");
// TODO: don't hardcode event ids (contribute them?)
auditQuerySb.append(" and (log.eventId = 'documentCreated' or log.eventId = 'documentModified' or log.eventId = 'documentMoved' or log.eventId = 'documentCreatedByCopy' or log.eventId = 'documentRestored' or log.eventId = 'addedToCollection' or log.eventId = 'documentProxyPublished' or log.eventId = 'documentLocked' or log.eventId = 'documentUnlocked')");
auditQuerySb.append(" or ");
auditQuerySb.append("log.category = 'eventLifeCycleCategory'");
auditQuerySb.append(" and log.eventId = 'lifecycle_transition_event' and log.docLifeCycle != 'deleted' ");
auditQuerySb.append(") and (");
auditQuerySb.append("(");
auditQuerySb.append(getCurrentRootFilteringClause(activeRoots.getPaths(), params));
auditQuerySb.append(")");
if (collectionSyncRootMemberIds != null && !collectionSyncRootMemberIds.isEmpty()) {
auditQuerySb.append(" or (");
auditQuerySb.append(getCollectionSyncRootFilteringClause(collectionSyncRootMemberIds, params));
auditQuerySb.append(")");
}
auditQuerySb.append(") or ");
}
// Detect any root (un-)registration changes for the roots previously
// seen by the current user.
// Exclude 'rootUnregistered' since root unregistration is covered by a
// "deleted" virtual event.
auditQuerySb.append("(");
auditQuerySb.append("log.category = '");
auditQuerySb.append(NuxeoDriveEvents.EVENT_CATEGORY);
auditQuerySb.append("' and log.eventId != 'rootUnregistered'");
auditQuerySb.append(")");
auditQuerySb.append(") and (");
auditQuerySb.append(getJPARangeClause(lowerBound, upperBound, integerBounds, params));
// we intentionally sort by eventDate even if the range filtering is
// done on the log id: eventDate is useful to reflect the ordering of
// events occurring inside the same transaction while the
// monotonic behavior of log id is useful for ensuring that consecutive
// range queries to the audit won't miss any events even when long
// running transactions are logged after a delay.
auditQuerySb.append(") order by log.repositoryId asc, log.eventDate desc");
String auditQuery = auditQuerySb.toString();
if (log.isDebugEnabled()) {
log.debug("Querying audit log for changes: " + auditQuery + " with params: " + params);
}
List<LogEntry> entries = (List<LogEntry>) auditService.nativeQuery(auditQuery, params, 1, limit);
// Post filter the output to remove (un)registration that are unrelated
// to the current user.
List<LogEntry> postFilteredEntries = new ArrayList<LogEntry>();
String principalName = session.getPrincipal().getName();
for (LogEntry entry : entries) {
ExtendedInfo impactedUserInfo = entry.getExtendedInfos().get("impactedUserName");
if (impactedUserInfo != null && !principalName.equals(impactedUserInfo.getValue(String.class))) {
// ignore event that only impact other users
continue;
}
if (log.isDebugEnabled()) {
log.debug(String.format("Change detected: %s", entry));
}
postFilteredEntries.add(entry);
}
return postFilteredEntries;
}
use of org.nuxeo.ecm.platform.audit.api.AuditReader in project nuxeo-drive-server by nuxeo.
the class AuditChangeFinder method getUpperBound.
/**
* Returns the last available log id in the audit log table (primary key) considering events older than the last
* clustering invalidation date if clustering is enabled for at least one of the given repositories. This is to make
* sure the {@code DocumentModel} further fetched from the session using the audit entry doc id is fresh.
*/
@Override
@SuppressWarnings("unchecked")
public long getUpperBound(Set<String> repositoryNames) {
long clusteringDelay = getClusteringDelay(repositoryNames);
AuditReader auditService = Framework.getService(AuditReader.class);
Map<String, Object> params = new HashMap<String, Object>();
StringBuilder auditQuerySb = new StringBuilder("from LogEntry log");
if (clusteringDelay > -1) {
// Double the delay in case of overlapping, see https://jira.nuxeo.com/browse/NXP-14826
long lastClusteringInvalidationDate = System.currentTimeMillis() - 2 * clusteringDelay;
params.put("lastClusteringInvalidationDate", new Date(lastClusteringInvalidationDate));
auditQuerySb.append(" where log.logDate < :lastClusteringInvalidationDate");
}
auditQuerySb.append(" order by log.id desc");
String auditQuery = auditQuerySb.toString();
if (log.isDebugEnabled()) {
log.debug("Querying audit log for greatest id: " + auditQuery + " with params: " + params);
}
List<LogEntry> entries = (List<LogEntry>) auditService.nativeQuery(auditQuery, params, 1, 1);
if (entries.isEmpty()) {
if (clusteringDelay > -1) {
// Check for existing entries without the clustering invalidation date filter to not return -1 in this
// case and make sure the lower bound of the next call to NuxeoDriveManager#getChangeSummary will be >=
// 0
List<LogEntry> allEntries = (List<LogEntry>) auditService.nativeQuery("from LogEntry", 1, 1);
if (!allEntries.isEmpty()) {
log.debug("Found no audit log entries matching the criterias but some exist, returning 0");
return 0;
}
}
log.debug("Found no audit log entries, returning -1");
return -1;
}
return entries.get(0).getId();
}
Aggregations