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");
                }
            }
        }
Пример #4
0
        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.");
            }
        }
Пример #5
0
        /// <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");
                }
            }
        }
Пример #6
0
        /// <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);
            }
        }
Пример #7
0
 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);
        }