private void LoadData(Series series) { IsLoading = true; Title = series.Title; Author = series.Author; CoverImageUri = new Uri(series.CoverImageUri); Illustrator = series.Illustrator; VolumeList.Clear(); foreach (var vol in series.Volumes) { var vvm = new VolumeViewModel { DataContext = vol }; //await vvm.LoadDataAsync(vol.ID); //vvm.Description = vol.Description; //int no = 0; //foreach (var cp in vol.Chapters) //{ // var cpvm = new ChapterPreviewModel // { // Id = cp.Id, // No = cp.ChapterNo, // Title = cp.Title, // }; // vvm.ChapterList.Add(cpvm); //} VolumeList.Add(vvm); } IsLoading = false; //await Task.WhenAll(VolumeList.Select(vvm => vvm.LoadDataAsync(vvm.Id))); }
/// <summary> /// Allows creation of an on-demand snapshot of volumes /// <para> /// If multiple volumes are provided, multiple name patterns are /// required, where the index of the list of items are related. For /// example, the name pattern at index <c>3</c> of the /// <c>namePatterns</c> parameter will be applied to the volume /// specified at index <c>3</c> of the <c>parentVolumeGuids</c> list. /// </para> /// </summary> /// <param name="parentVolumeGuids"> /// List of unique identifiers for all volumes for which to create a /// snapshot /// </param> /// <param name="namePatterns"> /// List of naming patterns for volume snapshots. Options of the /// <c>strftime</c> function are available to format time and the /// variable <c>%v</c> that will be translated to the volume name. /// </param> /// <param name="expirationSeconds"> /// The number of seconds after snapshot creation when the snapshots /// will be automatically deleted /// </param> /// <param name="retentionSeconds"> /// The number of seconds before a user can delete the snapshots. /// </param> /// <returns></returns> public Volume CreateSnapshot( Guid[] parentVolumeGuids, string[] namePatterns, long?expirationSeconds = null, long?retentionSeconds = null) { // prepare parameters GraphQLParameters parameters = new GraphQLParameters(); parameters.Add("parentVvUID", parentVolumeGuids, false); parameters.Add("snapNamePattern", namePatterns, false); parameters.Add("consistencyLevel", SnapshotConsistencyLevel.VV, false); parameters.Add("roSnap", true, false); parameters.Add("expirationSec", expirationSeconds, false); parameters.Add("retentionSec", retentionSeconds, false); TokenResponse tokenResponse = RunMutation <TokenResponse>( @"createSnap", parameters); bool deliverySuccess = DeliverToken(tokenResponse); if (!deliverySuccess) { throw new Exception("Snapshot creation failed"); } // query for the snapshot VolumeFilter filter = new VolumeFilter(); filter.Guid = new GuidFilter(); filter.Guid.MustEqual = tokenResponse.WaitOn; DateTime start = DateTime.UtcNow; while (true) { Thread.Sleep(2000); VolumeList list = GetVolumes(null, filter, null); if (list.FilteredCount > 0) { return(list.Items[0]); } // check if we should time out. double duration = (DateTime.UtcNow - start).TotalSeconds; double remaining = SNAPSHOT_CREATE_WAITTIME_SEC - duration; if (remaining <= 0) { throw new Exception("Snapshot creation timed out"); } } }
/// <summary> /// Allows creating a read/writeable clone of a volume or snapshot /// <para> /// Allows the creation of a volume clone from a base volume or /// snapshot. Clones are read and writeable copies of another volume. /// Clones can be used to quickly instantiate copies of data and data /// for recovery purposes when applications require read/write access /// for copy operations. /// </para> /// </summary> /// <param name="name"> /// The human readable name for the volume clone /// </param> /// <param name="volumeGuid"> /// The unique identifier for the volume or snapshot from which to /// create the clone. /// </param> /// <returns></returns> public Volume CreateClone(string name, Guid volumeGuid) { CreateCloneInput input = new CreateCloneInput(); input.Name = name; input.VolumeGuid = volumeGuid; // prepare parameters GraphQLParameters parameters = new GraphQLParameters(); parameters.Add("input", input, false); TokenResponse tokenResponse = RunMutation <TokenResponse>( @"createClone", parameters); bool deliverySuccess = DeliverToken(tokenResponse); if (!deliverySuccess) { throw new Exception("Clone creation failed"); } // query for the clone VolumeFilter filter = new VolumeFilter(); filter.Name = new StringFilter(); filter.Name.MustEqual = name; DateTime start = DateTime.UtcNow; while (true) { Thread.Sleep(2000); VolumeList list = GetVolumes(null, filter, null); if (list.FilteredCount > 0) { return(list.Items[0]); } // check if we should time out. double duration = (DateTime.UtcNow - start).TotalSeconds; double remaining = SNAPSHOT_CREATE_WAITTIME_SEC - duration; if (remaining <= 0) { throw new Exception("Clone creation timed out"); } } }
public override async Task RunAsync() { Host.WriteVerbose("- Attempting to create a shadow copy set for the volumes: {0}", String.Join(",", VolumeList.ToArray())); UpdateFinalContext(); using (VssClient client = new VssClient(Host)) { client.Initialize(Context); // Create the shadow copy set await client.CreateSnapshotAsync(VolumeList, BackupComponentsDoc, ExcludedWriters, IncludedWriters).ConfigureAwait(false); // Execute BackupComplete, except in fast snapshot creation if ((Context & VssVolumeSnapshotAttributes.DelayedPostSnapshot) == 0) { try { if (HasOption(CommonOptions.OptSetVarScript)) { client.GenerateSetvarScript(GetOptionValue <string>(CommonOptions.OptSetVarScript)); } if (HasOption(OptExecCommand)) { string arguments = String.Empty; if (HasOption(CommonOptions.OptExecCommandArgs)) { arguments = GetOptionValue <string>(CommonOptions.OptExecCommandArgs); } Host.ExecCommand(GetOptionValue <string>(OptExecCommand), arguments); } } catch (Exception) { // Mark backup failure and exit if ((Context & VssVolumeSnapshotAttributes.NoWriters) == 0) { await client.BackupCompleteAsync(false).ConfigureAwait(false); } throw; } // Complete the backup // Note that this will notify writers that the backup is succesful! // (which means eventually log truncation) if ((Context & VssVolumeSnapshotAttributes.NoWriters) == 0) { await client.BackupCompleteAsync(true).ConfigureAwait(false); } } Host.WriteLine("Snapshot creation done."); } }
/// <summary> /// Allows creation of a new volume /// </summary> /// <param name="input"> /// Configuration definition for the new volume /// </param> /// <returns>The created volume</returns> public Volume CreateVolume(CreateVolumeInput input) { // setup parameters GraphQLParameters parameters = new GraphQLParameters(); parameters.Add("input", input); TokenResponse tokenResponse = RunMutation <TokenResponse>( @"createVolumeV3", parameters); RecipeRecordIdentifier identifier = DeliverTokenV2(tokenResponse); if (identifier == null) { throw new Exception("Uncomprehensive information returned from server"); } // wait for recipe completion DateTime start = DateTime.UtcNow; // recipe filter NPodRecipeFilter filter = new NPodRecipeFilter(); filter.NPodGuid = identifier.NPodGuid; filter.RecipeGuid = identifier.RecipeGuid; while (true) { Thread.Sleep(1000); // query for recipes RecipeRecordList recipes = GetNPodRecipes(filter); // if there is no record in the cloud wait a few more seconds // this case should not exist. TODO: Remove in next version. if (recipes.Items.Length == 0) { continue; } // based on the query there should be exactly one RecipeRecord recipe = recipes.Items[0]; // execution failed if (recipe.State == RecipeState.Failed) { string error = string.Concat("volume creation failed", recipe.Status); throw new Exception(error); } // execution completed if (recipe.State == RecipeState.Completed) { VolumeFilter volumeFilter = new VolumeFilter(); volumeFilter.Guid = new GuidFilter(); volumeFilter.Guid.MustEqual = tokenResponse.WaitOn; VolumeList list = GetVolumes(null, volumeFilter, null); if (list.FilteredCount >= 0) { return(list.Items[0]); } } // still ongoing double duration = (DateTime.UtcNow - start).TotalSeconds; double timeRemaining = NPOD_CREATE_WAITTIME_SEC - duration; if (timeRemaining <= 0) { throw new Exception("Snapshot creation timed out"); } } }
/// <summary> /// Performs execution of the command /// </summary> protected override void ProcessRecord() { try { List <VolumeFilter> filters = new List <VolumeFilter>(); VolumeFilter snapsFilter = new VolumeFilter(); snapsFilter.BaseOnly = !OnlySnapshots.IsPresent && !IncludeSnapshots.IsPresent; filters.Add(snapsFilter); if (OnlySnapshots.IsPresent) { VolumeFilter f1 = new VolumeFilter(); f1.SnapshotsOnly = true; filters.Add(f1); } if (ParameterPresent("Guid")) { VolumeFilter f = new VolumeFilter(); f.Guid = new GuidFilter(); f.Guid.MustEqual = Guid; filters.Add(f); } if (ParameterPresent("Name")) { VolumeFilter f = new VolumeFilter(); f.Name = new StringFilter(); f.Name.MustEqual = Name; filters.Add(f); } if (ParameterPresent("NPod")) { VolumeFilter f = new VolumeFilter(); f.NPodGuid = new GuidFilter(); f.NPodGuid.MustEqual = NPod.Guid; filters.Add(f); } if (ParameterPresent("ParentVolume")) { VolumeFilter f = new VolumeFilter(); f.ParentGuid = new GuidFilter(); f.ParentGuid.MustEqual = ParentVolume.Guid; filters.Add(f); // make sure that snapshots are included foreach (VolumeFilter ef in filters) { if (ef.BaseOnly.HasValue) { ef.BaseOnly = false; } } } // convert to filter VolumeFilter filter = GenerateFilter(filters); // Compile a sort direction from the provided input // Default sort direction is Ascending VolumeSort sort = new VolumeSort(); sort.Name = SortDirection.Ascending; PageInput page = PageInput.First; VolumeList list = Connection.GetVolumes(page, filter, sort); foreach (Volume item in list.Items) { WriteObject(item); } while (list.More) { // advance the page page.Page = page.Page + 1; list = Connection.GetVolumes(page, filter, sort); foreach (Volume item in list.Items) { WriteObject(item); } } } catch (AggregateException exceptions) { foreach (Exception ex in exceptions.InnerExceptions) { WriteError(ex); } } catch (Exception ex) { WriteError(ex); } }
private Book GetBookFromVolume(VolumeList volumeList) { if (volumeList?.Items is { Length : > 0 } && volumeList.Items[0] != null)
/// <summary>获取系统状态 /// </summary> /// <returns></returns> public async Task <VolumeList> GetVolumeList() { var client = _clientManager.GetMasterClient(); var response = await client.VolumeListAsync(new MasterPb.VolumeListRequest()); #region functions VolumeEcShardInformation ecShardFunc(MasterPb.VolumeEcShardInformationMessage e) { return(new VolumeEcShardInformation() { Id = (int)e.Id, Collection = e.Collection, EcIndexBits = (int)e.EcIndexBits }); } VolumeInformation volumeFunc(MasterPb.VolumeInformationMessage v) { return(new VolumeInformation() { Id = (int)v.Id, Size = (long)v.Size, Collection = v.Collection, FileCount = (long)v.FileCount, DeletedByteCount = (long)v.DeletedByteCount, DeleteCount = (long)v.DeleteCount, ReadOnly = v.ReadOnly, ReplicaPlacement = (int)v.ReplicaPlacement, Version = (int)v.Version, Ttl = (int)v.Ttl, CompactRevision = (int)v.CompactRevision, ModifiedAtSecond = (long)v.ModifiedAtSecond }); } DataNode dataNodeFunc(MasterPb.DataNodeInfo d) { return(new DataNode() { Id = d.Id, VolumeCount = (long)d.VolumeCount, MaxVolumeCount = (long)d.MaxVolumeCount, FreeVolumeCount = (long)d.FreeVolumeCount, ActiveVolumeCount = (long)d.ActiveVolumeCount, EcShareInfos = d.EcShardInfos.Select(ecShardFunc).ToList(), VolumeInfos = d.VolumeInfos.Select(volumeFunc).ToList() }); } #endregion var volumeList = new VolumeList() { VolumeSizeLimitMb = (long)response.VolumeSizeLimitMb, Topology = new Topology() { Id = response.TopologyInfo.Id, VolumeCount = (long)response.TopologyInfo.VolumeCount, MaxVolumeCount = (long)response.TopologyInfo.MaxVolumeCount, FreeVolumeCount = (long)response.TopologyInfo.FreeVolumeCount, ActiveVolumeCount = (long)response.TopologyInfo.ActiveVolumeCount, DataCenters = response.TopologyInfo.DataCenterInfos.Select(x => { var dataCenter = new DataCenter() { Id = x.Id, VolumeCount = (long)x.VolumeCount, MaxVolumeCount = (long)x.MaxVolumeCount, FreeVolumeCount = (long)x.FreeVolumeCount, ActiveVolumeCount = (long)x.ActiveVolumeCount, Racks = x.RackInfos.Select(r => { var rack = new Rack() { Id = r.Id, VolumeCount = (long)r.VolumeCount, MaxVolumeCount = (long)r.MaxVolumeCount, FreeVolumeCount = (long)r.FreeVolumeCount, ActiveVolumeCount = (long)r.ActiveVolumeCount, DataNodes = r.DataNodeInfos.Select(dataNodeFunc).ToList() }; return(rack); }).ToList() }; return(dataCenter); }).ToList() } }; return(volumeList); }