public static SyncCopyContentToDeviceTarget.CallPrepareTargetAndListItemsToCopyReturnValue ExecuteMethod_CallPrepareTargetAndListItemsToCopy(AuthenticatedAsActiveDevice authenticatedAsActiveDevice, ContentItemLocationWithMD5[] thisSideContentMd5List) { DeviceOperationData deviceOperationData = new DeviceOperationData { OperationRequestString = "SYNCCOPYCONTENT", OperationSpecificContentData = thisSideContentMd5List, OperationParameters = new string[] { SyncSupport.RelativeRootFolderValue} }; deviceOperationData = DeviceSupport.ExecuteRemoteOperation<DeviceOperationData>(authenticatedAsActiveDevice.ID, "TheBall.CORE.RemoteDeviceCoreOperation", deviceOperationData); var returnValue = new SyncCopyContentToDeviceTarget.CallPrepareTargetAndListItemsToCopyReturnValue { ItemsToCopy = deviceOperationData.OperationSpecificContentData.Where(item => item.ItemDatas.Any(iData => iData.DataName == "OPTODO" && iData.ItemTextData == "COPY")).ToArray(), ItemsDeleted = deviceOperationData.OperationSpecificContentData.Where(item => item.ItemDatas.Any(iData => iData.DataName == "OPDONE" && iData.ItemTextData == "DELETED")).ToArray() }; return returnValue; }
public static void ExecuteMethod_CopyContentsToSyncRoot(ContentItemLocationWithMD5[] contentListingResult, string syncTargetRootFolder) { SyncSupport.SynchronizeSourceListToTargetFolder(SyncSupport.RelativeRootFolderValue, contentListingResult, syncTargetRootFolder); }
public static void SynchronizeSourceListToTargetFolder(string syncSourceRootFolder, ContentItemLocationWithMD5[] sourceContentList, string syncTargetRootFolder, CopySourceToTargetMethod copySourceToTarget = null, DeleteObsoleteTargetMethod deleteObsoleteTarget = null) { if (copySourceToTarget == null) copySourceToTarget = CopySourceToTarget; if (deleteObsoleteTarget == null) deleteObsoleteTarget = DeleteObsoleteTarget; if (String.IsNullOrEmpty(syncSourceRootFolder) || syncSourceRootFolder == "/") syncSourceRootFolder = RelativeRootFolderValue; else if(syncSourceRootFolder.EndsWith("/") == false) { syncSourceRootFolder += "/"; } var blobListing = InformationContext.CurrentOwner.GetOwnerBlobListing(syncTargetRootFolder, true); string fullTargetRootPath = StorageSupport.GetOwnerContentLocation(InformationContext.CurrentOwner, syncTargetRootFolder); int fullTargetRootPathLength = fullTargetRootPath.Length; ContentItemLocationWithMD5[] targetContents = (from CloudBlockBlob blob in blobListing let relativeName = blob.Name.Substring(fullTargetRootPathLength) select new ContentItemLocationWithMD5 { ContentLocation = relativeName, ContentMD5 = blob.Properties.ContentMD5 }).OrderBy(item => item.ContentLocation).ToArray(); var sourceContents = sourceContentList.OrderBy(item => item.ContentLocation).ToArray(); foreach (var sourceContent in sourceContents) { string originalLocation = sourceContent.ContentLocation; string nonOwnerLocation = StorageSupport.RemoveOwnerPrefixIfExists(originalLocation); string fixedContentLocation; if (originalLocation != nonOwnerLocation && syncSourceRootFolder != RelativeRootFolderValue) { if(nonOwnerLocation.StartsWith(syncSourceRootFolder) == false) throw new InvalidDataException("Sync source must start with given root location"); fixedContentLocation = nonOwnerLocation.Substring(syncSourceRootFolder.Length); } else fixedContentLocation = nonOwnerLocation; sourceContent.ContentLocation = fixedContentLocation; } int currSourceIX = 0; int currTargetIX = 0; while (currSourceIX < sourceContents.Length || currTargetIX < targetContents.Length) { var currSource = currSourceIX < sourceContents.Length ? sourceContents[currSourceIX] : null; var currTarget = currTargetIX < targetContents.Length ? targetContents[currTargetIX] : null; string currTargetBlobLocation = null; string currSourceBlobLocation = null; if (currSource != null && currTarget != null) { if (currSource.ContentLocation == currTarget.ContentLocation) { currSourceIX++; currTargetIX++; if (currSource.ContentMD5 == currTarget.ContentMD5) continue; currSourceBlobLocation = StorageSupport.GetOwnerContentLocation(InformationContext.CurrentOwner, syncSourceRootFolder + currSource.ContentLocation); currTargetBlobLocation = fullTargetRootPath + currTarget.ContentLocation; } else if (String.Compare(currSource.ContentLocation, currTarget.ContentLocation) < 0) { currSourceIX++; currSourceBlobLocation = StorageSupport.GetOwnerContentLocation(InformationContext.CurrentOwner, syncSourceRootFolder + currSource.ContentLocation); currTargetBlobLocation = fullTargetRootPath + currSource.ContentLocation; } else // source == null, target != null { currTargetIX++; currTargetBlobLocation = fullTargetRootPath + currTarget.ContentLocation; } } else if (currSource != null) { currSourceIX++; currSourceBlobLocation = StorageSupport.GetOwnerContentLocation(InformationContext.CurrentOwner, syncSourceRootFolder + currSource.ContentLocation); currTargetBlobLocation = fullTargetRootPath + currSource.ContentLocation; } else if (currTarget != null) { currTargetIX++; currTargetBlobLocation = fullTargetRootPath + currTarget.ContentLocation; } // at this stage we have either both set (that's copy) or just target set (that's delete) if (currSourceBlobLocation != null && currTargetBlobLocation != null) copySourceToTarget(currSourceBlobLocation, currTargetBlobLocation); else if (currTargetBlobLocation != null) deleteObsoleteTarget(currTargetBlobLocation); } }