Search in sources :

Example 1 with TooManyChangesException

use of org.nuxeo.drive.service.TooManyChangesException in project nuxeo-drive-server by nuxeo.

the class AuditChangeFinder method getFileSystemChanges.

protected List<FileSystemItemChange> getFileSystemChanges(CoreSession session, Set<IdRef> lastActiveRootRefs, SynchronizationRoots activeRoots, Set<String> collectionSyncRootMemberIds, long lowerBound, long upperBound, boolean integerBounds, int limit) throws TooManyChangesException {
    String principalName = session.getPrincipal().getName();
    List<FileSystemItemChange> changes = new ArrayList<FileSystemItemChange>();
    // Note: lastActiveRootRefs is not used: we could remove it from the
    // public API
    // and from the client as well but it might be useful to optimize future
    // alternative implementations FileSystemChangeFinder component so it
    // might
    // be better to leave it part of the public API as currently.
    // Find changes from the log under active roots or events that are
    // linked to the un-registration or deletion of formerly synchronized
    // roots
    List<LogEntry> entries = queryAuditEntries(session, activeRoots, collectionSyncRootMemberIds, lowerBound, upperBound, integerBounds, limit);
    // query with the actual active roots.
    for (LogEntry entry : entries) {
        if (NuxeoDriveEvents.EVENT_CATEGORY.equals(entry.getCategory())) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("Detected sync root change for user '%s' in audit log:" + " invalidating the root cache and refetching the changes.", principalName));
            }
            NuxeoDriveManager driveManager = Framework.getService(NuxeoDriveManager.class);
            driveManager.invalidateSynchronizationRootsCache(principalName);
            driveManager.invalidateCollectionSyncRootMemberCache(principalName);
            Map<String, SynchronizationRoots> synchronizationRoots = driveManager.getSynchronizationRoots(session.getPrincipal());
            SynchronizationRoots updatedActiveRoots = synchronizationRoots.get(session.getRepositoryName());
            Set<String> updatedCollectionSyncRootMemberIds = driveManager.getCollectionSyncRootMemberIds(session.getPrincipal()).get(session.getRepositoryName());
            entries = queryAuditEntries(session, updatedActiveRoots, updatedCollectionSyncRootMemberIds, lowerBound, upperBound, integerBounds, limit);
            break;
        }
    }
    if (entries.size() >= limit) {
        throw new TooManyChangesException("Too many changes found in the audit logs.");
    }
    for (LogEntry entry : entries) {
        if (log.isDebugEnabled()) {
            log.debug(String.format("Handling log entry %s", entry));
        }
        FileSystemItemChange change = null;
        DocumentRef docRef = new IdRef(entry.getDocUUID());
        ExtendedInfo fsIdInfo = entry.getExtendedInfos().get("fileSystemItemId");
        if (fsIdInfo != null) {
            // been updated, we just know the FileSystemItem id and name.
            if (log.isDebugEnabled()) {
                log.debug(String.format("Found extended info in audit log entry: document has been deleted, moved," + " is an unregistered synchronization root or its security has been updated," + " we just know the FileSystemItem id and name."));
            }
            boolean isChangeSet = false;
            // current user still has access to the document.
            if (!"deleted".equals(entry.getEventId()) && session.exists(docRef)) {
                change = getFileSystemItemChange(session, docRef, entry, fsIdInfo.getValue(String.class));
                if (change != null) {
                    if (NuxeoDriveEvents.MOVED_EVENT.equals(entry.getEventId())) {
                        // virtual event.
                        if (log.isDebugEnabled()) {
                            log.debug(String.format("Document %s (%s) has been moved to another synchronzation root, not adding entry to the change summary.", entry.getDocPath(), docRef));
                        }
                        continue;
                    }
                    isChangeSet = true;
                }
            }
            if (!isChangeSet) {
                // FileSystemItem id and name to the FileSystemItemChange entry.
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Document %s (%s) doesn't exist or is not adaptable as a FileSystemItem, only providing the FileSystemItem id and name to the FileSystemItemChange entry.", entry.getDocPath(), docRef));
                }
                String fsId = fsIdInfo.getValue(String.class);
                String eventId;
                if (NuxeoDriveEvents.MOVED_EVENT.equals(entry.getEventId())) {
                    // Move to a non synchronization root
                    eventId = NuxeoDriveEvents.DELETED_EVENT;
                } else {
                    // Deletion, unregistration or security update
                    eventId = entry.getEventId();
                }
                change = new FileSystemItemChangeImpl(eventId, entry.getEventDate().getTime(), entry.getRepositoryId(), entry.getDocUUID(), fsId, null);
            }
            if (log.isDebugEnabled()) {
                log.debug(String.format("Adding FileSystemItemChange entry to the change summary: %s", change));
            }
            changes.add(change);
        } else {
            // unregistered synchronization root nor a security update denying access to the current user.
            if (log.isDebugEnabled()) {
                log.debug(String.format("No extended info found in audit log entry %s (%s): this is not a deleted document, a moved document," + " an unregistered synchronization root nor a security update denying access to the current user.", entry.getDocPath(), docRef));
            }
            if (!session.exists(docRef)) {
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Document %s (%s) doesn't exist, not adding entry to the change summary.", entry.getDocPath(), docRef));
                }
                // try to propagate this event.
                continue;
            }
            // Let's try to adapt the document as a FileSystemItem to
            // provide it to the FileSystemItemChange entry.
            change = getFileSystemItemChange(session, docRef, entry, null);
            if (change == null) {
                // Non-adaptable documents are ignored
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Document %s (%s) is not adaptable as a FileSystemItem, not adding any entry to the change summary.", entry.getDocPath(), docRef));
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Adding FileSystemItemChange entry to the change summary: %s", change));
                }
                changes.add(change);
            }
        }
    }
    return changes;
}
Also used : DocumentRef(org.nuxeo.ecm.core.api.DocumentRef) ArrayList(java.util.ArrayList) SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots) IdRef(org.nuxeo.ecm.core.api.IdRef) ExtendedInfo(org.nuxeo.ecm.platform.audit.api.ExtendedInfo) FileSystemItemChange(org.nuxeo.drive.service.FileSystemItemChange) TooManyChangesException(org.nuxeo.drive.service.TooManyChangesException) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry) NuxeoDriveManager(org.nuxeo.drive.service.NuxeoDriveManager)

Example 2 with TooManyChangesException

use of org.nuxeo.drive.service.TooManyChangesException in project nuxeo-drive-server by nuxeo.

the class NuxeoDriveManagerImpl method getChangeSummary.

protected FileSystemChangeSummary getChangeSummary(Principal principal, Map<String, Set<IdRef>> lastActiveRootRefs, Map<String, SynchronizationRoots> roots, Map<String, Set<String>> collectionSyncRootMemberIds, long lowerBound, boolean integerBounds) {
    List<FileSystemItemChange> allChanges = new ArrayList<FileSystemItemChange>();
    // Compute the list of all repositories to consider for the aggregate summary
    Set<String> allRepositories = new TreeSet<String>();
    allRepositories.addAll(roots.keySet());
    allRepositories.addAll(lastActiveRootRefs.keySet());
    allRepositories.addAll(collectionSyncRootMemberIds.keySet());
    long syncDate;
    long upperBound;
    if (integerBounds) {
        upperBound = changeFinder.getUpperBound(allRepositories);
        // Truncate sync date to 0 milliseconds
        syncDate = System.currentTimeMillis();
        syncDate = syncDate - (syncDate % 1000);
    } else {
        upperBound = changeFinder.getCurrentDate();
        syncDate = upperBound;
    }
    Boolean hasTooManyChanges = Boolean.FALSE;
    int limit = Integer.parseInt(Framework.getProperty(DOCUMENT_CHANGE_LIMIT_PROPERTY, "1000"));
    if (!allRepositories.isEmpty() && lowerBound >= 0 && upperBound > lowerBound) {
        for (String repositoryName : allRepositories) {
            try (CloseableCoreSession session = CoreInstance.openCoreSession(repositoryName, principal)) {
                // Get document changes
                Set<IdRef> lastRefs = lastActiveRootRefs.get(repositoryName);
                if (lastRefs == null) {
                    lastRefs = Collections.emptySet();
                }
                SynchronizationRoots activeRoots = roots.get(repositoryName);
                if (activeRoots == null) {
                    activeRoots = SynchronizationRoots.getEmptyRoots(repositoryName);
                }
                Set<String> repoCollectionSyncRootMemberIds = collectionSyncRootMemberIds.get(repositoryName);
                if (repoCollectionSyncRootMemberIds == null) {
                    repoCollectionSyncRootMemberIds = Collections.emptySet();
                }
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Start: getting FileSystemItem changes for repository %s / user %s between %s and %s with activeRoots = %s", repositoryName, principal.getName(), lowerBound, upperBound, activeRoots.getPaths()));
                }
                List<FileSystemItemChange> changes;
                if (integerBounds) {
                    changes = changeFinder.getFileSystemChangesIntegerBounds(session, lastRefs, activeRoots, repoCollectionSyncRootMemberIds, lowerBound, upperBound, limit);
                } else {
                    changes = changeFinder.getFileSystemChanges(session, lastRefs, activeRoots, lowerBound, upperBound, limit);
                }
                allChanges.addAll(changes);
            } catch (TooManyChangesException e) {
                hasTooManyChanges = Boolean.TRUE;
                allChanges.clear();
                break;
            }
        }
    }
    // Send back to the client the list of currently active roots to be able
    // to efficiently detect root unregistration events for the next
    // incremental change summary
    Map<String, Set<IdRef>> activeRootRefs = new HashMap<String, Set<IdRef>>();
    for (Map.Entry<String, SynchronizationRoots> rootsEntry : roots.entrySet()) {
        activeRootRefs.put(rootsEntry.getKey(), rootsEntry.getValue().getRefs());
    }
    FileSystemChangeSummary summary = new FileSystemChangeSummaryImpl(allChanges, activeRootRefs, syncDate, upperBound, hasTooManyChanges);
    if (log.isDebugEnabled()) {
        log.debug(String.format("End: getting %d FileSystemItem changes for user %s between %s and %s with activeRoots = %s -> %s", allChanges.size(), principal.getName(), lowerBound, upperBound, roots, summary));
    }
    return summary;
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) FileSystemChangeSummary(org.nuxeo.drive.service.FileSystemChangeSummary) ArrayList(java.util.ArrayList) CloseableCoreSession(org.nuxeo.ecm.core.api.CloseableCoreSession) SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots) IdRef(org.nuxeo.ecm.core.api.IdRef) TreeSet(java.util.TreeSet) FileSystemItemChange(org.nuxeo.drive.service.FileSystemItemChange) TooManyChangesException(org.nuxeo.drive.service.TooManyChangesException) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

ArrayList (java.util.ArrayList)2 FileSystemItemChange (org.nuxeo.drive.service.FileSystemItemChange)2 SynchronizationRoots (org.nuxeo.drive.service.SynchronizationRoots)2 TooManyChangesException (org.nuxeo.drive.service.TooManyChangesException)2 IdRef (org.nuxeo.ecm.core.api.IdRef)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 Set (java.util.Set)1 TreeSet (java.util.TreeSet)1 FileSystemChangeSummary (org.nuxeo.drive.service.FileSystemChangeSummary)1 NuxeoDriveManager (org.nuxeo.drive.service.NuxeoDriveManager)1 CloseableCoreSession (org.nuxeo.ecm.core.api.CloseableCoreSession)1 DocumentRef (org.nuxeo.ecm.core.api.DocumentRef)1 ExtendedInfo (org.nuxeo.ecm.platform.audit.api.ExtendedInfo)1 LogEntry (org.nuxeo.ecm.platform.audit.api.LogEntry)1