public override void FinalizeItemWrite(Stream stream, EntryUpdateInfo updateInfo) { stream.Flush(); stream.Close(); SyncEntryAdapterData adapterEntry = updateInfo.Entry.AdapterEntries.FirstOrDefault(e => e.AdapterId == this.Config.Id); if (adapterEntry == null) { adapterEntry = new SyncEntryAdapterData() { SyncEntry = updateInfo.Entry, AdapterId = this.Configuration.Id, }; // [2018-04-30] It appears that the SyncEntryId field needs to be set on the adapter entry // in order to avoid a referential integrity violation in the DB. adapterEntry.SyncEntryId = updateInfo.Entry.Id; updateInfo.Entry.AdapterEntries.Add(adapterEntry); } string fullPath; using (var db = this.Relationship.GetDatabase()) { fullPath = Path.Combine( this.Config.RootDirectory, updateInfo.Entry.GetRelativePath(db, this.PathSeparator)); } adapterEntry.AdapterEntryId = GetItemId(fullPath, false); }
public override void UpdateItem(EntryUpdateInfo updateInfo, SyncEntryChangedFlags changeFlags) { if (updateInfo.Entry.Type == SyncEntryType.Directory) { Logger.Debug("Suppressing UpdateItem() call for Directory in BackblazeB2 adapter"); return; } // The changeFlags parameter is passed by value, so we will modify it as we go to unset // the properties that we change. If we are left with a changeFlags that is non-zero, // then we missed a case. if ((changeFlags & SyncEntryChangedFlags.ModifiedTimestamp) != 0) { Pre.Assert(updateInfo.ModifiedDateTimeUtcNew != null, "updateInfo.ModifiedDateTimeUtcNew != null"); // No action needed at the remote end. Updating the blob will update the Last-Modified // property. However, we do need to update the Entry. updateInfo.Entry.ModifiedDateTimeUtc = updateInfo.ModifiedDateTimeUtcNew.Value; changeFlags &= ~SyncEntryChangedFlags.ModifiedTimestamp; } if (changeFlags != SyncEntryChangedFlags.None) { throw new NotImplementedException("changeFlags = " + changeFlags); } }
public EntryProcessingContext( EntryUpdateInfo entryUpdateInfo, SemaphoreSlim semaphore) { this.EntryUpdateInfo = entryUpdateInfo; this.Semaphore = semaphore; }
public override void FinalizeItemWrite(Stream stream, EntryUpdateInfo updateInfo) { string fileId; if (stream is BackblazeB2LargeUploadStream largeUploadStream) { long size = largeUploadStream.Session.Entry.GetSize(this.Relationship, SyncEntryPropertyLocation.Destination); if (largeUploadStream.Session.BytesUploaded != size) { // TODO: Cancel the upload? throw new Exception( string.Format( "File size if {0}, but uploaded {1}", size, largeUploadStream.Session.BytesUploaded)); } // Allocate the hash array to contain exactly the expected number of hashes string[] partSha1Array = new string[largeUploadStream.Session.CurrentPartNumber]; for (int i = 1; i < largeUploadStream.Session.CurrentPartNumber; i++) { partSha1Array[i] = largeUploadStream.Session.PartHashes[i]; } this.backblazeClient.FinishLargeFile( largeUploadStream.Session.StartLargeFileResponse.FileId, partSha1Array).Wait(); fileId = largeUploadStream.Session.UploadResponse.FileId; } else if (stream is BackblazeB2UploadStream uploadStream) { uploadStream.Flush(); fileId = uploadStream.Session.UploadResponse.FileId; } else { throw new NotImplementedException(); } SyncEntryAdapterData adapterData = updateInfo.Entry.AdapterEntries.FirstOrDefault(a => a.AdapterId == this.Configuration.Id); if (adapterData == null) { adapterData = new SyncEntryAdapterData { SyncEntry = updateInfo.Entry, AdapterId = this.Configuration.Id }; updateInfo.Entry.AdapterEntries.Add(adapterData); } adapterData.AdapterEntryId = fileId; }
public override void UpdateItem(EntryUpdateInfo updateInfo, SyncEntryChangedFlags changeFlags) { if (updateInfo.Entry.Type == SyncEntryType.Directory) { Logger.Debug("Suppressing UpdateItem() call for Directory in BackblazeB2 adapter"); return; } throw new NotImplementedException(); }
public void BasicOrder() { List <EntryUpdateInfo> input = new List <EntryUpdateInfo> { EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.Deleted, @"a\b\c"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.NewDirectory, @"a\b\c\d"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.FileSize, @"a\b\c\e"), }; input.Sort(new EntryProcessingSorter()); Assert.AreEqual(0, input.FindIndex(e => e.RelativePath == @"a\b\c\d")); Assert.AreEqual(1, input.FindIndex(e => e.RelativePath == @"a\b\c\e")); Assert.AreEqual(2, input.FindIndex(e => e.RelativePath == @"a\b\c")); }
public AnalyzeJobProgressInfo( EntryUpdateInfo updateInfo, int sourceAdapterId, string activity, int filesTotal, long bytesTotal) { this.Activity = activity; this.ProgressValue = null; this.SourceAdapterId = sourceAdapterId; this.FilesTotal = filesTotal; this.BytesTotal = bytesTotal; this.UpdateInfo = updateInfo; }
public PSAnalyzeResult(EntryUpdateInfo info) { this.Flags = info.Flags; this.State = info.State; this.SizeOld = info.OriginalSizeOld; this.SizeNew = info.OriginalSizeNew; this.Sha1HashOld = this.GetHashString(info.OriginalSha1HashOld); this.Sha1HashNew = this.GetHashString(info.OriginalSha1HashNew); this.Md5HashOld = this.GetHashString(info.OriginalMd5HashOld); this.Md5HashNew = this.GetHashString(info.OriginalMd5HashNew); this.CreationDateTimeUtcOld = info.CreationDateTimeUtcOld; this.CreationDateTimeUtcNew = info.CreationDateTimeUtcNew; this.ModifiedDateTimeUtcOld = info.ModifiedDateTimeUtcOld; this.ModifiedDateTimeUtcNew = info.ModifiedDateTimeUtcNew; this.PathOld = info.PathOld; this.PathNew = info.PathNew; }
public void CalculateChangeMetrics(EntryUpdateInfo info) { if (info.Entry.Type == SyncEntryType.Directory) { if (info.HasSyncEntryFlag(SyncEntryChangedFlags.NewDirectory)) { this.ChangeMetricsList[1].Added++; } else if (info.HasSyncEntryFlag(SyncEntryChangedFlags.Deleted)) { this.ChangeMetricsList[1].Removed++; } else if (info.HasSyncEntryFlag(SyncEntryChangedFlags.CreatedTimestamp) || info.HasSyncEntryFlag(SyncEntryChangedFlags.ModifiedTimestamp)) { this.ChangeMetricsList[1].Metadata++; } } else { if (info.HasSyncEntryFlag(SyncEntryChangedFlags.NewFile)) { this.ChangeMetricsList[0].Added++; this.ChangeMetricsList[2].Added += info.Entry.GetSize(this.SyncRelationship.GetSyncRelationship(), SyncEntryPropertyLocation.Source); this.BytesToCopy += info.Entry.GetSize(this.SyncRelationship.GetSyncRelationship(), SyncEntryPropertyLocation.Source); } else if (info.HasSyncEntryFlag(SyncEntryChangedFlags.Deleted)) { this.ChangeMetricsList[0].Removed++; this.ChangeMetricsList[2].Removed += info.Entry.GetSize(this.SyncRelationship.GetSyncRelationship(), SyncEntryPropertyLocation.Source); } else if (info.HasSyncEntryFlag(SyncEntryChangedFlags.CreatedTimestamp) || info.HasSyncEntryFlag(SyncEntryChangedFlags.ModifiedTimestamp)) { this.ChangeMetricsList[0].Metadata++; } else if (info.HasSyncEntryFlag(SyncEntryChangedFlags.Sha1Hash) || info.HasSyncEntryFlag(SyncEntryChangedFlags.Md5Hash) || info.HasSyncEntryFlag(SyncEntryChangedFlags.FileSize)) { this.ChangeMetricsList[0].Modified++; this.ChangeMetricsList[2].Modified += info.Entry.GetSize(this.SyncRelationship.GetSyncRelationship(), SyncEntryPropertyLocation.Source); this.BytesToCopy += info.Entry.GetSize(this.SyncRelationship.GetSyncRelationship(), SyncEntryPropertyLocation.Source); } } }
public void DeletedReverseOrder() { List <EntryUpdateInfo> input = new List <EntryUpdateInfo> { EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.Deleted, @"a\deleted2"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.Deleted, @"a\deleted1"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.Deleted, @"a\deleted3"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.Deleted, @"a\deleted2\child1"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.Deleted, @"a\deleted2\child1\two"), }; input.Sort(new EntryProcessingSorter()); Assert.AreEqual(0, input.FindIndex(e => e.RelativePath == @"a\deleted3")); Assert.AreEqual(1, input.FindIndex(e => e.RelativePath == @"a\deleted2\child1\two")); Assert.AreEqual(2, input.FindIndex(e => e.RelativePath == @"a\deleted2\child1")); Assert.AreEqual(3, input.FindIndex(e => e.RelativePath == @"a\deleted2")); Assert.AreEqual(4, input.FindIndex(e => e.RelativePath == @"a\deleted1")); }
public void SortyByRelativePath() { List <EntryUpdateInfo> input = new List <EntryUpdateInfo> { EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.NewDirectory, @"a\newDir1"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.NewDirectory, @"a\newDir3"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.NewDirectory, @"a\newDir2"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.FileSize, @"a\newFile2"), EntryUpdateInfo.CreateForTests(SyncEntryChangedFlags.FileSize, @"a\newFile1"), }; input.Sort(new EntryProcessingSorter()); Assert.AreEqual(0, input.FindIndex(e => e.RelativePath == @"a\newDir1")); Assert.AreEqual(1, input.FindIndex(e => e.RelativePath == @"a\newDir2")); Assert.AreEqual(2, input.FindIndex(e => e.RelativePath == @"a\newDir3")); Assert.AreEqual(3, input.FindIndex(e => e.RelativePath == @"a\newFile1")); Assert.AreEqual(4, input.FindIndex(e => e.RelativePath == @"a\newFile2")); }
public SyncJobProgressInfo( EntryUpdateInfo updateInfo, int filesTotal, int filesCompleted, long bytesTotal, long bytesCompleted, int bytesPerSecond) { //this.Stage = SyncJobStage.Sync; this.UpdateInfo = updateInfo; this.ProgressValue = (double)bytesCompleted / (double)bytesTotal; this.FilesTotal = filesTotal; this.FilesCompleted = filesCompleted; this.BytesTotal = bytesTotal; this.BytesCompleted = bytesCompleted; this.BytesPerSecond = bytesPerSecond; }
public override void FinalizeItemWrite(Stream stream, EntryUpdateInfo updateInfo) { AzureStorageUploadStream uploadStream = stream as AzureStorageUploadStream; Pre.ThrowIfArgumentNull(uploadStream, "uploadStream"); // If there are any block IDs in the block list, then the file was uploaded using blocks (as opposed to // uploading the file as a single blob). For this, we need to call PutBlockList to finalize the creation // of the blob in storage. if (uploadStream.BlockList.Any()) { HttpResponseMessage response = this.storageClient.PutBlockListAsync( this.TypedConfiguration.ContainerName, uploadStream.FileName, uploadStream.BlockList).Result; using (response) { if (!response.IsSuccessStatusCode) { throw new AzureStorageHttpException(); } } } SyncEntryAdapterData adapterData = updateInfo.Entry.AdapterEntries.FirstOrDefault(a => a.AdapterId == this.Configuration.Id); if (adapterData == null) { adapterData = new SyncEntryAdapterData { SyncEntry = updateInfo.Entry, AdapterId = this.Configuration.Id }; updateInfo.Entry.AdapterEntries.Add(adapterData); } adapterData.AdapterEntryId = GetUniqueIdForFile(updateInfo.RelativePath); }
public override void FinalizeItemWrite(Stream stream, EntryUpdateInfo updateInfo) { OneDriveFileUploadStream uploadStream = (OneDriveFileUploadStream)stream; SyncEntryAdapterData adapterEntry = updateInfo.Entry.AdapterEntries.FirstOrDefault(e => e.AdapterId == this.Config.Id); if (adapterEntry == null) { adapterEntry = new SyncEntryAdapterData() { SyncEntry = updateInfo.Entry, AdapterId = this.Config.Id }; updateInfo.Entry.AdapterEntries.Add(adapterEntry); } adapterEntry.AdapterEntryId = uploadStream.UploadSession.Item.Id; }
public override void UpdateItem(EntryUpdateInfo updateInfo, SyncEntryChangedFlags changeFlags) { string fullPath, newFullPath = null; using (var database = this.Relationship.GetDatabase()) { fullPath = Path.Combine(this.Config.RootDirectory, updateInfo.Entry.GetRelativePath(database, this.PathSeparator)); if (!string.IsNullOrWhiteSpace(updateInfo.PathNew)) { newFullPath = Path.Combine(this.Config.RootDirectory, updateInfo.PathNew); } } FileSystemInfo fileSystemInfo = GetFileSystemInfo(fullPath, updateInfo.Entry.Type); if ((changeFlags & SyncEntryChangedFlags.CreatedTimestamp) != 0) { Pre.Assert(updateInfo.CreationDateTimeUtcNew != null, "updateInfo.CreationDateTimeUtcNew != null"); // Write the new created timestamp to the file/folder fileSystemInfo.CreationTimeUtc = updateInfo.CreationDateTimeUtcNew.Value; // Update the SyncEntry to record that this is now the "current" value of CreationDateTimeUtcNew updateInfo.Entry.CreationDateTimeUtc = updateInfo.CreationDateTimeUtcNew.Value; } if ((changeFlags & SyncEntryChangedFlags.ModifiedTimestamp) != 0) { Pre.Assert(updateInfo.ModifiedDateTimeUtcNew != null, "updateInfo.ModifiedDateTimeUtcNew != null"); // Write the new modified timestamp to the file/folder fileSystemInfo.LastWriteTimeUtc = updateInfo.ModifiedDateTimeUtcNew.Value; // Update the SyncEntry to record that this is now the "current" value of ModifiedDateTimeUtcNew updateInfo.Entry.ModifiedDateTimeUtc = updateInfo.ModifiedDateTimeUtcNew.Value; } if ((changeFlags & SyncEntryChangedFlags.Renamed) != 0 || (changeFlags & SyncEntryChangedFlags.Moved) != 0) { if (updateInfo.Entry.Type == SyncEntryType.File) { Pre.Assert(!string.IsNullOrEmpty(newFullPath), "newFullPath != null"); File.Move(fullPath, newFullPath); } else if (updateInfo.Entry.Type == SyncEntryType.Directory) { Pre.Assert(!string.IsNullOrEmpty(newFullPath), "newFullPath != null"); Directory.Move(fullPath, newFullPath); } else { throw new NotImplementedException(); } if ((changeFlags & SyncEntryChangedFlags.Renamed) != 0) { updateInfo.Entry.Name = PathUtility.GetSegment(updateInfo.PathNew, -1); } if ((changeFlags & SyncEntryChangedFlags.Moved) != 0) { updateInfo.Entry.ParentId = updateInfo.ParentIdNew; } } }
public override void UpdateItem(EntryUpdateInfo updateInfo, SyncEntryChangedFlags changeFlags) { throw new NotImplementedException(); }
public override void FinalizeItemWrite(Stream stream, EntryUpdateInfo updateInfo) { }
public override void FinalizeItemWrite(Stream stream, EntryUpdateInfo updateInfo) { throw new NotImplementedException(); }