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;
}
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;
}
Aggregations