internal virtual async Task <List <TValue> > GetValuesAsync(TimeSpan timeout, CancellationToken cancellationToken, ITransaction transaction, BRSContinuationToken continuationToken, int maxResults = 0) { List <TValue> listOfValues = new List <TValue>(); BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "GetValuesAsync"); try { if (transaction == null) { using (transaction = this.StatefulService.StateManager.CreateTransaction()) { listOfValues = await GetValuesAsyncUtils(transaction, cancellationToken, continuationToken, maxResults); await transaction.CommitAsync(); } } else { listOfValues = await GetValuesAsyncUtils(transaction, cancellationToken, continuationToken, maxResults); } return(listOfValues); } catch (Exception exception) { BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "GetValuesAsync failed"); this.LogException(TraceType, exception); this.HandleException(exception); } return(listOfValues); }
internal virtual async Task <List <TValue> > GetValuesAsyncUtils(ITransaction transaction, CancellationToken cancellationToken, BRSContinuationToken continuationToken, int maxResults = 0) { if (maxResults != 0 && continuationToken == null) { throw new ArgumentException("continuationToken cannot be null when maxResults is not equal to 0."); } List <TValue> listOfValues = new List <TValue>(); if ((continuationToken == null || continuationToken.IncomingContinuationToken == null) && maxResults == 0) { var enumerable = await this.StoreReliableDictionary.CreateEnumerableAsync(transaction); var enumerator = enumerable.GetAsyncEnumerator(); while (await enumerator.MoveNextAsync(cancellationToken)) { listOfValues.Add(enumerator.Current.Value); } } else { var enumerable = await this.StoreReliableDictionary.CreateEnumerableAsync(transaction, key => key.ToString().CompareTo(continuationToken.IncomingContinuationToken) > 0, EnumerationMode.Ordered); var enumerator = enumerable.GetAsyncEnumerator(); long counter = 0; while (await enumerator.MoveNextAsync(cancellationToken)) { listOfValues.Add(enumerator.Current.Value); counter++; if (maxResults != 0 && counter >= maxResults) { string continuationTokenToSet = enumerator.Current.Key.ToString(); if (await enumerator.MoveNextAsync(cancellationToken)) { continuationToken.OutgoingContinuationToken = continuationTokenToSet; break; } } } } return(listOfValues); }
internal override async Task <BackupConfigurationInfo> RunAsync(TimeSpan timeout, CancellationToken cancellationToken) { string applicationNameUri; string serviceNameUri; string partitionId; List <BackupEntityConfigurationInfo> backupConfigurationInfos = new List <BackupEntityConfigurationInfo>(); var suspendStore = await SuspendStore.CreateOrGetSuspendStatusStore(this.StatefulService); var enablementKey = await UtilityHelper.GetFabricUriFromRequstHeader(this.fabricRequestHeader, timeout, cancellationToken); BRSContinuationToken brsContinuationToken = new BRSContinuationToken(); brsContinuationToken.IncomingContinuationToken = continuationToken; var fabricBackupResourceType = UtilityHelper.GetApplicationAndServicePartitionUri(enablementKey, out applicationNameUri, out serviceNameUri, out partitionId); var backupMapping = await this.BackupMappingStore.GetValueAsync(enablementKey, timeout, cancellationToken); int maxResultsForOverriddenPolicies = 0; if (maxResults != 0) { maxResultsForOverriddenPolicies = maxResults - 1; } switch (fabricBackupResourceType) { case FabricBackupResourceType.PartitionUri: PartitionBackupConfigurationInfo partitionBackupConfigurationInfo = null; BackupSuspensionInfo backupSuspensionInfo = new BackupSuspensionInfo(); if (await suspendStore.IsFabrcUriSuspended(enablementKey, timeout, cancellationToken)) { backupSuspensionInfo.IsSuspended = true; backupSuspensionInfo.SuspensionInheritedFrom = BackupEntityKind.Partition; } else if (await suspendStore.IsFabrcUriSuspended(serviceNameUri, timeout, cancellationToken)) { backupSuspensionInfo.IsSuspended = true; backupSuspensionInfo.SuspensionInheritedFrom = BackupEntityKind.Service; } else if (await suspendStore.IsFabrcUriSuspended(applicationNameUri, timeout, cancellationToken)) { backupSuspensionInfo.IsSuspended = true; backupSuspensionInfo.SuspensionInheritedFrom = BackupEntityKind.Application; } if (backupMapping != null) { partitionBackupConfigurationInfo = new PartitionBackupConfigurationInfo(serviceNameUri, partitionId, backupMapping.BackupPolicyName, BackupEntityKind.Partition, backupSuspensionInfo ); } else { var backupMappingInherited = await this.BackupMappingStore.GetValueAsync(serviceNameUri, timeout, cancellationToken); if (backupMappingInherited != null) { partitionBackupConfigurationInfo = new PartitionBackupConfigurationInfo(serviceNameUri, partitionId, backupMappingInherited.BackupPolicyName, BackupEntityKind.Service, backupSuspensionInfo ); } else { backupMappingInherited = await this.BackupMappingStore.GetValueAsync(applicationNameUri, timeout, cancellationToken); if (backupMappingInherited != null) { partitionBackupConfigurationInfo = new PartitionBackupConfigurationInfo(serviceNameUri, partitionId, backupMappingInherited.BackupPolicyName, BackupEntityKind.Application, backupSuspensionInfo ); } } } return(partitionBackupConfigurationInfo); case FabricBackupResourceType.ServiceUri: ServiceBackupConfigurationInfo serviceBackupConfigurationInfo = null; backupSuspensionInfo = new BackupSuspensionInfo(); if (await suspendStore.IsFabrcUriSuspended(serviceNameUri, timeout, cancellationToken)) { backupSuspensionInfo.IsSuspended = true; backupSuspensionInfo.SuspensionInheritedFrom = BackupEntityKind.Service; } else if (await suspendStore.IsFabrcUriSuspended(applicationNameUri, timeout, cancellationToken)) { backupSuspensionInfo.IsSuspended = true; backupSuspensionInfo.SuspensionInheritedFrom = BackupEntityKind.Application; } if (backupMapping != null) { serviceBackupConfigurationInfo = new ServiceBackupConfigurationInfo(serviceNameUri, backupMapping.BackupPolicyName, BackupEntityKind.Service, backupSuspensionInfo); } else { backupMapping = await this.BackupMappingStore.GetValueAsync(applicationNameUri, timeout, cancellationToken); if (backupMapping != null) { serviceBackupConfigurationInfo = new ServiceBackupConfigurationInfo(serviceNameUri, backupMapping.BackupPolicyName, BackupEntityKind.Application, backupSuspensionInfo); } } if (serviceBackupConfigurationInfo != null && String.IsNullOrEmpty(brsContinuationToken.IncomingContinuationToken)) { backupConfigurationInfos.Add(serviceBackupConfigurationInfo); } if (maxResults == 1 && String.IsNullOrEmpty(brsContinuationToken.IncomingContinuationToken) && serviceBackupConfigurationInfo != null) { // if maxResults is 1, then, we need to check if more elements are there or not. List <string> suspendedPartitions = await suspendStore.GetAllSuspensionWithFabricUri(serviceNameUri, timeout, cancellationToken, brsContinuationToken.IncomingContinuationToken); var overridesBackupMappings = await this.BackupMappingStore.GetAllProtectionWithFabricUri(serviceNameUri, timeout, cancellationToken, brsContinuationToken.IncomingContinuationToken); int countToCompare = 0; if (backupSuspensionInfo.IsSuspended) { countToCompare = 1; } if (overridesBackupMappings.Count > 1 || suspendedPartitions.Count > countToCompare) { // overridesBackupMappings should be greater than 1 as it contains this mapping also or suspendedPartitions should have its count greater than zero. brsContinuationToken.OutgoingContinuationToken = serviceNameUri + ContinuationTokenSeparatorChar + OverrideContinuationToken; } } else { backupConfigurationInfos.AddRange( await this.GetOverriddenBackupConfigurationinfo(serviceNameUri, backupSuspensionInfo, timeout, cancellationToken, brsContinuationToken, maxResultsForOverriddenPolicies)); } break; case FabricBackupResourceType.ApplicationUri: ApplicationBackupConfigurationInfo applicationBackupConfigurationInfo = null; backupSuspensionInfo = new BackupSuspensionInfo(); if (await suspendStore.IsFabrcUriSuspended(applicationNameUri, timeout, cancellationToken)) { backupSuspensionInfo.IsSuspended = true; backupSuspensionInfo.SuspensionInheritedFrom = BackupEntityKind.Application; } if (backupMapping != null) { applicationBackupConfigurationInfo = new ApplicationBackupConfigurationInfo(applicationNameUri, backupMapping.BackupPolicyName, BackupEntityKind.Application, backupSuspensionInfo); } if (applicationBackupConfigurationInfo != null && String.IsNullOrEmpty(brsContinuationToken.IncomingContinuationToken)) { backupConfigurationInfos.Add(applicationBackupConfigurationInfo); } if (maxResults == 1 && String.IsNullOrEmpty(brsContinuationToken.IncomingContinuationToken) && applicationBackupConfigurationInfo != null) { // if maxResults is 1, then, we need to check if more elements are there or not. List <string> suspendedPartitions = await suspendStore.GetAllSuspensionWithFabricUri(applicationNameUri, timeout, cancellationToken); var overridesBackupMappings = await this.BackupMappingStore.GetAllProtectionWithFabricUri(applicationNameUri, timeout, cancellationToken, null); int countToCompare = 0; if (backupSuspensionInfo.IsSuspended) { countToCompare = 1; } if (overridesBackupMappings.Count > 1 || suspendedPartitions.Count > countToCompare) { // overridesBackupMappings is compared to 1 as 1st element will be same as this one. brsContinuationToken.OutgoingContinuationToken = applicationNameUri + ContinuationTokenSeparatorChar + OverrideContinuationToken; } } else { backupConfigurationInfos.AddRange( await this.GetOverriddenBackupConfigurationinfo(applicationNameUri, backupSuspensionInfo, timeout, cancellationToken, brsContinuationToken, maxResultsForOverriddenPolicies)); } break; } if (backupConfigurationInfos.Count == 0) { throw new FabricException(StringResources.BackupMappingNotExisting, FabricErrorCode.BackupNotEnabled); } return(new PagedBackupConfigurationInfo() { Items = backupConfigurationInfos, ContinuationToken = brsContinuationToken.OutgoingContinuationToken }); }
private async Task <List <BackupEntityConfigurationInfo> > GetOverriddenBackupConfigurationinfo(string applicationServiceNameUri, BackupSuspensionInfo inheritedBackupSuspensionInfo, TimeSpan timeout, CancellationToken cancellationToken, BRSContinuationToken brsContinuationToken, int maxResultsLocal = 0) { List <BackupEntityConfigurationInfo> backupConfigurationInfos = new List <BackupEntityConfigurationInfo>(); bool listSuspended = false; if (!String.IsNullOrEmpty(brsContinuationToken.IncomingContinuationToken)) { string[] array = brsContinuationToken.IncomingContinuationToken.Split(ContinuationTokenSeparatorChar); brsContinuationToken.IncomingContinuationToken = array[0]; if (array[1] == SuspendedContinuationToken) { // We need to check if we were listing suspended partitions previously or override. listSuspended = true; } } string continuationTokenForSuspendendPartitions = null; if (listSuspended) { // if we were listing overrides, then this continuationTokenForSuspendendPartitions should be null. continuationTokenForSuspendendPartitions = brsContinuationToken.IncomingContinuationToken; } var suspendStore = await SuspendStore.CreateOrGetSuspendStatusStore(this.StatefulService); List <string> suspendedEntities = await suspendStore.GetAllSuspensionWithFabricUri(applicationServiceNameUri, timeout, cancellationToken, continuationTokenForSuspendendPartitions); HashSet <string> suspendedEntitiesHashSet = new HashSet <string>(suspendedEntities); var overridesBackupMappings = await this.BackupMappingStore.GetAllProtectionWithFabricUri(applicationServiceNameUri, timeout, cancellationToken, brsContinuationToken.IncomingContinuationToken); string applicationNameUri = null; string serviceNameUri = null; string partitionId = null; int counter = 0; if (maxResultsLocal != 0) { // if maxResults is equal to zero, then we dont need to sort as we have already filtered the elements. overridesBackupMappings = overridesBackupMappings.OrderBy(backupMapping => backupMapping.ApplicationOrServiceUri).ToList(); } foreach (var overridesBackupMapping in overridesBackupMappings) { if (!applicationServiceNameUri.Equals(overridesBackupMapping.ApplicationOrServiceUri)) { BackupEntityConfigurationInfo backupConfigurationInfo = null; FabricBackupResourceType fabricBackupResourceType = UtilityHelper .GetApplicationAndServicePartitionUri( overridesBackupMapping.ApplicationOrServiceUri, out applicationNameUri, out serviceNameUri, out partitionId); BackupSuspensionInfo backupSuspensionInfo = inheritedBackupSuspensionInfo; switch (fabricBackupResourceType) { case FabricBackupResourceType.PartitionUri: if (suspendedEntitiesHashSet.Contains(overridesBackupMapping.ApplicationOrServiceUri)) { backupSuspensionInfo = new BackupSuspensionInfo(BackupEntityKind.Partition, true); suspendedEntitiesHashSet.Remove(overridesBackupMapping.ApplicationOrServiceUri); } if (listSuspended) { continue; } backupConfigurationInfo = new PartitionBackupConfigurationInfo(serviceNameUri, partitionId, overridesBackupMapping.BackupPolicyName, BackupEntityKind.Partition, backupSuspensionInfo); break; case FabricBackupResourceType.ServiceUri: if (suspendedEntitiesHashSet.Contains(overridesBackupMapping.ApplicationOrServiceUri)) { backupSuspensionInfo = new BackupSuspensionInfo(BackupEntityKind.Service, true); suspendedEntitiesHashSet.Remove(overridesBackupMapping.ApplicationOrServiceUri); } if (listSuspended) { continue; } backupConfigurationInfo = new ServiceBackupConfigurationInfo(serviceNameUri, overridesBackupMapping.BackupPolicyName, BackupEntityKind.Service, backupSuspensionInfo); break; case FabricBackupResourceType.ApplicationUri: if (suspendedEntitiesHashSet.Contains(overridesBackupMapping.ApplicationOrServiceUri)) { backupSuspensionInfo = new BackupSuspensionInfo(BackupEntityKind.Application, true); suspendedEntitiesHashSet.Remove(overridesBackupMapping.ApplicationOrServiceUri); } if (listSuspended) { continue; } backupConfigurationInfo = new ApplicationBackupConfigurationInfo(applicationNameUri, overridesBackupMapping.BackupPolicyName, BackupEntityKind.Application, backupSuspensionInfo); break; } if (backupConfigurationInfo != null) { backupConfigurationInfos.Add(backupConfigurationInfo); counter++; if (maxResultsLocal != 0 && counter == maxResultsLocal) { if (counter < overridesBackupMappings.Count || suspendedEntitiesHashSet.Count > 0) { // we need to check if there are more elements to be listed or not. brsContinuationToken.OutgoingContinuationToken = overridesBackupMapping.ApplicationOrServiceUri + ContinuationTokenSeparatorChar + OverrideContinuationToken; } return(backupConfigurationInfos); } } } } suspendedEntitiesHashSet.Remove(applicationServiceNameUri); foreach (var leftSuspendUri in suspendedEntitiesHashSet) { if (maxResultsLocal != 0) { // if maxResults is equal to zero, then we dont need to sort as we have already filtered the elements. suspendedEntitiesHashSet.ToList().Sort(); } FabricBackupResourceType leftSuspendUriType = UtilityHelper .GetApplicationAndServicePartitionUri( leftSuspendUri, out applicationNameUri, out serviceNameUri, out partitionId); BackupEntityConfigurationInfo backupConfigurationInfo = null; BackupMappingModel backupMapping = null; BackupEntityKind backupEntityKind = BackupEntityKind.Invalid; switch (leftSuspendUriType) { case FabricBackupResourceType.PartitionUri: backupMapping = await this.BackupMappingStore.GetValueAsync(serviceNameUri); backupEntityKind = backupMapping != null ? BackupEntityKind.Service : BackupEntityKind.Invalid; backupMapping = await this.BackupMappingStore.GetValueAsync(applicationNameUri); backupEntityKind = backupMapping != null ? BackupEntityKind.Application : BackupEntityKind.Invalid; backupConfigurationInfo = new PartitionBackupConfigurationInfo(serviceNameUri, partitionId, backupMapping.BackupPolicyName, backupEntityKind, new BackupSuspensionInfo(BackupEntityKind.Partition, true)); break; case FabricBackupResourceType.ServiceUri: backupMapping = await this.BackupMappingStore.GetValueAsync(applicationNameUri); backupEntityKind = backupMapping != null ? BackupEntityKind.Application : BackupEntityKind.Invalid; backupConfigurationInfo = new ServiceBackupConfigurationInfo(serviceNameUri, backupMapping.BackupPolicyName, backupEntityKind, new BackupSuspensionInfo(BackupEntityKind.Service, true)); break; case FabricBackupResourceType.ApplicationUri: backupMapping = await this.BackupMappingStore.GetValueAsync(applicationNameUri); backupEntityKind = backupMapping != null ? BackupEntityKind.Application : BackupEntityKind.Invalid; backupConfigurationInfo = new ApplicationBackupConfigurationInfo(applicationNameUri, backupMapping.BackupPolicyName, backupEntityKind, new BackupSuspensionInfo(BackupEntityKind.Application, true)); break; } if (backupMapping != null && backupEntityKind != BackupEntityKind.Invalid) { backupConfigurationInfos.Add(backupConfigurationInfo); counter++; if (maxResultsLocal != 0 && counter == maxResultsLocal) { if (counter < suspendedEntitiesHashSet.Count) { // we need to check if there are more elements to be listed or not. brsContinuationToken.OutgoingContinuationToken = leftSuspendUri + ContinuationTokenSeparatorChar + SuspendedContinuationToken; } break; } } } return(backupConfigurationInfos); }
internal override async Task <PagedBackupInfoList> RunAsync(TimeSpan timeout, CancellationToken cancellationToken) { BRSContinuationToken continuationTokenForNextStage = new BRSContinuationToken(); if (continuationToken != null) { continuationTokenForNextStage.IncomingContinuationToken = continuationToken; } List <RestorePoint> restorePoints = new List <RestorePoint>(); this.ThrowInvalidArgumentIfNull(this.backupByStorageQueryDescription.Storage); BackupStorageModel backupStorageModel = BackupStorageModel.FromBackupStorageView(this.backupByStorageQueryDescription.Storage); this.PopulateApplicationServiceAndPartitionWithBackupEntity(this.backupByStorageQueryDescription.BackupEntity, timeout, cancellationToken); try { List <RestorePoint> fetchedRestorePoints = await backupStorageModel.GetBackupEnumerationsTask( this.ApplicationName, this.ServiceName, this.PartitionId, this.backupByStorageQueryDescription.StartDateTimeFilter, this.backupByStorageQueryDescription.EndDateTimeFilter, this.backupByStorageQueryDescription.Latest, cancellationToken, continuationTokenForNextStage, maxResults); if (fetchedRestorePoints != null && fetchedRestorePoints.Count > 0) { restorePoints = fetchedRestorePoints; } } catch (Exception exception) { List <RestorePointEnumerationFailureInfo> restorePointEnumerationFailureInfo = new List <RestorePointEnumerationFailureInfo>(); AggregateException aggregateException = exception as AggregateException; if (aggregateException != null) { foreach (var innerException in aggregateException.InnerExceptions) { restorePoints.Add(new RestorePoint () { FailureError = new FabricError() { Code = (NativeTypes.FABRIC_ERROR_CODE)innerException.HResult, Message = innerException.Message } }); } } else { restorePoints.Add(new RestorePoint () { FailureError = new FabricError() { Code = (NativeTypes.FABRIC_ERROR_CODE)exception.HResult, Message = exception.Message } }); } } return(new PagedBackupInfoList() { Items = restorePoints, ContinuationToken = continuationTokenForNextStage.OutgoingContinuationToken }); }
public List <string> EnumerateRecoveryPointMetadataFiles(string relativePath, DateTime startDateTime, DateTime endDateTime, bool isLatestRequested, BRSContinuationToken continuationToken, int maxResults) { if (String.IsNullOrEmpty(relativePath)) { throw new ArgumentException("relativePath cannot be null"); } if (continuationToken == null) { throw new ArgumentException("continuationToken cannot be null"); } // Convert relative path to AzureStore format. string blobStoreRelativePath = AzureBlobStoreHelper.ConvertToAzureBlobStorePath(relativePath); BlobContinuationToken blobContinuationTokenFromQuery = null; if (!String.IsNullOrEmpty(continuationToken.IncomingContinuationToken)) { string[] continuationTokenList = new string[] { }; try { // continuationToen here equals targetlocation "+" nextMarker. continuationTokenList = continuationToken.IncomingContinuationToken.Split(new char[] { ContinuationTokenSeparatorChar }, 2); } catch (Exception ex) { throw new ArgumentException("continuationToken provided is not correct. Exception thrown: {0}", ex); } if (continuationTokenList.Count() != 2) { throw new ArgumentException("continuationToken provided is not correct. token: {0}", continuationToken.IncomingContinuationToken); } string targetLocation = continuationTokenList[0]; string nextMarker = continuationTokenList[1]; blobContinuationTokenFromQuery = new BlobContinuationToken(); blobContinuationTokenFromQuery.NextMarker = nextMarker; if (targetLocation == "Null") { blobContinuationTokenFromQuery.TargetLocation = null; } else { StorageLocation storageLocation; if (Enum.TryParse <StorageLocation>(targetLocation, out storageLocation)) { blobContinuationTokenFromQuery.TargetLocation = storageLocation; } else { throw new ArgumentException("targetLocation in continuationToken is not correct. {0} ", targetLocation); } } } Dictionary <string, string> latestInPartition = new Dictionary <string, string>(); try { CloudBlobDirectory blobDirectory = AzureBlobStoreHelper.GetCloudBlobDirectoryRef(this.container, blobStoreRelativePath); List <string> metadataBlobs = new List <string>(); int counter = 0; BlobContinuationToken finalBlobContinuationToken = null; BlobContinuationToken currentToken = blobContinuationTokenFromQuery; do { if (maxResults != 0 && counter == maxResults) { break; } int maxResultsQuery = MaximumCount; if (maxResults != 0 && counter + maxResultsQuery > maxResults) { maxResultsQuery = (maxResults - counter) * 2; } maxResultsQuery = (maxResultsQuery < MaximumCount) ? maxResultsQuery : MaximumCount; BlobResultSegment blobResultSegment = AzureBlobStoreHelper.GetBlobList(blobDirectory, true, currentToken, maxResultsQuery); currentToken = blobResultSegment.ContinuationToken; foreach (IListBlobItem blobItem in blobResultSegment.Results) { if (blobItem is CloudBlockBlob) { CloudBlockBlob blob = (CloudBlockBlob)blobItem; string blobName = blob.Name; if (blobName.EndsWith(RecoveryPointMetadataFileExtension)) { // Lets parse the files with respect to date here itself. // Let's parse the date time from file name ListBackupFile(startDateTime, endDateTime, blobName, metadataBlobs, latestInPartition, isLatestRequested, ref counter); } } } } while (currentToken != null); finalBlobContinuationToken = currentToken; if (finalBlobContinuationToken != null) { string nextMarkerFinal = finalBlobContinuationToken.NextMarker; string targetLocationFinal = "Null"; if (finalBlobContinuationToken.TargetLocation != null) { targetLocationFinal = finalBlobContinuationToken.TargetLocation.ToString(); } continuationToken.OutgoingContinuationToken = targetLocationFinal + ContinuationTokenSeparatorChar + nextMarkerFinal; } if (isLatestRequested) { List <string> newMetaDataFileList = new List <string>(); foreach (var tuple in latestInPartition) { newMetaDataFileList.Add(tuple.Value); } return(newMetaDataFileList); } return(metadataBlobs); } catch (Exception e) { throw new IOException(String.Format("Unable to enumerate metadata files from container:{0} and relative path: {1}.", this.container.Uri, blobStoreRelativePath), e); } }
public List <string> EnumerateRecoveryPointMetadataFiles(string relativePath, DateTime startDateTime, DateTime endDateTime, bool isLatestRequested, BRSContinuationToken continuationToken, int maxResults) { return(this.blobRecoveryPointStore.EnumerateRecoveryPointMetadataFiles(relativePath, startDateTime, endDateTime, isLatestRequested, continuationToken, maxResults)); }
public List <string> EnumerateRecoveryPointMetadataFiles(string relativePath, DateTime startDateTime, DateTime endDateTime, bool isLatestRequested, BRSContinuationToken continuationToken, int maxResults) { if (String.IsNullOrEmpty(relativePath)) { throw new ArgumentException("relativePath cannot be null"); } if (continuationToken == null) { throw new ArgumentException("continuationToken cannot be null"); } char pathSeparator = this.storeInformation.PathSeparator; string relativePathContinuationToken = null; string fileNameContinuationToken = null; if (!String.IsNullOrEmpty(continuationToken.IncomingContinuationToken)) { List <string> continuationTokenList = continuationToken.IncomingContinuationToken.Split(ContinuationTokenSeparatorChar).ToList(); if (continuationTokenList.Count != 4) { throw new ArgumentException("Invalid ContinuationToken is given. token: {0}", continuationToken.IncomingContinuationToken); } relativePathContinuationToken = string.Format("{0}{1}{2}{1}{3}", continuationTokenList[0], pathSeparator, continuationTokenList[1], continuationTokenList[2]); fileNameContinuationToken = continuationTokenList[3]; } var remotePath = Path.Combine(this.storeInformation.Path, relativePath); string remotePathContinuationToken = null; if (!String.IsNullOrEmpty(relativePathContinuationToken)) { remotePathContinuationToken = Path.Combine(this.storeInformation.Path, relativePathContinuationToken); } try { Dictionary <string, string> latestInPartition = new Dictionary <string, string>(); List <string> foldersToIterate = ListFoldersToIterate(remotePath, remotePathContinuationToken); foldersToIterate.Sort(); List <string> finalFileList = new List <string>(); string finalContinuationTokenPath = null; int counter = 0; bool toBreak = false; bool anyMoreLeft = true; foreach (var directory in foldersToIterate) { if (toBreak) { break; } string fileNameContinuationTokenFinal = null; if (directory == remotePathContinuationToken) { fileNameContinuationTokenFinal = fileNameContinuationToken; } List <string> fileNames = ListMetadataFilesInTheFolder(directory).Where(x => ConvertFileNameToDateTime(Path.GetFileNameWithoutExtension(x)) > ConvertFileNameToDateTime(Path.GetFileNameWithoutExtension(fileNameContinuationTokenFinal))).ToList(); int fileCount = fileNames.Count; if (maxResults != 0 && fileCount + counter >= maxResults) { if (maxResults == fileCount + counter && directory == foldersToIterate.Last()) { anyMoreLeft = false; } var sortedFileNames = fileNames.OrderBy(fileName => ConvertFileNameToDateTime(Path.GetFileNameWithoutExtension(fileName))); foreach (var fileName in sortedFileNames) { if (startDateTime != DateTime.MinValue || endDateTime != DateTime.MaxValue) { if (this.storeInformation.FilterFileBasedOnDateTime(fileName, startDateTime, endDateTime)) { AddFileToAppropriateObject(finalFileList, latestInPartition, fileName, isLatestRequested, ref counter); } } else { AddFileToAppropriateObject(finalFileList, latestInPartition, fileName, isLatestRequested, ref counter); } if (counter == maxResults) { finalContinuationTokenPath = fileName; toBreak = true; break; } } } else { foreach (var fileName in fileNames) { if (startDateTime != DateTime.MinValue || endDateTime != DateTime.MinValue) { if (this.storeInformation.FilterFileBasedOnDateTime(fileName, startDateTime, endDateTime)) { AddFileToAppropriateObject(finalFileList, latestInPartition, fileName, isLatestRequested, ref counter); } } else { AddFileToAppropriateObject(finalFileList, latestInPartition, fileName, isLatestRequested, ref counter); } } } } if (!string.IsNullOrEmpty(finalContinuationTokenPath)) { if (anyMoreLeft) { // First remove the store path from the start. if (finalContinuationTokenPath.StartsWith(this.storeInformation.Path)) { finalContinuationTokenPath = finalContinuationTokenPath.Remove(0, this.storeInformation.Path.Length); } continuationToken.OutgoingContinuationToken = finalContinuationTokenPath.Trim(pathSeparator).Replace(pathSeparator, ContinuationTokenSeparatorChar); } } if (isLatestRequested) { List <string> newMetaDataFileList = new List <string>(); foreach (var tuple in latestInPartition) { newMetaDataFileList.Add(tuple.Value); } return(newMetaDataFileList); } return(finalFileList); } catch (Exception e) { throw new IOException(String.Format("Unable to enumerate metadata files from location {0}.", remotePath), e); } }