private bool CheckInsideChange(IFolder targetIFolder, IChangeEvents changeTokens) { var children = targetIFolder.GetChildren(); var leafFolders = children.OfType <IFolder>(); var leafFiles = children.OfType <IDocument>(); var changed = leafFolders.Any(childFolder => changeTokens.ChangeEventList.Any(change => childFolder.Id == change.ObjectId)) || leafFiles.Any(childFile => changeTokens.ChangeEventList.Any(change => childFile.VersionSeriesId == change.Properties["versionSeriesId"][0] as string)) ; if (changed) { return(true); } foreach (var leafFolder in leafFolders) { changed = CheckInsideChange(leafFolder, changeTokens); if (changed) { return(true); } } return(false); }
/// <summary> /// Synchronize using the ChangeLog feature of CMIS. /// Not all CMIS servers support this feature, so sometimes CrawlStrategy is used instead. /// </summary> private void ChangeLogSync(IFolder remoteFolder) { // Get last ChangeLog token on server side. string lastTokenOnServer = session.Binding.GetRepositoryService().GetRepositoryInfo(session.RepositoryInfo.Id, null).LatestChangeLogToken; // Get last ChangeLog token that had been saved on client side. // TODO catch exception invalidArgument which means that changelog has been truncated and this token is not found anymore. string lastTokenOnClient = database.GetChangeLogToken(); if (lastTokenOnClient == null) { // Token is null, which means no sync has ever happened yet, so just copy everything. RecursiveFolderCopy(remoteFolder, repoinfo.TargetDirectory); // Update ChangeLog token. Logger.Info("Sync | Updating ChangeLog token: " + lastTokenOnServer); database.SetChangeLogToken(lastTokenOnServer); } else { // If there are remote changes, apply them. if (lastTokenOnServer.Equals(lastTokenOnClient)) { Logger.Info("Sync | No changes on server, ChangeLog token: " + lastTokenOnServer); } else { // Check which files/folders have changed. int maxNumItems = 1000; IChangeEvents changes = session.GetContentChanges(lastTokenOnClient, true, maxNumItems); // Replicate each change to the local side. foreach (IChangeEvent change in changes.ChangeEventList) { ApplyRemoteChange(change); } // Save ChangeLog token locally. // TODO only if successful Logger.Info("Sync | Updating ChangeLog token: " + lastTokenOnServer); database.SetChangeLogToken(lastTokenOnServer); } // Upload local changes by comparing with database. // TODO } }
public void SmokeTestContentChanges() { if (Session.RepositoryInfo.Capabilities.ChangesCapability != null) { if (Session.RepositoryInfo.Capabilities.ChangesCapability != CapabilityChanges.None) { IChangeEvents changeEvents = Session.GetContentChanges(null, true, 1000); Assert.NotNull(changeEvents); } else { Console.WriteLine("Content changes not supported!"); } } else { Console.WriteLine("ChangesCapability not set!"); } }
/// <summary> /// Synchronize using the ChangeLog feature of CMIS. /// Not all CMIS servers support this feature, so sometimes CrawlStrategy is used instead. /// </summary> private void ChangeLogSync(IFolder remoteFolder) { // Get last change log token on server side. session.Binding.GetRepositoryService().GetRepositoryInfos(null); // refresh string lastTokenOnServer = session.Binding.GetRepositoryService().GetRepositoryInfo(session.RepositoryInfo.Id, null).LatestChangeLogToken; // Get last change token that had been saved on client side. // TODO catch exception invalidArgument which means that changelog has been truncated and this token is not found anymore. string lastTokenOnClient = database.GetChangeLogToken(); if (lastTokenOnClient == lastTokenOnServer) { Logger.Debug("No change from remote, wait for the next time."); return; } if (lastTokenOnClient == null) { // Token is null, which means no sync has ever happened yet, so just sync everything from remote. CrawlRemote(remoteFolder, repoinfo.TargetDirectory, null, null); Logger.Info("Succeeded to sync from remote, update ChangeLog token: " + lastTokenOnServer); database.SetChangeLogToken(lastTokenOnServer); } do { Config.Feature f = null; if (ConfigManager.CurrentConfig.getFolder(repoinfo.Name) != null) { f = ConfigManager.CurrentConfig.getFolder(repoinfo.Name).SupportedFeatures; } int maxNumItems = (f != null && f.MaxNumberOfContentChanges != null)? (int)f.MaxNumberOfContentChanges: 100; // Check which files/folders have changed. IChangeEvents changes = session.GetContentChanges(lastTokenOnClient, IsPropertyChangesSupported, maxNumItems); // Replicate each change to the local side. bool success = true; foreach (IChangeEvent change in changes.ChangeEventList) { try { switch (change.ChangeType) { case ChangeType.Created: Logger.Info("New remote object (" + change.ObjectId + ") found."); goto case ChangeType.Updated; case ChangeType.Updated: if (change.ChangeType == ChangeType.Updated) { Logger.Info("Remote object (" + change.ObjectId + ") has been changed remotely."); } success = ApplyRemoteChangeUpdate(change) && success; break; case ChangeType.Deleted: Logger.Info("Remote object (" + change.ObjectId + ") has been deleted remotely."); success = ApplyRemoteChangeDelete(change) && success; break; default: break; } } catch (Exception e) { Logger.Warn("Exception when apply the change: ", e); success = false; } } if (success) { // Save change log token locally. if (changes.HasMoreItems == true) { lastTokenOnClient = changes.LatestChangeLogToken; } else { lastTokenOnClient = lastTokenOnServer; } Logger.Info("Sync the changes on server, update ChangeLog token: " + lastTokenOnClient); database.SetChangeLogToken(lastTokenOnClient); session.Binding.GetRepositoryService().GetRepositoryInfos(null); // refresh lastTokenOnServer = session.Binding.GetRepositoryService().GetRepositoryInfo(session.RepositoryInfo.Id, null).LatestChangeLogToken; } else { Logger.Warn("Failure to sync the changes on server, force crawl sync from remote"); CrawlRemote(remoteFolder, repoinfo.TargetDirectory, null, null); Logger.Info("Succeeded to sync from remote, update ChangeLog token: " + lastTokenOnServer); database.SetChangeLogToken(lastTokenOnServer); return; } }while (!lastTokenOnServer.Equals(lastTokenOnClient)); }
private void Sync() { // Get last change log token on server side. this.session.Binding.GetRepositoryService().GetRepositoryInfos(null); // refresh string lastTokenOnServer = this.session.Binding.GetRepositoryService().GetRepositoryInfo(this.session.RepositoryInfo.Id, null).LatestChangeLogToken; // Get last change token that had been saved on client side. string lastTokenOnClient = this.storage.ChangeLogToken; if (lastTokenOnClient == null) { // Token is null, which means no content change sync has ever happened yet, so just sync everything from remote. // Force full sync var fullsyncevent = new StartNextSyncEvent(true); Queue.AddEvent(fullsyncevent); return; } do { // Check which files/folders have changed. IChangeEvents changes = this.session.GetContentChanges(lastTokenOnClient, this.isPropertyChangesSupported, this.maxNumberOfContentChanges); // Replicate each change to the local side. bool first = true; foreach (IChangeEvent change in changes.ChangeEventList) { // ignore first event when lists overlapp if (first) { first = false; if (this.lastChange != null && (this.lastChange.ChangeType == DotCMIS.Enums.ChangeType.Created || this.lastChange.ChangeType == DotCMIS.Enums.ChangeType.Deleted)) { if (change != null && change.ChangeType == this.lastChange.ChangeType && change.ObjectId == this.lastChange.ObjectId) { continue; } } } this.lastChange = change; Queue.AddEvent(new ContentChangeEvent(change.ChangeType, change.ObjectId)); } // Save change log token locally. if (changes.HasMoreItems == true) { lastTokenOnClient = changes.LatestChangeLogToken; } else { lastTokenOnClient = lastTokenOnServer; } this.storage.ChangeLogToken = lastTokenOnClient; // refresh this.session.Binding.GetRepositoryService().GetRepositoryInfos(null); lastTokenOnServer = this.session.Binding.GetRepositoryService().GetRepositoryInfo(this.session.RepositoryInfo.Id, null).LatestChangeLogToken; } while (!lastTokenOnServer.Equals(lastTokenOnClient)); }
private bool CheckInsideChange(IFolder targetIFolder, IChangeEvents changeTokens) { var children = targetIFolder.GetChildren(); var leafFolders = children.OfType<IFolder>(); var leafFiles = children.OfType<IDocument>(); var changed = leafFolders.Any(childFolder => changeTokens.ChangeEventList.Any(change => childFolder.Id == change.ObjectId)) || leafFiles.Any(childFile => changeTokens.ChangeEventList.Any(change => childFile.VersionSeriesId == change.Properties["versionSeriesId"][0] as string)) ; if (changed) return true; foreach (var leafFolder in leafFolders) { changed = CheckInsideChange(leafFolder, changeTokens); if (changed) return true; } return false; }