Search in sources :

Example 1 with AuditReader

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();
}
Also used : ArrayList(java.util.ArrayList) List(java.util.List) AuditReader(org.nuxeo.ecm.platform.audit.api.AuditReader) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Example 2 with AuditReader

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;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) AuditReader(org.nuxeo.ecm.platform.audit.api.AuditReader) ExtendedInfo(org.nuxeo.ecm.platform.audit.api.ExtendedInfo) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Example 3 with AuditReader

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();
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) List(java.util.List) AuditReader(org.nuxeo.ecm.platform.audit.api.AuditReader) Date(java.util.Date) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Aggregations

ArrayList (java.util.ArrayList)3 List (java.util.List)3 AuditReader (org.nuxeo.ecm.platform.audit.api.AuditReader)3 LogEntry (org.nuxeo.ecm.platform.audit.api.LogEntry)3 HashMap (java.util.HashMap)2 Date (java.util.Date)1 ExtendedInfo (org.nuxeo.ecm.platform.audit.api.ExtendedInfo)1