Beispiel #1
0
 internal SnapshotData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData, IDictionary <string, string> tags, AzureLocation location, string managedBy, SnapshotSku sku, ExtendedLocation extendedLocation, DateTimeOffset?timeCreated, OperatingSystemTypes?osType, HyperVGeneration?hyperVGeneration, DiskPurchasePlan purchasePlan, SupportedCapabilities supportedCapabilities, DiskCreationData creationData, int?diskSizeGB, long?diskSizeBytes, DiskState?diskState, string uniqueId, EncryptionSettingsGroup encryptionSettingsGroup, string provisioningState, bool?incremental, DiskEncryption encryption, NetworkAccessPolicy?networkAccessPolicy, ResourceIdentifier diskAccessId, DiskSecurityProfile securityProfile, bool?supportsHibernation, PublicNetworkAccess?publicNetworkAccess, float?completionPercent, CopyCompletionError copyCompletionError, DataAccessAuthMode?dataAccessAuthMode) : base(id, name, resourceType, systemData, tags, location)
 {
     ManagedBy               = managedBy;
     Sku                     = sku;
     ExtendedLocation        = extendedLocation;
     TimeCreated             = timeCreated;
     OSType                  = osType;
     HyperVGeneration        = hyperVGeneration;
     PurchasePlan            = purchasePlan;
     SupportedCapabilities   = supportedCapabilities;
     CreationData            = creationData;
     DiskSizeGB              = diskSizeGB;
     DiskSizeBytes           = diskSizeBytes;
     DiskState               = diskState;
     UniqueId                = uniqueId;
     EncryptionSettingsGroup = encryptionSettingsGroup;
     ProvisioningState       = provisioningState;
     Incremental             = incremental;
     Encryption              = encryption;
     NetworkAccessPolicy     = networkAccessPolicy;
     DiskAccessId            = diskAccessId;
     SecurityProfile         = securityProfile;
     SupportsHibernation     = supportsHibernation;
     PublicNetworkAccess     = publicNetworkAccess;
     CompletionPercent       = completionPercent;
     CopyCompletionError     = copyCompletionError;
     DataAccessAuthMode      = dataAccessAuthMode;
 }
Beispiel #2
0
        public void HandleMessage(Packet msg)
        {
            if (msg.PacketType == P2PMessageCode.Hello)
            {
                HandleHello(Deserialize <HelloMessage>(msg.Data));
                Metrics.HellosReceived++;

                foreach (Capability capability in AgreedCapabilities.GroupBy(c => c.ProtocolCode).Select(c => c.OrderBy(v => v.Version).Last()))
                {
                    if (Logger.IsTrace)
                    {
                        Logger.Trace($"{Session.RemoteNodeId} Starting protocolHandler for {capability.ProtocolCode} v{capability.Version} on {Session.RemotePort}");
                    }
                    SubprotocolRequested?.Invoke(this, new ProtocolEventArgs(capability.ProtocolCode, capability.Version));
                }
            }
            else if (msg.PacketType == P2PMessageCode.Disconnect)
            {
                DisconnectMessage disconnectMessage = Deserialize <DisconnectMessage>(msg.Data);
                if (Logger.IsTrace)
                {
                    Logger.Trace($"|NetworkTrace| {Session.RemoteNodeId} Received disconnect ({(Enum.IsDefined(typeof(DisconnectReason), (byte)disconnectMessage.Reason) ? ((DisconnectReason)disconnectMessage.Reason).ToString() : disconnectMessage.Reason.ToString())}) on {Session.RemotePort}");
                }
                Close(disconnectMessage.Reason);
            }
            else if (msg.PacketType == P2PMessageCode.Ping)
            {
                if (Logger.IsTrace)
                {
                    Logger.Trace($"{Session.RemoteNodeId} Received PING on {Session.RemotePort}");
                }
                HandlePing();
            }
            else if (msg.PacketType == P2PMessageCode.Pong)
            {
                if (Logger.IsTrace)
                {
                    Logger.Trace($"{Session.RemoteNodeId} Received PONG on {Session.RemotePort}");
                }
                HandlePong(msg);
            }
            else if (msg.PacketType == P2PMessageCode.AddCapability)
            {
                var message    = Deserialize <AddCapabilityMessage>(msg.Data);
                var capability = message.Capability;
                AgreedCapabilities.Add(message.Capability);
                SupportedCapabilities.Add(message.Capability);
                if (Logger.IsTrace)
                {
                    Logger.Trace($"{Session.RemoteNodeId} Starting protocolHandler for {capability.ProtocolCode} v{capability.Version} on {Session.RemotePort}");
                }
                SubprotocolRequested?.Invoke(this, new ProtocolEventArgs(capability.ProtocolCode, capability.Version));
            }
            else
            {
                Logger.Error($"{Session.RemoteNodeId} Unhandled packet type: {msg.PacketType}");
            }
        }
        public override void AddSupportedCapability(Capability capability)
        {
            if (SupportedCapabilities.Contains(capability))
            {
                return;
            }

            SupportedCapabilities.Add(capability);
        }
 internal DiskRestorePointData(ResourceIdentifier id, string name, ResourceType type, DateTimeOffset?timeCreated, string sourceResourceId, OperatingSystemTypes?oSType, HyperVGeneration?hyperVGeneration, DiskPurchasePlan purchasePlan, SupportedCapabilities supportedCapabilities, string familyId, string sourceUniqueId, Encryption encryption, bool?supportsHibernation, NetworkAccessPolicy?networkAccessPolicy, PublicNetworkAccess?publicNetworkAccess, string diskAccessId, float?completionPercent, string replicationState, string sourceResourceLocation) : base(id, name, type)
 {
     TimeCreated            = timeCreated;
     SourceResourceId       = sourceResourceId;
     OSType                 = oSType;
     HyperVGeneration       = hyperVGeneration;
     PurchasePlan           = purchasePlan;
     SupportedCapabilities  = supportedCapabilities;
     FamilyId               = familyId;
     SourceUniqueId         = sourceUniqueId;
     Encryption             = encryption;
     SupportsHibernation    = supportsHibernation;
     NetworkAccessPolicy    = networkAccessPolicy;
     PublicNetworkAccess    = publicNetworkAccess;
     DiskAccessId           = diskAccessId;
     CompletionPercent      = completionPercent;
     ReplicationState       = replicationState;
     SourceResourceLocation = sourceResourceLocation;
 }
Beispiel #5
0
 internal ManagedDiskData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData, IDictionary <string, string> tags, AzureLocation location, ResourceIdentifier managedBy, IReadOnlyList <ResourceIdentifier> managedByExtended, DiskSku sku, IList <string> zones, ExtendedLocation extendedLocation, DateTimeOffset?timeCreated, OperatingSystemTypes?osType, HyperVGeneration?hyperVGeneration, DiskPurchasePlan purchasePlan, SupportedCapabilities supportedCapabilities, DiskCreationData creationData, int?diskSizeGB, long?diskSizeBytes, string uniqueId, EncryptionSettingsGroup encryptionSettingsGroup, string provisioningState, long?diskIopsReadWrite, long?diskMBpsReadWrite, long?diskIopsReadOnly, long?diskMBpsReadOnly, DiskState?diskState, DiskEncryption encryption, int?maxShares, IReadOnlyList <ShareInfoElement> shareInfo, NetworkAccessPolicy?networkAccessPolicy, ResourceIdentifier diskAccessId, string tier, bool?burstingEnabled, PropertyUpdatesInProgress propertyUpdatesInProgress, bool?supportsHibernation, DiskSecurityProfile securityProfile, float?completionPercent, PublicNetworkAccess?publicNetworkAccess, DataAccessAuthMode?dataAccessAuthMode) : base(id, name, resourceType, systemData, tags, location)
 {
     ManagedBy         = managedBy;
     ManagedByExtended = managedByExtended;
     Sku                       = sku;
     Zones                     = zones;
     ExtendedLocation          = extendedLocation;
     TimeCreated               = timeCreated;
     OSType                    = osType;
     HyperVGeneration          = hyperVGeneration;
     PurchasePlan              = purchasePlan;
     SupportedCapabilities     = supportedCapabilities;
     CreationData              = creationData;
     DiskSizeGB                = diskSizeGB;
     DiskSizeBytes             = diskSizeBytes;
     UniqueId                  = uniqueId;
     EncryptionSettingsGroup   = encryptionSettingsGroup;
     ProvisioningState         = provisioningState;
     DiskIopsReadWrite         = diskIopsReadWrite;
     DiskMBpsReadWrite         = diskMBpsReadWrite;
     DiskIopsReadOnly          = diskIopsReadOnly;
     DiskMBpsReadOnly          = diskMBpsReadOnly;
     DiskState                 = diskState;
     Encryption                = encryption;
     MaxShares                 = maxShares;
     ShareInfo                 = shareInfo;
     NetworkAccessPolicy       = networkAccessPolicy;
     DiskAccessId              = diskAccessId;
     Tier                      = tier;
     BurstingEnabled           = burstingEnabled;
     PropertyUpdatesInProgress = propertyUpdatesInProgress;
     SupportsHibernation       = supportsHibernation;
     SecurityProfile           = securityProfile;
     CompletionPercent         = completionPercent;
     PublicNetworkAccess       = publicNetworkAccess;
     DataAccessAuthMode        = dataAccessAuthMode;
 }
        private void Run()
        {
            // EncryptionSettingsCollection
            EncryptionSettingsCollection vEncryptionSettingsCollection = null;

            // EncryptionSettingsCollection
            EncryptionSettingsElement vEncryptionSettingsElement = null;

            // Encryption
            Encryption vEncryption = null;

            // Sku
            DiskSku vSku = null;

            // SupportedCapabilities
            SupportedCapabilities vSupportedCapabilities = null;

            if (this.IsParameterBound(c => c.EncryptionSettingsEnabled))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }
                vEncryptionSettingsCollection.Enabled = (bool)this.EncryptionSettingsEnabled;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsElement == null)
                {
                    vEncryptionSettingsElement = new EncryptionSettingsElement();
                    vEncryptionSettingsCollection.EncryptionSettings.Add(vEncryptionSettingsElement);
                }

                vEncryptionSettingsCollection.EncryptionSettings[0].DiskEncryptionKey = this.DiskEncryptionKey;
            }

            if (this.IsParameterBound(c => c.KeyEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsElement == null)
                {
                    vEncryptionSettingsElement = new EncryptionSettingsElement();
                    vEncryptionSettingsCollection.EncryptionSettings.Add(vEncryptionSettingsElement);
                }

                vEncryptionSettingsCollection.EncryptionSettings[0].KeyEncryptionKey = this.KeyEncryptionKey;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionSetId))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.DiskEncryptionSetId = this.DiskEncryptionSetId;
            }

            if (this.IsParameterBound(c => c.EncryptionType))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.Type = this.EncryptionType;
            }

            if (this.IsParameterBound(c => c.SkuName))
            {
                if (vSku == null)
                {
                    vSku = new DiskSku();
                }
                vSku.Name = this.SkuName;
            }

            if (this.IsParameterBound(c => c.AcceleratedNetwork))
            {
                if (vSupportedCapabilities == null)
                {
                    vSupportedCapabilities = new SupportedCapabilities();
                }
                vSupportedCapabilities.AcceleratedNetwork = AcceleratedNetwork;
            }

            if (this.IsParameterBound(c => c.Architecture))
            {
                if (vSupportedCapabilities == null)
                {
                    vSupportedCapabilities = new SupportedCapabilities();
                }
                vSupportedCapabilities.Architecture = this.Architecture;
            }

            var vDiskUpdate = new PSDiskUpdate
            {
                OsType            = this.IsParameterBound(c => c.OsType) ? this.OsType : (OperatingSystemTypes?)null,
                DiskSizeGB        = this.IsParameterBound(c => c.DiskSizeGB) ? this.DiskSizeGB : (int?)null,
                DiskIOPSReadWrite = this.IsParameterBound(c => c.DiskIOPSReadWrite) ? this.DiskIOPSReadWrite : (int?)null,
                DiskMBpsReadWrite = this.IsParameterBound(c => c.DiskMBpsReadWrite) ? this.DiskMBpsReadWrite : (int?)null,
                DiskIOPSReadOnly  = this.IsParameterBound(c => c.DiskIOPSReadOnly) ? this.DiskIOPSReadOnly : null,
                DiskMBpsReadOnly  = this.IsParameterBound(c => c.DiskMBpsReadOnly) ? this.DiskMBpsReadOnly : null,
                MaxShares         = this.IsParameterBound(c => c.MaxSharesCount) ? this.MaxSharesCount : null,
                Tags = this.IsParameterBound(c => c.Tag) ? this.Tag.Cast <DictionaryEntry>().ToDictionary(ht => (string)ht.Key, ht => (string)ht.Value) : null,
                NetworkAccessPolicy          = this.IsParameterBound(c => c.NetworkAccessPolicy) ? this.NetworkAccessPolicy: null,
                DiskAccessId                 = this.IsParameterBound(c => c.DiskAccessId) ? this.DiskAccessId: null,
                EncryptionSettingsCollection = vEncryptionSettingsCollection,
                Encryption            = vEncryption,
                Sku                   = vSku,
                Tier                  = this.IsParameterBound(c => c.Tier) ? this.Tier : null,
                BurstingEnabled       = this.IsParameterBound(c => c.BurstingEnabled) ? this.BurstingEnabled : null,
                PurchasePlan          = this.IsParameterBound(c => c.PurchasePlan) ? this.PurchasePlan : null,
                SupportsHibernation   = this.IsParameterBound(c => c.SupportsHibernation) ? SupportsHibernation : null,
                SupportedCapabilities = vSupportedCapabilities,
                PublicNetworkAccess   = this.IsParameterBound(c => c.PublicNetworkAccess) ? PublicNetworkAccess : null,
                DataAccessAuthMode    = this.IsParameterBound(c => c.DataAccessAuthMode) ? DataAccessAuthMode : null
            };

            WriteObject(vDiskUpdate);
        }
Beispiel #7
0
        /// <summary>
        /// Handles a message with a command like "PRIVMSG"
        /// </summary>
        private async Task HandleCommand(RawMessage message)
        {
            switch (message.Command)
            {
            case "CAP":
            {
                var capCommand = message.Parameters[1];
                switch (capCommand)
                {
                case "LS":
                {
                    if (_negotiatingCapabilities)
                    {
                        break;
                    }

                    _serverCapabilities = message.Parameters[2].Split(' ').ToArray();
                    Debug.WriteLine("Offered capabilities: {0}", args: string.Join(", ", _serverCapabilities));

                    var supportedCapabilities = _serverCapabilities
                                                .Where(sc => SupportedCapabilities.Contains(sc))
                                                .ToArray();

                    if (supportedCapabilities.Any())
                    {
                        _negotiatingCapabilities = true;
                        await Raw.SendMessageAsync(new RawMessage("CAP", "REQ",
                                                                  string.Join(' ', supportedCapabilities)));
                    }
                    else
                    {
                        // We don't support any of the offered capabilities, we end here.
                        await Raw.SendMessageAsync(new RawMessage("CAP", "END"));

                        Debug.WriteLine("Negotiated no capabilities");
                    }

                    break;
                }

                case "ACK":
                {
                    if (!_negotiatingCapabilities)
                    {
                        break;
                    }

                    _acknowledgedCapabilities = message.Parameters[2].Split(' ');
                    await Raw.SendMessageAsync(new RawMessage("CAP", "END"));

                    _negotiatingCapabilities = false;
                    Debug.WriteLine("Finished negotiating capabilities: {0}",
                                    args: string.Join(", ", _acknowledgedCapabilities));

                    break;
                }

                default:
                {
                    Debug.WriteLine("Unhandled capability command: {0}", args: capCommand);

                    break;
                }
                }

                break;
            }

            case "PRIVMSG":
            {
                if (!CheckForExpected(message))
                {
                    var ircMessage = new IrcMessage(this, message);
                    var pme        = new MessageReceivedEventArgs(this, ircMessage);
                    MessageReceived?.Invoke(this, pme);
                }

                break;
            }

            case "PING":
            {
                await Raw.SendMessageAsync(new RawMessage("PONG", message.Parameters[0]));

                break;
            }

            default:
            {
                if (!CheckForExpected(message))
                {
                    Debug.WriteLine("Unhandled IRC message: {0}", message);
                }

                break;
            }
            }
        }
        public override void HandleMessage(Packet msg)
        {
            switch (msg.PacketType)
            {
            case P2PMessageCode.Hello:
            {
                Metrics.HellosReceived++;
                HandleHello(Deserialize <HelloMessage>(msg.Data));

                foreach (Capability capability in
                         AgreedCapabilities.GroupBy(c => c.ProtocolCode).Select(c => c.OrderBy(v => v.Version).Last()))
                {
                    if (Logger.IsTrace)
                    {
                        Logger.Trace($"{Session} Starting protocolHandler for {capability.ProtocolCode} v{capability.Version} on {Session.RemotePort}");
                    }
                    SubprotocolRequested?.Invoke(this, new ProtocolEventArgs(capability.ProtocolCode, capability.Version));
                }

                break;
            }

            case P2PMessageCode.Disconnect:
            {
                DisconnectMessage disconnectMessage = Deserialize <DisconnectMessage>(msg.Data);
                ReportIn(disconnectMessage);
                if (Logger.IsTrace)
                {
                    string reason = Enum.IsDefined(typeof(DisconnectReason), (byte)disconnectMessage.Reason)
                            ? ((DisconnectReason)disconnectMessage.Reason).ToString()
                            : disconnectMessage.Reason.ToString();
                    Logger.Trace($"{Session} Received disconnect ({reason}) on {Session.RemotePort}");
                }

                Close(disconnectMessage.Reason);
                break;
            }

            case P2PMessageCode.Ping:
            {
                if (Logger.IsTrace)
                {
                    Logger.Trace($"{Session} Received PING on {Session.RemotePort}");
                }
                HandlePing();
                break;
            }

            case P2PMessageCode.Pong:
            {
                if (Logger.IsTrace)
                {
                    Logger.Trace($"{Session} Received PONG on {Session.RemotePort}");
                }
                HandlePong(msg);
                break;
            }

            case P2PMessageCode.AddCapability:
            {
                AddCapabilityMessage message    = Deserialize <AddCapabilityMessage>(msg.Data);
                Capability           capability = message.Capability;
                AgreedCapabilities.Add(message.Capability);
                SupportedCapabilities.Add(message.Capability);
                if (Logger.IsTrace)
                {
                    Logger.Trace($"{Session.RemoteNodeId} Starting handler for {capability} on {Session.RemotePort}");
                }
                SubprotocolRequested?.Invoke(this, new ProtocolEventArgs(capability.ProtocolCode, capability.Version));
                break;
            }

            default:
                Logger.Error($"{Session.RemoteNodeId} Unhandled packet type: {msg.PacketType}");
                break;
            }
        }
        private void HandleHello(HelloMessage hello)
        {
            ReportIn(hello);
            bool isInbound = !_sentHello;

            if (Logger.IsTrace)
            {
                Logger.Trace($"{Session} P2P received hello.");
            }

            if (!hello.NodeId.Equals(Session.RemoteNodeId))
            {
                if (Logger.IsDebug)
                {
                    Logger.Debug($"Inconsistent Node ID details - expected {Session.RemoteNodeId}, " +
                                 $"received hello with {hello.NodeId} " +
                                 $"on {(isInbound ? "IN connection" : "OUT connection")}");
                }
                // it does not really matter if there is mismatch - we do not use it anywhere
//                throw new NodeDetailsMismatchException();
            }

            RemoteClientId        = hello.ClientId;
            Session.Node.ClientId = hello.ClientId;

            if (Logger.IsTrace)
            {
                Logger.Trace(!_sentHello
                ? $"{Session.RemoteNodeId} P2P initiating inbound {hello.Protocol}.{hello.P2PVersion} " +
                             $"on {hello.ListenPort} ({hello.ClientId})"
                : $"{Session.RemoteNodeId} P2P initiating outbound {hello.Protocol}.{hello.P2PVersion} " +
                             $"on {hello.ListenPort} ({hello.ClientId})");
            }

            // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md
            // Clients implementing a newer version simply send a packet with higher version and possibly additional list elements.
            // * If such a packet is received by a node with lower version,
            //   it will blindly assume that the remote end is backwards-compatible and respond with the old handshake.
            // * If the packet is received by a node with equal version,
            //   new features of the protocol can be used.
            // * If the packet is received by a node with higher version,
            //   it can enable backwards-compatibility logic or drop the connection.

            ProtocolVersion = hello.P2PVersion;

            List <Capability> capabilities = hello.Capabilities;

            AvailableCapabilities = new List <Capability>(capabilities);
            foreach (Capability theirCapability in capabilities)
            {
                if (SupportedCapabilities.Contains(theirCapability))
                {
                    if (Logger.IsTrace)
                    {
                        Logger.Trace($"{Session.RemoteNodeId} Agreed on {theirCapability.ProtocolCode} v{theirCapability.Version}");
                    }
                    AgreedCapabilities.Add(theirCapability);
                }
                else
                {
                    if (Logger.IsTrace)
                    {
                        Logger.Trace($"{Session.RemoteNodeId} Capability not supported " +
                                     $"{theirCapability.ProtocolCode} v{theirCapability.Version}");
                    }
                }
            }

            if (!capabilities.Any(c => SupportedCapabilities.Contains(c)))
            {
                Session.InitiateDisconnect(
                    DisconnectReason.UselessPeer,
                    $"capabilities: {string.Join(", ", capabilities)}");
            }

            ReceivedProtocolInitMsg(hello);

            P2PProtocolInitializedEventArgs eventArgs = new P2PProtocolInitializedEventArgs(this)
            {
                P2PVersion   = ProtocolVersion,
                ClientId     = RemoteClientId,
                Capabilities = capabilities,
                ListenPort   = hello.ListenPort
            };

            ProtocolInitialized?.Invoke(this, eventArgs);
        }
Beispiel #10
0
        public void HandleHello(HelloMessage hello)
        {
            Logger.Info($"{P2PSession.RemoteNodeId} P2P received hello.");
            if (!hello.NodeId.Equals(P2PSession.RemoteNodeId))
            {
                throw new NodeDetailsMismatchException();
            }

            //P2PSession.RemoteNodeId = hello.NodeId;
            //P2PSession.RemotePort = hello.ListenPort;
            RemoteClientId = hello.ClientId;

            Logger.Info(!_sentHello
                ? $"{P2PSession.RemoteNodeId} P2P initiating inbound {hello.Protocol} v{hello.P2PVersion} protocolHandler on {hello.ListenPort} ({hello.ClientId})"
                : $"{P2PSession.RemoteNodeId} P2P initiating outbound {hello.Protocol} v{hello.P2PVersion} protocolHandler on {hello.ListenPort} ({hello.ClientId})");

            // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md
            // Clients implementing a newer version simply send a packet with higher version and possibly additional list elements.
            // * If such a packet is received by a node with lower version, it will blindly assume that the remote end is backwards-compatible and respond with the old handshake.
            // * If the packet is received by a node with equal version, new features of the protocol can be used.
            // * If the packet is received by a node with higher version, it can enable backwards-compatibility logic or drop the connection.

            //Moved that validation to PeerManager
            //if (hello.P2PVersion < 4 || hello.P2PVersion > 5)
            //{
            //    //triggers disconnect on the session, which will trigger it on all protocol handlers
            //    P2PSession.InitiateDisconnectAsync(DisconnectReason.IncompatibleP2PVersion);
            //    //Disconnect(DisconnectReason.IncompatibleP2PVersion);
            //    return;
            //}

            ProtocolVersion = hello.P2PVersion;

            //TODO Check required capabilities and disconnect if not supported

            foreach (Capability remotePeerCapability in hello.Capabilities)
            {
                if (SupportedCapabilities.Contains(remotePeerCapability))
                {
                    Logger.Info($"{P2PSession.RemoteNodeId} Agreed on {remotePeerCapability.ProtocolCode} v{remotePeerCapability.Version}");
                    AgreedCapabilities.Add(remotePeerCapability);
                }
                else
                {
                    Logger.Info($"{P2PSession.RemoteNodeId} Capability not supported {remotePeerCapability.ProtocolCode} v{remotePeerCapability.Version}");
                }
            }

            //if (!_sentHello)
            //{
            //    throw new InvalidOperationException($"Handling {nameof(HelloMessage)} from peer before sending our own");
            //}
            _isInitialized = true;
            ReceivedProtocolInitMsg(hello);

            var eventArgs = new P2PProtocolInitializedEventArgs(this)
            {
                P2PVersion   = hello.P2PVersion,
                ClientId     = hello.ClientId,
                Capabilities = hello.Capabilities
            };

            ProtocolInitialized?.Invoke(this, eventArgs);
        }
        internal static SnapshotData DeserializeSnapshotData(JsonElement element)
        {
            Optional <string>            managedBy                               = default;
            Optional <SnapshotSku>       sku                                     = default;
            Optional <ExtendedLocation>  extendedLocation                        = default;
            IDictionary <string, string> tags                                    = default;
            AzureLocation                           location                     = default;
            ResourceIdentifier                      id                           = default;
            string                                  name                         = default;
            ResourceType                            type                         = default;
            SystemData                              systemData                   = default;
            Optional <DateTimeOffset>               timeCreated                  = default;
            Optional <OperatingSystemTypes>         osType                       = default;
            Optional <HyperVGeneration>             hyperVGeneration             = default;
            Optional <DiskPurchasePlan>             purchasePlan                 = default;
            Optional <SupportedCapabilities>        supportedCapabilities        = default;
            Optional <CreationData>                 creationData                 = default;
            Optional <int>                          diskSizeGB                   = default;
            Optional <long>                         diskSizeBytes                = default;
            Optional <DiskState>                    diskState                    = default;
            Optional <string>                       uniqueId                     = default;
            Optional <EncryptionSettingsCollection> encryptionSettingsCollection = default;
            Optional <string>                       provisioningState            = default;
            Optional <bool>                         incremental                  = default;
            Optional <Encryption>                   encryption                   = default;
            Optional <NetworkAccessPolicy>          networkAccessPolicy          = default;
            Optional <string>                       diskAccessId                 = default;
            Optional <DiskSecurityProfile>          securityProfile              = default;
            Optional <bool>                         supportsHibernation          = default;
            Optional <PublicNetworkAccess>          publicNetworkAccess          = default;
            Optional <float>                        completionPercent            = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("managedBy"))
                {
                    managedBy = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("sku"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    sku = SnapshotSku.DeserializeSnapshotSku(property.Value);
                    continue;
                }
                if (property.NameEquals("extendedLocation"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    extendedLocation = ExtendedLocation.DeserializeExtendedLocation(property.Value);
                    continue;
                }
                if (property.NameEquals("tags"))
                {
                    Dictionary <string, string> dictionary = new Dictionary <string, string>();
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        dictionary.Add(property0.Name, property0.Value.GetString());
                    }
                    tags = dictionary;
                    continue;
                }
                if (property.NameEquals("location"))
                {
                    location = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("id"))
                {
                    id = new ResourceIdentifier(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("name"))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("type"))
                {
                    type = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("systemData"))
                {
                    systemData = JsonSerializer.Deserialize <SystemData>(property.Value.ToString());
                    continue;
                }
                if (property.NameEquals("properties"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.NameEquals("timeCreated"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            timeCreated = property0.Value.GetDateTimeOffset("O");
                            continue;
                        }
                        if (property0.NameEquals("osType"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            osType = property0.Value.GetString().ToOperatingSystemTypes();
                            continue;
                        }
                        if (property0.NameEquals("hyperVGeneration"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            hyperVGeneration = new HyperVGeneration(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("purchasePlan"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            purchasePlan = DiskPurchasePlan.DeserializeDiskPurchasePlan(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("supportedCapabilities"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            supportedCapabilities = SupportedCapabilities.DeserializeSupportedCapabilities(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("creationData"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            creationData = CreationData.DeserializeCreationData(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("diskSizeGB"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskSizeGB = property0.Value.GetInt32();
                            continue;
                        }
                        if (property0.NameEquals("diskSizeBytes"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskSizeBytes = property0.Value.GetInt64();
                            continue;
                        }
                        if (property0.NameEquals("diskState"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskState = new DiskState(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("uniqueId"))
                        {
                            uniqueId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("encryptionSettingsCollection"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            encryptionSettingsCollection = EncryptionSettingsCollection.DeserializeEncryptionSettingsCollection(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("provisioningState"))
                        {
                            provisioningState = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("incremental"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            incremental = property0.Value.GetBoolean();
                            continue;
                        }
                        if (property0.NameEquals("encryption"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            encryption = Encryption.DeserializeEncryption(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("networkAccessPolicy"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            networkAccessPolicy = new NetworkAccessPolicy(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("diskAccessId"))
                        {
                            diskAccessId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("securityProfile"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            securityProfile = DiskSecurityProfile.DeserializeDiskSecurityProfile(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("supportsHibernation"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            supportsHibernation = property0.Value.GetBoolean();
                            continue;
                        }
                        if (property0.NameEquals("publicNetworkAccess"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            publicNetworkAccess = new PublicNetworkAccess(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("completionPercent"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            completionPercent = property0.Value.GetSingle();
                            continue;
                        }
                    }
                    continue;
                }
            }
            return(new SnapshotData(id, name, type, systemData, tags, location, managedBy.Value, sku.Value, extendedLocation.Value, Optional.ToNullable(timeCreated), Optional.ToNullable(osType), Optional.ToNullable(hyperVGeneration), purchasePlan.Value, supportedCapabilities.Value, creationData.Value, Optional.ToNullable(diskSizeGB), Optional.ToNullable(diskSizeBytes), Optional.ToNullable(diskState), uniqueId.Value, encryptionSettingsCollection.Value, provisioningState.Value, Optional.ToNullable(incremental), encryption.Value, Optional.ToNullable(networkAccessPolicy), diskAccessId.Value, securityProfile.Value, Optional.ToNullable(supportsHibernation), Optional.ToNullable(publicNetworkAccess), Optional.ToNullable(completionPercent)));
        }
        public void HandleHello(HelloMessage hello)
        {
            bool isInbound = !_sentHello;

            if (Logger.IsTrace)
            {
                Logger.Trace($"{P2PSession.RemoteNodeId} P2P received hello.");
            }


            if (!hello.NodeId.Equals(P2PSession.RemoteNodeId))
            {
                if (Logger.IsDebug)
                {
                    Logger.Debug($"Inconsistent Node ID details - expected {P2PSession.RemoteNodeId}, received hello with {hello.NodeId} on " + (isInbound ? "IN connection" : "OUT connection"));
                }
                // it does not really matter if there is mismatch - we do not use it anywhere
//                throw new NodeDetailsMismatchException();
            }

            RemoteClientId = hello.ClientId;

            Logger.Trace(!_sentHello
                ? $"{P2PSession.RemoteNodeId} P2P initiating inbound {hello.Protocol} v{hello.P2PVersion} on {hello.ListenPort} ({hello.ClientId})"
                : $"{P2PSession.RemoteNodeId} P2P initiating outbound {hello.Protocol} v{hello.P2PVersion} on {hello.ListenPort} ({hello.ClientId})");

            // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md
            // Clients implementing a newer version simply send a packet with higher version and possibly additional list elements.
            // * If such a packet is received by a node with lower version, it will blindly assume that the remote end is backwards-compatible and respond with the old handshake.
            // * If the packet is received by a node with equal version, new features of the protocol can be used.
            // * If the packet is received by a node with higher version, it can enable backwards-compatibility logic or drop the connection.

            ProtocolVersion = hello.P2PVersion;

            var capabilities = hello.Capabilities;

            foreach (Capability remotePeerCapability in capabilities)
            {
                if (SupportedCapabilities.Contains(remotePeerCapability))
                {
                    if (Logger.IsTrace)
                    {
                        Logger.Trace($"{P2PSession.RemoteNodeId} Agreed on {remotePeerCapability.ProtocolCode} v{remotePeerCapability.Version}");
                    }
                    AgreedCapabilities.Add(remotePeerCapability);
                }
                else
                {
                    if (Logger.IsTrace)
                    {
                        Logger.Trace($"{P2PSession.RemoteNodeId} Capability not supported {remotePeerCapability.ProtocolCode} v{remotePeerCapability.Version}");
                    }
                }
            }

            _isInitialized = true;

            if (!capabilities.Any(x => x.ProtocolCode == Protocol.Eth && (x.Version == 62 || x.Version == 63)))
            {
                Disconnect(DisconnectReason.UselessPeer);
            }

            ReceivedProtocolInitMsg(hello);

            var eventArgs = new P2PProtocolInitializedEventArgs(this)
            {
                P2PVersion   = ProtocolVersion,
                ClientId     = RemoteClientId,
                Capabilities = capabilities,
                ListenPort   = hello.ListenPort
            };

            ProtocolInitialized?.Invoke(this, eventArgs);
        }
        internal static DiskData DeserializeDiskData(JsonElement element)
        {
            Optional <string> managedBy = default;
            Optional <IReadOnlyList <string> > managedByExtended = default;
            Optional <DiskSku>           sku                                          = default;
            Optional <IList <string> >   zones                                        = default;
            Optional <ExtendedLocation>  extendedLocation                             = default;
            IDictionary <string, string> tags                                         = default;
            AzureLocation                                location                     = default;
            ResourceIdentifier                           id                           = default;
            string                                       name                         = default;
            ResourceType                                 type                         = default;
            Optional <DateTimeOffset>                    timeCreated                  = default;
            Optional <OperatingSystemTypes>              osType                       = default;
            Optional <HyperVGeneration>                  hyperVGeneration             = default;
            Optional <DiskPurchasePlan>                  purchasePlan                 = default;
            Optional <SupportedCapabilities>             supportedCapabilities        = default;
            Optional <CreationData>                      creationData                 = default;
            Optional <int>                               diskSizeGB                   = default;
            Optional <long>                              diskSizeBytes                = default;
            Optional <string>                            uniqueId                     = default;
            Optional <EncryptionSettingsCollection>      encryptionSettingsCollection = default;
            Optional <string>                            provisioningState            = default;
            Optional <long>                              diskIOPSReadWrite            = default;
            Optional <long>                              diskMBpsReadWrite            = default;
            Optional <long>                              diskIOPSReadOnly             = default;
            Optional <long>                              diskMBpsReadOnly             = default;
            Optional <DiskState>                         diskState                    = default;
            Optional <Encryption>                        encryption                   = default;
            Optional <int>                               maxShares                    = default;
            Optional <IReadOnlyList <ShareInfoElement> > shareInfo                    = default;
            Optional <NetworkAccessPolicy>               networkAccessPolicy          = default;
            Optional <string>                            diskAccessId                 = default;
            Optional <string>                            tier                         = default;
            Optional <bool>                              burstingEnabled              = default;
            Optional <PropertyUpdatesInProgress>         propertyUpdatesInProgress    = default;
            Optional <bool>                              supportsHibernation          = default;
            Optional <DiskSecurityProfile>               securityProfile              = default;
            Optional <float>                             completionPercent            = default;
            Optional <PublicNetworkAccess>               publicNetworkAccess          = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("managedBy"))
                {
                    managedBy = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("managedByExtended"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    List <string> array = new List <string>();
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        array.Add(item.GetString());
                    }
                    managedByExtended = array;
                    continue;
                }
                if (property.NameEquals("sku"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    sku = DiskSku.DeserializeDiskSku(property.Value);
                    continue;
                }
                if (property.NameEquals("zones"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    List <string> array = new List <string>();
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        array.Add(item.GetString());
                    }
                    zones = array;
                    continue;
                }
                if (property.NameEquals("extendedLocation"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    extendedLocation = ExtendedLocation.DeserializeExtendedLocation(property.Value);
                    continue;
                }
                if (property.NameEquals("tags"))
                {
                    Dictionary <string, string> dictionary = new Dictionary <string, string>();
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        dictionary.Add(property0.Name, property0.Value.GetString());
                    }
                    tags = dictionary;
                    continue;
                }
                if (property.NameEquals("location"))
                {
                    location = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("id"))
                {
                    id = new ResourceIdentifier(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("name"))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("type"))
                {
                    type = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("properties"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.NameEquals("timeCreated"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            timeCreated = property0.Value.GetDateTimeOffset("O");
                            continue;
                        }
                        if (property0.NameEquals("osType"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            osType = property0.Value.GetString().ToOperatingSystemTypes();
                            continue;
                        }
                        if (property0.NameEquals("hyperVGeneration"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            hyperVGeneration = new HyperVGeneration(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("purchasePlan"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            purchasePlan = DiskPurchasePlan.DeserializeDiskPurchasePlan(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("supportedCapabilities"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            supportedCapabilities = SupportedCapabilities.DeserializeSupportedCapabilities(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("creationData"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            creationData = CreationData.DeserializeCreationData(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("diskSizeGB"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskSizeGB = property0.Value.GetInt32();
                            continue;
                        }
                        if (property0.NameEquals("diskSizeBytes"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskSizeBytes = property0.Value.GetInt64();
                            continue;
                        }
                        if (property0.NameEquals("uniqueId"))
                        {
                            uniqueId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("encryptionSettingsCollection"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            encryptionSettingsCollection = EncryptionSettingsCollection.DeserializeEncryptionSettingsCollection(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("provisioningState"))
                        {
                            provisioningState = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("diskIOPSReadWrite"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskIOPSReadWrite = property0.Value.GetInt64();
                            continue;
                        }
                        if (property0.NameEquals("diskMBpsReadWrite"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskMBpsReadWrite = property0.Value.GetInt64();
                            continue;
                        }
                        if (property0.NameEquals("diskIOPSReadOnly"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskIOPSReadOnly = property0.Value.GetInt64();
                            continue;
                        }
                        if (property0.NameEquals("diskMBpsReadOnly"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskMBpsReadOnly = property0.Value.GetInt64();
                            continue;
                        }
                        if (property0.NameEquals("diskState"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            diskState = new DiskState(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("encryption"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            encryption = Encryption.DeserializeEncryption(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("maxShares"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            maxShares = property0.Value.GetInt32();
                            continue;
                        }
                        if (property0.NameEquals("shareInfo"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            List <ShareInfoElement> array = new List <ShareInfoElement>();
                            foreach (var item in property0.Value.EnumerateArray())
                            {
                                array.Add(ShareInfoElement.DeserializeShareInfoElement(item));
                            }
                            shareInfo = array;
                            continue;
                        }
                        if (property0.NameEquals("networkAccessPolicy"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            networkAccessPolicy = new NetworkAccessPolicy(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("diskAccessId"))
                        {
                            diskAccessId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("tier"))
                        {
                            tier = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("burstingEnabled"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            burstingEnabled = property0.Value.GetBoolean();
                            continue;
                        }
                        if (property0.NameEquals("propertyUpdatesInProgress"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            propertyUpdatesInProgress = PropertyUpdatesInProgress.DeserializePropertyUpdatesInProgress(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("supportsHibernation"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            supportsHibernation = property0.Value.GetBoolean();
                            continue;
                        }
                        if (property0.NameEquals("securityProfile"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            securityProfile = DiskSecurityProfile.DeserializeDiskSecurityProfile(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("completionPercent"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            completionPercent = property0.Value.GetSingle();
                            continue;
                        }
                        if (property0.NameEquals("publicNetworkAccess"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            publicNetworkAccess = new PublicNetworkAccess(property0.Value.GetString());
                            continue;
                        }
                    }
                    continue;
                }
            }
            return(new DiskData(id, name, type, tags, location, managedBy.Value, Optional.ToList(managedByExtended), sku.Value, Optional.ToList(zones), extendedLocation.Value, Optional.ToNullable(timeCreated), Optional.ToNullable(osType), Optional.ToNullable(hyperVGeneration), purchasePlan.Value, supportedCapabilities.Value, creationData.Value, Optional.ToNullable(diskSizeGB), Optional.ToNullable(diskSizeBytes), uniqueId.Value, encryptionSettingsCollection.Value, provisioningState.Value, Optional.ToNullable(diskIOPSReadWrite), Optional.ToNullable(diskMBpsReadWrite), Optional.ToNullable(diskIOPSReadOnly), Optional.ToNullable(diskMBpsReadOnly), Optional.ToNullable(diskState), encryption.Value, Optional.ToNullable(maxShares), Optional.ToList(shareInfo), Optional.ToNullable(networkAccessPolicy), diskAccessId.Value, tier.Value, Optional.ToNullable(burstingEnabled), propertyUpdatesInProgress.Value, Optional.ToNullable(supportsHibernation), securityProfile.Value, Optional.ToNullable(completionPercent), Optional.ToNullable(publicNetworkAccess)));
        }
        private void Run()
        {
            // Sku
            DiskSku vSku = null;

            // CreationData
            CreationData vCreationData = null;

            // EncryptionSettingsCollection
            EncryptionSettingsCollection vEncryptionSettingsCollection = null;

            // Encryption
            Encryption vEncryption = null;

            // ExtendedLocation
            ExtendedLocation vExtendedLocation = null;

            // SupportedCapabilities
            SupportedCapabilities vSupportedCapabilities = null;

            if (this.IsParameterBound(c => c.SkuName))
            {
                if (vSku == null)
                {
                    vSku = new DiskSku();
                }
                vSku.Name = this.SkuName;
            }

            if (this.IsParameterBound(c => c.CreateOption))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.CreateOption = this.CreateOption;
            }

            if (this.IsParameterBound(c => c.StorageAccountId))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.StorageAccountId = this.StorageAccountId;
            }

            if (this.IsParameterBound(c => c.ImageReference))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.ImageReference = this.ImageReference;
            }

            if (this.IsParameterBound(c => c.GalleryImageReference))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.GalleryImageReference = this.GalleryImageReference;
            }

            if (this.IsParameterBound(c => c.SourceUri))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.SourceUri = this.SourceUri;
            }

            if (this.IsParameterBound(c => c.SourceResourceId))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.SourceResourceId = this.SourceResourceId;
            }

            if (this.IsParameterBound(c => c.UploadSizeInBytes))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.UploadSizeBytes = this.UploadSizeInBytes;
            }

            if (this.IsParameterBound(c => c.LogicalSectorSize))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.LogicalSectorSize = this.LogicalSectorSize;
            }

            if (this.IsParameterBound(c => c.EncryptionSettingsEnabled))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }
                vEncryptionSettingsCollection.Enabled = (bool)this.EncryptionSettingsEnabled;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings.Count == 0)
                {
                    vEncryptionSettingsCollection.EncryptionSettings.Add(new EncryptionSettingsElement());
                }

                vEncryptionSettingsCollection.EncryptionSettings[0].DiskEncryptionKey = this.DiskEncryptionKey;
            }

            if (this.IsParameterBound(c => c.KeyEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings.Count == 0)
                {
                    vEncryptionSettingsCollection.EncryptionSettings.Add(new EncryptionSettingsElement());
                }

                vEncryptionSettingsCollection.EncryptionSettings[0].KeyEncryptionKey = this.KeyEncryptionKey;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionSetId))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.DiskEncryptionSetId = this.DiskEncryptionSetId;
            }

            if (this.IsParameterBound(c => c.EncryptionType))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.Type = this.EncryptionType;
            }

            if (this.IsParameterBound(c => c.EdgeZone))
            {
                vExtendedLocation = new ExtendedLocation {
                    Name = this.EdgeZone, Type = ExtendedLocationTypes.EdgeZone
                };
            }

            if (this.IsParameterBound(c => c.AcceleratedNetwork))
            {
                if (vSupportedCapabilities == null)
                {
                    vSupportedCapabilities = new SupportedCapabilities();
                }
                vSupportedCapabilities.AcceleratedNetwork = AcceleratedNetwork;
            }

            var vDisk = new PSDisk
            {
                Zones             = this.IsParameterBound(c => c.Zone) ? this.Zone : null,
                OsType            = this.IsParameterBound(c => c.OsType) ? this.OsType : (OperatingSystemTypes?)null,
                HyperVGeneration  = this.IsParameterBound(c => c.HyperVGeneration) ? this.HyperVGeneration : null,
                DiskSizeGB        = this.IsParameterBound(c => c.DiskSizeGB) ? this.DiskSizeGB : (int?)null,
                DiskIOPSReadWrite = this.IsParameterBound(c => c.DiskIOPSReadWrite) ? this.DiskIOPSReadWrite : (long?)null,
                DiskMBpsReadWrite = this.IsParameterBound(c => c.DiskMBpsReadWrite) ? this.DiskMBpsReadWrite : (long?)null,
                DiskIOPSReadOnly  = this.IsParameterBound(c => c.DiskIOPSReadOnly) ? this.DiskIOPSReadOnly : (long?)null,
                DiskMBpsReadOnly  = this.IsParameterBound(c => c.DiskMBpsReadOnly) ? this.DiskMBpsReadOnly : (long?)null,
                MaxShares         = this.IsParameterBound(c => c.MaxSharesCount) ? this.MaxSharesCount : (int?)null,
                Location          = this.IsParameterBound(c => c.Location) ? this.Location : null,
                ExtendedLocation  = vExtendedLocation,
                Tags         = this.IsParameterBound(c => c.Tag) ? this.Tag.Cast <DictionaryEntry>().ToDictionary(ht => (string)ht.Key, ht => (string)ht.Value) : null,
                Sku          = vSku,
                CreationData = vCreationData,
                EncryptionSettingsCollection = vEncryptionSettingsCollection,
                Encryption          = vEncryption,
                NetworkAccessPolicy = this.IsParameterBound(c => c.NetworkAccessPolicy) ? this.NetworkAccessPolicy : null,
                DiskAccessId        = this.IsParameterBound(c => c.DiskAccessId) ? this.DiskAccessId : null,
                Tier                  = this.IsParameterBound(c => c.Tier) ? this.Tier : null,
                BurstingEnabled       = this.IsParameterBound(c => c.BurstingEnabled) ? this.BurstingEnabled : null,
                PurchasePlan          = this.IsParameterBound(c => c.PurchasePlan) ? this.PurchasePlan : null,
                SupportsHibernation   = this.IsParameterBound(c => c.SupportsHibernation) ? SupportsHibernation : null,
                SupportedCapabilities = vSupportedCapabilities,
                PublicNetworkAccess   = this.IsParameterBound(c => c.PublicNetworkAccess) ? PublicNetworkAccess : null
            };

            WriteObject(vDisk);
        }
Beispiel #15
0
        private void Run()
        {
            // Sku
            SnapshotSku vSku = null;

            // CreationData
            CreationData vCreationData = null;

            // EncryptionSettingsCollection
            EncryptionSettingsCollection vEncryptionSettingsCollection = null;

            // Encryption
            Encryption vEncryption = null;

            // ExtendedLocation
            ExtendedLocation vExtendedLocation = null;

            // SupportedCapabilities
            SupportedCapabilities vSupportedCapabilities = null;

            if (this.IsParameterBound(c => c.SkuName))
            {
                if (vSku == null)
                {
                    vSku = new SnapshotSku();
                }
                vSku.Name = this.SkuName;
            }

            if (this.IsParameterBound(c => c.CreateOption))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.CreateOption = this.CreateOption;
            }

            if (this.IsParameterBound(c => c.StorageAccountId))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.StorageAccountId = this.StorageAccountId;
            }

            if (this.IsParameterBound(c => c.ImageReference))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.ImageReference = this.ImageReference;
            }

            if (this.IsParameterBound(c => c.SourceUri))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.SourceUri = this.SourceUri;
            }

            if (this.IsParameterBound(c => c.SourceResourceId))
            {
                if (vCreationData == null)
                {
                    vCreationData = new CreationData();
                }
                vCreationData.SourceResourceId = this.SourceResourceId;
            }

            if (this.IsParameterBound(c => c.EncryptionSettingsEnabled))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }
                vEncryptionSettingsCollection.Enabled = (bool)this.EncryptionSettingsEnabled;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings.Count == 0)
                {
                    vEncryptionSettingsCollection.EncryptionSettings.Add(new EncryptionSettingsElement());
                }

                vEncryptionSettingsCollection.EncryptionSettings[0].DiskEncryptionKey = this.DiskEncryptionKey;
            }

            if (this.IsParameterBound(c => c.KeyEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings.Count == 0)
                {
                    vEncryptionSettingsCollection.EncryptionSettings.Add(new EncryptionSettingsElement());
                }

                vEncryptionSettingsCollection.EncryptionSettings[0].KeyEncryptionKey = this.KeyEncryptionKey;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionSetId))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.DiskEncryptionSetId = this.DiskEncryptionSetId;
            }

            if (this.IsParameterBound(c => c.EncryptionType))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.Type = this.EncryptionType;
            }

            if (this.IsParameterBound(c => c.EdgeZone))
            {
                vExtendedLocation = new ExtendedLocation {
                    Name = this.EdgeZone, Type = ExtendedLocationTypes.EdgeZone
                };
            }

            if (this.IsParameterBound(c => c.AcceleratedNetwork))
            {
                if (vSupportedCapabilities == null)
                {
                    vSupportedCapabilities = new SupportedCapabilities();
                }
                vSupportedCapabilities.AcceleratedNetwork = AcceleratedNetwork;
            }

            var vSnapshot = new PSSnapshot
            {
                OsType           = this.IsParameterBound(c => c.OsType) ? this.OsType : (OperatingSystemTypes?)null,
                HyperVGeneration = this.IsParameterBound(c => c.HyperVGeneration) ? this.HyperVGeneration : null,
                DiskSizeGB       = this.IsParameterBound(c => c.DiskSizeGB) ? this.DiskSizeGB : (int?)null,
                Incremental      = this.Incremental.IsPresent,
                Location         = this.IsParameterBound(c => c.Location) ? this.Location : null,
                ExtendedLocation = vExtendedLocation,
                Tags             = this.IsParameterBound(c => c.Tag) ? this.Tag.Cast <DictionaryEntry>().ToDictionary(ht => (string)ht.Key, ht => (string)ht.Value) : null,
                Sku          = vSku,
                CreationData = vCreationData,
                EncryptionSettingsCollection = vEncryptionSettingsCollection,
                Encryption            = vEncryption,
                NetworkAccessPolicy   = this.IsParameterBound(c => c.NetworkAccessPolicy) ? this.NetworkAccessPolicy : null,
                DiskAccessId          = this.IsParameterBound(c => c.DiskAccessId) ? this.DiskAccessId : null,
                PurchasePlan          = this.IsParameterBound(c => c.PurchasePlan) ? this.PurchasePlan : null,
                SupportsHibernation   = this.IsParameterBound(c => c.SupportsHibernation) ? SupportsHibernation : null,
                SupportedCapabilities = vSupportedCapabilities,
                PublicNetworkAccess   = this.IsParameterBound(c => c.PublicNetworkAccess) ? PublicNetworkAccess : null
            };

            WriteObject(vSnapshot);
        }
        internal static DiskRestorePointData DeserializeDiskRestorePointData(JsonElement element)
        {
            ResourceIdentifier               id                     = default;
            string                           name                   = default;
            ResourceType                     type                   = default;
            SystemData                       systemData             = default;
            Optional <DateTimeOffset>        timeCreated            = default;
            Optional <string>                sourceResourceId       = default;
            Optional <OperatingSystemTypes>  osType                 = default;
            Optional <HyperVGeneration>      hyperVGeneration       = default;
            Optional <DiskPurchasePlan>      purchasePlan           = default;
            Optional <SupportedCapabilities> supportedCapabilities  = default;
            Optional <string>                familyId               = default;
            Optional <string>                sourceUniqueId         = default;
            Optional <Encryption>            encryption             = default;
            Optional <bool>                  supportsHibernation    = default;
            Optional <NetworkAccessPolicy>   networkAccessPolicy    = default;
            Optional <PublicNetworkAccess>   publicNetworkAccess    = default;
            Optional <string>                diskAccessId           = default;
            Optional <float>                 completionPercent      = default;
            Optional <string>                replicationState       = default;
            Optional <string>                sourceResourceLocation = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("id"))
                {
                    id = new ResourceIdentifier(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("name"))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("type"))
                {
                    type = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("systemData"))
                {
                    systemData = JsonSerializer.Deserialize <SystemData>(property.Value.ToString());
                    continue;
                }
                if (property.NameEquals("properties"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.NameEquals("timeCreated"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            timeCreated = property0.Value.GetDateTimeOffset("O");
                            continue;
                        }
                        if (property0.NameEquals("sourceResourceId"))
                        {
                            sourceResourceId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("osType"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            osType = property0.Value.GetString().ToOperatingSystemTypes();
                            continue;
                        }
                        if (property0.NameEquals("hyperVGeneration"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            hyperVGeneration = new HyperVGeneration(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("purchasePlan"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            purchasePlan = DiskPurchasePlan.DeserializeDiskPurchasePlan(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("supportedCapabilities"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            supportedCapabilities = SupportedCapabilities.DeserializeSupportedCapabilities(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("familyId"))
                        {
                            familyId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("sourceUniqueId"))
                        {
                            sourceUniqueId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("encryption"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            encryption = Encryption.DeserializeEncryption(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("supportsHibernation"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            supportsHibernation = property0.Value.GetBoolean();
                            continue;
                        }
                        if (property0.NameEquals("networkAccessPolicy"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            networkAccessPolicy = new NetworkAccessPolicy(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("publicNetworkAccess"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            publicNetworkAccess = new PublicNetworkAccess(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("diskAccessId"))
                        {
                            diskAccessId = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("completionPercent"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            completionPercent = property0.Value.GetSingle();
                            continue;
                        }
                        if (property0.NameEquals("replicationState"))
                        {
                            replicationState = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("sourceResourceLocation"))
                        {
                            sourceResourceLocation = property0.Value.GetString();
                            continue;
                        }
                    }
                    continue;
                }
            }
            return(new DiskRestorePointData(id, name, type, systemData, Optional.ToNullable(timeCreated), sourceResourceId.Value, Optional.ToNullable(osType), Optional.ToNullable(hyperVGeneration), purchasePlan.Value, supportedCapabilities.Value, familyId.Value, sourceUniqueId.Value, encryption.Value, Optional.ToNullable(supportsHibernation), Optional.ToNullable(networkAccessPolicy), Optional.ToNullable(publicNetworkAccess), diskAccessId.Value, Optional.ToNullable(completionPercent), replicationState.Value, sourceResourceLocation.Value));
        }
        internal LanguageClient(LanguageClientOptions options) : base(options)
        {
            _capabilities       = options.SupportedCapabilities;
            _clientCapabilities = options.ClientCapabilities;
            var services = options.Services;

            services.AddLogging(builder => options.LoggingBuilderAction(builder));
            options.RequestProcessIdentifier ??= (options.SupportsContentModified
                ? new RequestProcessIdentifier(RequestProcessType.Parallel)
                : new RequestProcessIdentifier(RequestProcessType.Serial));
            // services.AddSingleton<IOptionsMonitor<LoggerFilterOptions>, LanguageClientLoggerFilterOptions>();

            _clientInfo = options.ClientInfo;
            _receiver   = options.Receiver;
            var serializer            = options.Serializer;
            var supportedCapabilities = new SupportedCapabilities();

            _textDocumentIdentifiers = new TextDocumentIdentifiers();
            var collection = new SharedHandlerCollection(supportedCapabilities, _textDocumentIdentifiers);

            services.AddSingleton <IHandlersManager>(collection);
            _collection = collection;
            // _initializeDelegates = initializeDelegates;
            // _initializedDelegates = initializedDelegates;
            _startedDelegates      = options.StartedDelegates;
            _rootUri               = options.RootUri;
            _trace                 = options.Trace;
            _initializationOptions = options.InitializationOptions;

            services.AddSingleton <IOutputHandler>(_ =>
                                                   new OutputHandler(options.Output, options.Serializer, options.Receiver.ShouldFilterOutput, _.GetService <ILogger <OutputHandler> >()));
            services.AddSingleton(_collection);
            services.AddSingleton(_textDocumentIdentifiers);
            services.AddSingleton(serializer);
            services.AddSingleton <OmniSharp.Extensions.JsonRpc.ISerializer>(serializer);
            services.AddSingleton(options.RequestProcessIdentifier);
            services.AddSingleton <OmniSharp.Extensions.JsonRpc.IReceiver>(options.Receiver);
            services.AddSingleton(options.Receiver);
            services.AddSingleton <ILanguageClient>(this);
            services.AddSingleton <LspRequestRouter>();
            services.AddSingleton <IRequestRouter <ILspHandlerDescriptor> >(_ => _.GetRequiredService <LspRequestRouter>());
            services.AddSingleton <IRequestRouter <IHandlerDescriptor> >(_ => _.GetRequiredService <LspRequestRouter>());
            services.AddSingleton <IResponseRouter, ResponseRouter>();

            services.AddSingleton <IProgressManager, ProgressManager>();
            services.AddSingleton(_ => _.GetRequiredService <IProgressManager>() as IJsonRpcHandler);
            services.AddSingleton <IClientWorkDoneManager, ClientWorkDoneManager>();
            services.AddSingleton(_ => _.GetRequiredService <IClientWorkDoneManager>() as IJsonRpcHandler);

            EnsureAllHandlersAreRegistered();

            services.AddSingleton <RegistrationManager>();
            services.AddSingleton <IRegistrationManager>(_ => _.GetRequiredService <RegistrationManager>());
            if (options.DynamicRegistration)
            {
                services.AddSingleton(_ => _.GetRequiredService <RegistrationManager>() as IJsonRpcHandler);
            }

            var workspaceFoldersManager = new WorkspaceFoldersManager(this);

            services.AddSingleton(workspaceFoldersManager);
            services.AddSingleton <IWorkspaceFoldersManager>(workspaceFoldersManager);
            if (options.WorkspaceFolders)
            {
                services.AddSingleton <IJsonRpcHandler>(workspaceFoldersManager);
            }

            var serviceProvider = services.BuildServiceProvider();

            _disposable.Add(serviceProvider);
            _serviceProvider = serviceProvider;
            collection.SetServiceProvider(_serviceProvider);

            _responseRouter          = _serviceProvider.GetRequiredService <IResponseRouter>();
            _progressManager         = _serviceProvider.GetRequiredService <IProgressManager>();
            _workDoneManager         = _serviceProvider.GetRequiredService <IClientWorkDoneManager>();
            _registrationManager     = _serviceProvider.GetRequiredService <RegistrationManager>();
            _workspaceFoldersManager = _serviceProvider.GetRequiredService <IWorkspaceFoldersManager>();

            _connection = new Connection(
                options.Input,
                _serviceProvider.GetRequiredService <IOutputHandler>(),
                options.Receiver,
                options.RequestProcessIdentifier,
                _serviceProvider.GetRequiredService <IRequestRouter <IHandlerDescriptor> >(),
                _responseRouter,
                _serviceProvider.GetRequiredService <ILoggerFactory>(),
                options.OnUnhandledException ?? (e => { }),
                options.CreateResponseException,
                options.MaximumRequestTimeout,
                options.SupportsContentModified,
                options.Concurrency
                );

            // We need to at least create Window here in case any handler does loggin in their constructor
            TextDocument = new TextDocumentLanguageClient(this, _serviceProvider);
            Client       = new ClientLanguageClient(this, _serviceProvider);
            General      = new GeneralLanguageClient(this, _serviceProvider);
            Window       = new WindowLanguageClient(this, _serviceProvider);
            Workspace    = new WorkspaceLanguageClient(this, _serviceProvider);

            workspaceFoldersManager.Add(options.Folders);

            var serviceHandlers    = _serviceProvider.GetServices <IJsonRpcHandler>().ToArray();
            var serviceIdentifiers = _serviceProvider.GetServices <ITextDocumentIdentifier>().ToArray();

            _disposable.Add(_textDocumentIdentifiers.Add(serviceIdentifiers));
            _disposable.Add(_collection.Add(serviceHandlers));
            options.AddLinks(_collection);
        }
        private void Run()
        {
            // EncryptionSettingsCollection
            EncryptionSettingsCollection vEncryptionSettingsCollection = null;

            // Encryption
            Encryption vEncryption = null;

            // Sku
            SnapshotSku vSku = null;

            SupportedCapabilities vSupportedCapabilities = null;

            if (this.IsParameterBound(c => c.EncryptionSettingsEnabled))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }
                vEncryptionSettingsCollection.Enabled = (bool)this.EncryptionSettingsEnabled;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings.Count == 0)
                {
                    vEncryptionSettingsCollection.EncryptionSettings.Add(new EncryptionSettingsElement());
                }
                vEncryptionSettingsCollection.EncryptionSettings[0].DiskEncryptionKey = this.DiskEncryptionKey;
            }

            if (this.IsParameterBound(c => c.KeyEncryptionKey))
            {
                if (vEncryptionSettingsCollection == null)
                {
                    vEncryptionSettingsCollection = new EncryptionSettingsCollection();
                }
                if (vEncryptionSettingsCollection.EncryptionSettings == null)
                {
                    vEncryptionSettingsCollection.EncryptionSettings = new List <EncryptionSettingsElement>();
                }

                if (vEncryptionSettingsCollection.EncryptionSettings.Count == 0)
                {
                    vEncryptionSettingsCollection.EncryptionSettings.Add(new EncryptionSettingsElement());
                }
                vEncryptionSettingsCollection.EncryptionSettings[0].KeyEncryptionKey = this.KeyEncryptionKey;
            }

            if (this.IsParameterBound(c => c.DiskEncryptionSetId))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.DiskEncryptionSetId = this.DiskEncryptionSetId;
            }

            if (this.IsParameterBound(c => c.EncryptionType))
            {
                if (vEncryption == null)
                {
                    vEncryption = new Encryption();
                }
                vEncryption.Type = this.EncryptionType;
            }

            if (this.IsParameterBound(c => c.SkuName))
            {
                if (vSku == null)
                {
                    vSku = new SnapshotSku();
                }
                vSku.Name = this.SkuName;
            }

            if (this.IsParameterBound(c => c.Architecture))
            {
                if (vSupportedCapabilities == null)
                {
                    vSupportedCapabilities = new SupportedCapabilities();
                }
                vSupportedCapabilities.Architecture = this.Architecture;
            }

            var vSnapshotUpdate = new PSSnapshotUpdate
            {
                OsType     = this.IsParameterBound(c => c.OsType) ? this.OsType : (OperatingSystemTypes?)null,
                DiskSizeGB = this.IsParameterBound(c => c.DiskSizeGB) ? this.DiskSizeGB : (int?)null,
                Tags       = this.IsParameterBound(c => c.Tag) ? this.Tag.Cast <DictionaryEntry>().ToDictionary(ht => (string)ht.Key, ht => (string)ht.Value) : null,
                EncryptionSettingsCollection = vEncryptionSettingsCollection,
                Encryption            = vEncryption,
                Sku                   = vSku,
                SupportsHibernation   = this.IsParameterBound(c => c.SupportsHibernation) ? SupportsHibernation : null,
                PublicNetworkAccess   = this.IsParameterBound(c => c.PublicNetworkAccess) ? PublicNetworkAccess : null,
                DataAccessAuthMode    = this.IsParameterBound(c => c.DataAccessAuthMode) ? DataAccessAuthMode : null,
                SupportedCapabilities = vSupportedCapabilities
            };

            WriteObject(vSnapshotUpdate);
        }