예제 #1
0
        /// <summary>
        /// Delete the SignalR service.
        /// </summary>
        /// <param name="resourceGroup"></param>
        /// <param name="signalR"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task DeleteAsync(
            IResourceGroup resourceGroup,
            SignalRResource signalR,
            CancellationToken cancellationToken = default
            )
        {
            if (resourceGroup is null)
            {
                throw new ArgumentNullException(nameof(resourceGroup));
            }
            if (signalR is null)
            {
                throw new ArgumentNullException(nameof(signalR));
            }

            try {
                Log.Debug($"Deleting SignalR Service: {signalR.Name} ...");

                await _signalRManagementClient
                .SignalR
                .DeleteAsync(
                    resourceGroup.Name,
                    signalR.Name,
                    cancellationToken
                    );

                Log.Debug($"Deleted SignalR Service: {signalR.Name}");
            }
            catch (Exception ex) {
                Log.Error(ex, $"Failed to delete SignalR Service: {signalR.Name}");
                throw;
            }
        }
예제 #2
0
        /// <summary>
        /// Get primary connection string for the SignalR service.
        /// </summary>
        /// <param name="resourceGroup"></param>
        /// <param name="signalR"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <string> GetConnectionStringAsync(
            IResourceGroup resourceGroup,
            SignalRResource signalR,
            CancellationToken cancellationToken = default
            )
        {
            if (resourceGroup is null)
            {
                throw new ArgumentNullException(nameof(resourceGroup));
            }
            if (signalR is null)
            {
                throw new ArgumentNullException(nameof(signalR));
            }

            try {
                var keys = await _signalRManagementClient
                           .SignalR
                           .ListKeysAsync(
                    resourceGroup.Name,
                    signalR.Name,
                    cancellationToken
                    );

                return(keys.PrimaryConnectionString);
            }
            catch (Exception ex) {
                Log.Error(ex, $"Failed to get connection string for SignalR Service: {signalR.Name}");
                throw;
            }
        }
        public override void ExecuteCmdlet()
        {
            base.ExecuteCmdlet();

            RunCmdlet(() =>
            {
                switch (ParameterSetName)
                {
                case ResourceGroupParameterSet:
                    ResolveResourceGroupName();
                    break;

                case ResourceIdParameterSet:
                    this.LoadFromResourceId();
                    break;

                case InputObjectParameterSet:
                    this.LoadFromInputObject();
                    break;

                default:
                    throw new ArgumentException(Resources.ParameterSetError);
                }

                if (ShouldProcess($"SignalR service {ResourceGroupName}/{Name}", "update"))
                {
                    PromptParameter(nameof(ResourceGroupName), ResourceGroupName);
                    PromptParameter(nameof(Name), Name);
                    PromptParameter(nameof(Sku), Sku, true, DefaultSku);
                    PromptParameter(nameof(UnitCount), UnitCount, true, DefaultUnitCount);
                    PromptParameter(nameof(Tag), Tag == null ? null : JsonConvert.SerializeObject(Tag));
                    PromptParameter(nameof(ServiceMode), ServiceMode);

                    IList <string> origins = ParseAndCheckAllowedOrigins(AllowedOrigin);
                    PromptParameter(nameof(AllowedOrigin), origins == null ? null : JsonConvert.SerializeObject(origins));


                    Sku       = Sku ?? DefaultSku;
                    UnitCount = UnitCount ?? DefaultUnitCount;

                    IList <SignalRFeature> features = ServiceMode == null ? null : new List <SignalRFeature> {
                        new SignalRFeature(flag: FeatureFlags.ServiceMode, value: ServiceMode)
                    };
                    SignalRCorsSettings cors = AllowedOrigin == null ? null : new SignalRCorsSettings(allowedOrigins: origins);

                    var parameters = new SignalRResource(
                        tags: Tag,
                        sku: new ResourceSku(name: Sku, capacity: UnitCount),
                        features: features,
                        cors: cors);

                    Client.SignalR.Update(ResourceGroupName, Name, parameters);

                    var signalr = (Client.SignalR.Get(ResourceGroupName, Name));
                    WriteObject(new PSSignalRResource(signalr));
                }
            });
        }
 public PSSignalRResource(SignalRResource signalRResource)
     : base(signalRResource)
 {
     ExternalIp        = signalRResource.ExternalIP;
     HostName          = signalRResource.HostName;
     HostNamePrefix    = signalRResource.HostNamePrefix;
     ProvisioningState = signalRResource.ProvisioningState;
     PublicPort        = signalRResource.PublicPort;
     ServerPort        = signalRResource.ServerPort;
     Sku = new PSResourceSku(signalRResource.Sku);
 }
예제 #5
0
        public override void ExecuteCmdlet()
        {
            base.ExecuteCmdlet();

            RunCmdlet(() =>
            {
                ResolveResourceGroupName(required: false);
                ResourceGroupName = ResourceGroupName ?? Name;

                if (ShouldProcess($"SignalR service {ResourceGroupName}/{Name}", "new"))
                {
                    PromptParameter(nameof(ResourceGroupName), ResourceGroupName);
                    PromptParameter(nameof(Name), Name);

                    if (Location == null)
                    {
                        Location = GetLocationFromResourceGroup();
                        PromptParameter(nameof(Location), null, true, Location, "(from resource group location)");
                    }
                    else
                    {
                        PromptParameter(nameof(Location), Location);
                    }

                    PromptParameter(nameof(Sku), Sku, true, DefaultSku);
                    PromptParameter(nameof(UnitCount), UnitCount);
                    PromptParameter(nameof(Tag), Tag == null ? null : JsonConvert.SerializeObject(Tag));
                    PromptParameter(nameof(ServiceMode), ServiceMode);

                    IList <string> origins = ParseAndCheckAllowedOrigins(AllowedOrigin);
                    PromptParameter(nameof(AllowedOrigin), origins == null ? null : JsonConvert.SerializeObject(origins));

                    Sku = Sku ?? DefaultSku;

                    IList <SignalRFeature> features = ServiceMode == null ? null : new List <SignalRFeature> {
                        new SignalRFeature(flag: FeatureFlags.ServiceMode, value: ServiceMode)
                    };
                    SignalRCorsSettings cors = AllowedOrigin == null ? null : new SignalRCorsSettings(allowedOrigins: origins);

                    var parameters = new SignalRResource(
                        location: Location,
                        tags: Tag,
                        sku: new ResourceSku(name: Sku, capacity: UnitCount),
                        features: features,
                        cors: cors);

                    Client.SignalR.CreateOrUpdate(parameters, ResourceGroupName, Name);

                    var signalr = Client.SignalR.Get(ResourceGroupName, Name);
                    WriteObject(new PSSignalRResource(signalr));
                }
            });
        }
예제 #6
0
 public PSSignalRResource(SignalRResource signalRResource)
     : base(signalRResource)
 {
     ExternalIp        = signalRResource.ExternalIP;
     HostName          = signalRResource.HostName;
     HostNamePrefix    = signalRResource.HostNamePrefix;
     ProvisioningState = signalRResource.ProvisioningState;
     PublicPort        = signalRResource.PublicPort;
     ServerPort        = signalRResource.ServerPort;
     Sku      = new PSResourceSku(signalRResource.Sku);
     Features = new List <PSSignalRFeature>();
     foreach (var feature in signalRResource.Features)
     {
         Features.Add(new PSSignalRFeature(feature));
     }
     Cors    = new PSSignalRCorsSettings(signalRResource.Cors);
     Version = signalRResource.Version;
 }
예제 #7
0
 public PSSignalRResource(SignalRResource signalR)
     : base(signalR)
 {
     ExternalIp        = signalR.ExternalIP;
     HostName          = signalR.HostName;
     ProvisioningState = signalR.ProvisioningState;
     PublicPort        = signalR.PublicPort;
     ServerPort        = signalR.ServerPort;
     Sku      = new PSResourceSku(signalR.Sku);
     Features = new List <PSSignalRFeature>();
     foreach (var feature in signalR.Features)
     {
         Features.Add(new PSSignalRFeature(feature));
     }
     Cors        = new PSSignalRCorsSettings(signalR.Cors);
     Version     = signalR.Version;
     NetworkAcls = new PSSignalRNetworkAcls(signalR.NetworkACLs);
     Upstream    = new PSServerlessUpstreamSettings(signalR.Upstream);
 }
예제 #8
0
        private void SignalRScenarioVerification(SignalRManagementClient signalrClient, ResourceGroup resourceGroup, SignalRResource signalr, bool isStandard, int capacity = 1)
        {
            // Validate the newly created SignalR instance
            SignalRTestUtilities.ValidateResourceDefaultTags(signalr);
            Assert.NotNull(signalr.Sku);
            if (isStandard)
            {
                Assert.Equal(SignalRSkuTier.Standard, signalr.Sku.Tier);
                Assert.Equal("Standard_S1", signalr.Sku.Name);
                Assert.Equal("S1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            else
            {
                Assert.Equal(SignalRSkuTier.Free, signalr.Sku.Tier);
                Assert.Equal("Free_F1", signalr.Sku.Name);
                Assert.Equal("F1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            Assert.Equal(ProvisioningState.Succeeded, signalr.ProvisioningState);
            Assert.NotEmpty(signalr.HostName);
            Assert.NotEmpty(signalr.ExternalIP);
            Assert.NotNull(signalr.PublicPort);
            Assert.NotNull(signalr.ServerPort);
            Assert.NotEmpty(signalr.Version);
            Assert.Equal(3, signalr.Features.Count);            // ServiceMode will be set as Default
            Assert.Equal("Default", signalr.Features.First().Value);
            Assert.Equal(1, signalr.Cors.AllowedOrigins.Count); // all origins(*) are allowed by default.
            Assert.Equal("*", signalr.Cors.AllowedOrigins.First());
            Assert.Equal("SignalR", signalr.Kind);
            Assert.Equal(1, signalr.Upstream.Templates.Count);

            // List the SignalR instances by resource group
            var signalrByResourceGroup = signalrClient.SignalR.ListByResourceGroup(resourceGroup.Name);

            Assert.Single(signalrByResourceGroup);
            signalr = signalrByResourceGroup.FirstOrDefault(r => StringComparer.OrdinalIgnoreCase.Equals(r.Name, signalr.Name));
            SignalRTestUtilities.ValidateResourceDefaultTags(signalr);

            // Get the SignalR instance by name
            signalr = signalrClient.SignalR.Get(resourceGroup.Name, signalr.Name);
            SignalRTestUtilities.ValidateResourceDefaultTags(signalr);

            // List keys
            var keys = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);

            Assert.NotNull(keys);
            Assert.NotEmpty(keys.PrimaryKey);
            Assert.NotEmpty(keys.PrimaryConnectionString);
            Assert.NotEmpty(keys.SecondaryKey);
            Assert.NotEmpty(keys.SecondaryConnectionString);

            // Update the SignalR instance
            capacity = isStandard ? 1 : 5;
            signalr  = signalrClient.SignalR.Update(resourceGroup.Name, signalr.Name, new SignalRResource
            {
                Tags = SignalRTestUtilities.DefaultNewTags,
                Sku  = new ResourceSku
                {
                    Name     = isStandard ? "Free_F1" : "Standard_S1",
                    Tier     = isStandard ? "Free" : "Standard",
                    Capacity = capacity,
                },
                Features = new List <SignalRFeature> {
                    new SignalRFeature {
                        Value = "Serverless"
                    }
                },
                Cors = new SignalRCorsSettings
                {
                    AllowedOrigins = new List <string>
                    {
                        "http://example.com:12345",
                        "https://contoso.com",
                    }
                },
            });

            // Validate the updated SignalR instance
            SignalRTestUtilities.ValidateResourceDefaultNewTags(signalr);
            Assert.NotNull(signalr.Sku);
            if (isStandard)
            {
                Assert.Equal(SignalRSkuTier.Free, signalr.Sku.Tier);
                Assert.Equal("Free_F1", signalr.Sku.Name);
                Assert.Equal("F1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            else
            {
                Assert.Equal(SignalRSkuTier.Standard, signalr.Sku.Tier);
                Assert.Equal("Standard_S1", signalr.Sku.Name);
                Assert.Equal("S1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            Assert.Equal(ProvisioningState.Succeeded, signalr.ProvisioningState);
            Assert.NotEmpty(signalr.HostName);
            Assert.NotEmpty(signalr.ExternalIP);
            Assert.NotNull(signalr.PublicPort);
            Assert.NotNull(signalr.ServerPort);
            Assert.NotEmpty(signalr.Version);
            Assert.Equal(3, signalr.Features.Count);
            Assert.Equal("Serverless", signalr.Features.First().Value);
            Assert.Equal(2, signalr.Cors.AllowedOrigins.Count);
            Assert.Equal("http://example.com:12345", signalr.Cors.AllowedOrigins.First());
            Assert.Equal("https://contoso.com", signalr.Cors.AllowedOrigins.Last());

            // List keys of the updated SignalR instance
            keys = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);
            Assert.NotNull(keys);
            Assert.NotEmpty(keys.PrimaryKey);
            Assert.NotEmpty(keys.PrimaryConnectionString);
            Assert.NotEmpty(keys.SecondaryKey);
            Assert.NotEmpty(keys.SecondaryConnectionString);

            // Regenerate primary key
            var newKeys1 = signalrClient.SignalR.RegenerateKey(resourceGroup.Name, signalr.Name, new RegenerateKeyParameters
            {
                KeyType = "Primary",
            });

            // Due to a bug in SignalR RP, the result of RegenerateKey is null. UnComment following lines after we fixed it RP side
            //Assert.NotNull(newKeys1);
            //Assert.NotEqual(keys.PrimaryKey, newKeys1.PrimaryKey);
            //Assert.NotEqual(keys.PrimaryConnectionString, newKeys1.PrimaryConnectionString);
            //Assert.Null(newKeys1.SecondaryKey);
            //Assert.Null(newKeys1.SecondaryConnectionString);

            // Ensure only the primary key is regenerated
            newKeys1 = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);
            Assert.NotNull(newKeys1);
            Assert.NotEqual(keys.PrimaryKey, newKeys1.PrimaryKey);
            Assert.NotEqual(keys.PrimaryConnectionString, newKeys1.PrimaryConnectionString);
            Assert.Equal(keys.SecondaryKey, newKeys1.SecondaryKey);
            Assert.Equal(keys.SecondaryConnectionString, newKeys1.SecondaryConnectionString);

            // Regenerate secondary key
            var newKeys2 = signalrClient.SignalR.RegenerateKey(resourceGroup.Name, signalr.Name, new RegenerateKeyParameters
            {
                KeyType = "Secondary",
            });

            // Due to a bug in SignalR RP, the result of RegenerateKey is null. UnComment following lines after we fixed it RP side
            //Assert.NotNull(newKeys2);
            //Assert.Null(newKeys2.PrimaryKey);
            //Assert.Null(newKeys2.PrimaryConnectionString);
            //Assert.NotEqual(keys.SecondaryKey, newKeys2.SecondaryKey);
            //Assert.NotEqual(keys.SecondaryConnectionString, newKeys2.SecondaryConnectionString);

            // ensure only the secondary key is regenerated
            newKeys2 = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);
            Assert.NotNull(newKeys2);
            Assert.Equal(newKeys1.PrimaryKey, newKeys2.PrimaryKey);
            Assert.Equal(newKeys1.PrimaryConnectionString, newKeys2.PrimaryConnectionString);
            Assert.NotEqual(newKeys1.SecondaryKey, newKeys2.SecondaryKey);
            Assert.NotEqual(newKeys1.SecondaryConnectionString, newKeys2.SecondaryConnectionString);

            // Delete the SignalR instance
            signalrClient.SignalR.Delete(resourceGroup.Name, signalr.Name);

            // Delete again, should be no-op
            signalrClient.SignalR.Delete(resourceGroup.Name, signalr.Name);
        }
예제 #9
0
 private void AddOrUpdateServiceMode(SignalRResource signalR, string ServiceMode)
 {
     signalR.Features = signalR.Features?.SkipWhile(f => f.Flag.Equals(ServiceMode)).ToList() ??
                        new List <SignalRFeature>();
     signalR.Features.Add(new SignalRFeature(FeatureFlags.ServiceMode, ServiceMode));
 }
예제 #10
0
 /// <summary>
 /// Operation to update an exiting SignalR service.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group that contains the resource. You can obtain
 /// this value from the Azure Resource Manager API or the portal.
 /// </param>
 /// <param name='resourceName'>
 /// The name of the SignalR resource.
 /// </param>
 /// <param name='parameters'>
 /// Parameters for the update operation
 /// </param>
 /// <param name='cancellationToken'>
 /// The cancellation token.
 /// </param>
 public static async Task <SignalRResource> BeginUpdateAsync(this ISignalROperations operations, string resourceGroupName, string resourceName, SignalRResource parameters = default(SignalRResource), CancellationToken cancellationToken = default(CancellationToken))
 {
     using (var _result = await operations.BeginUpdateWithHttpMessagesAsync(resourceGroupName, resourceName, parameters, null, cancellationToken).ConfigureAwait(false))
     {
         return(_result.Body);
     }
 }
예제 #11
0
 /// <summary>
 /// Operation to update an exiting SignalR service.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group that contains the resource. You can obtain
 /// this value from the Azure Resource Manager API or the portal.
 /// </param>
 /// <param name='resourceName'>
 /// The name of the SignalR resource.
 /// </param>
 /// <param name='parameters'>
 /// Parameters for the update operation
 /// </param>
 public static SignalRResource BeginUpdate(this ISignalROperations operations, string resourceGroupName, string resourceName, SignalRResource parameters = default(SignalRResource))
 {
     return(operations.BeginUpdateAsync(resourceGroupName, resourceName, parameters).GetAwaiter().GetResult());
 }
예제 #12
0
        /// <summary>
        /// Create a Standard tier Serverless instance of SignalR service in the given resource group.
        /// </summary>
        /// <param name="resourceGroup"></param>
        /// <param name="signalRName"></param>
        /// <param name="tags"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <SignalRResource> CreateAsync(
            IResourceGroup resourceGroup,
            string signalRName,
            IDictionary <string, string> tags   = null,
            CancellationToken cancellationToken = default
            )
        {
            if (resourceGroup is null)
            {
                throw new ArgumentNullException(nameof(resourceGroup));
            }
            if (string.IsNullOrEmpty(signalRName))
            {
                throw new ArgumentNullException(nameof(signalRName));
            }

            try {
                tags ??= new Dictionary <string, string>();

                Log.Information($"Creating SignalR Service: {signalRName} ...");

                var serviceModeFeature = new SignalRFeature {
                    Flag  = ServiceMode.Serverless.Flag,
                    Value = ServiceMode.Serverless.Value
                };

                var signalRCreateParameters = new SignalRResource()
                {
                    Location = resourceGroup.RegionName,
                    Tags     = tags,

                    Sku = new ResourceSku {
                        Name     = "Standard_S1",
                        Tier     = "Standard",
                        Capacity = 1,
                    },
                    HostNamePrefix = signalRName,
                    Features       = new List <SignalRFeature> {
                        serviceModeFeature
                    }
                };

                signalRCreateParameters.Validate();

                var signalR = await _signalRManagementClient
                              .SignalR
                              .CreateOrUpdateAsync(
                    resourceGroup.Name,
                    signalRName,
                    signalRCreateParameters,
                    cancellationToken
                    );

                Log.Information($"Created SignalR Service: {signalRName}");

                return(signalR);
            }
            catch (Exception ex) {
                Log.Error(ex, $"Failed ot create SignalR Service: {signalRName}");
                throw;
            }
        }
 /// <summary>
 /// Create or update a resource.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='parameters'>
 /// Parameters for the create or update operation
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group that contains the resource. You can obtain
 /// this value from the Azure Resource Manager API or the portal.
 /// </param>
 /// <param name='resourceName'>
 /// The name of the resource.
 /// </param>
 public static SignalRResource BeginCreateOrUpdate(this ISignalROperations operations, SignalRResource parameters, string resourceGroupName, string resourceName)
 {
     return(operations.BeginCreateOrUpdateAsync(parameters, resourceGroupName, resourceName).GetAwaiter().GetResult());
 }
예제 #14
0
        private void SignalRScenarioVerification(SignalRManagementClient signalrClient, ResourceGroup resourceGroup, SignalRResource signalr, bool isStandard, int capacity = 1)
        {
            // Validate the newly created SignalR instance
            SignalRTestUtilities.ValidateResourceDefaultTags(signalr);
            Assert.NotNull(signalr.Sku);
            if (isStandard)
            {
                Assert.Equal(SignalRSkuTier.Standard, signalr.Sku.Tier);
                Assert.Equal("Standard_S1", signalr.Sku.Name);
                Assert.Equal("S1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            else
            {
                Assert.Equal(SignalRSkuTier.Free, signalr.Sku.Tier);
                Assert.Equal("Free_F1", signalr.Sku.Name);
                Assert.Equal("F1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            // Currently, HostNamePrefix is used as a placeholder. It's not regarded by the RP
            Assert.Null(signalr.HostNamePrefix);
            Assert.Equal(ProvisioningState.Succeeded, signalr.ProvisioningState);
            Assert.NotEmpty(signalr.HostName);
            Assert.NotEmpty(signalr.ExternalIP);
            Assert.NotNull(signalr.PublicPort);
            Assert.NotNull(signalr.ServerPort);
            Assert.NotEmpty(signalr.Version);

            // List the SignalR instances by resource group
            var signalrByResourceGroup = signalrClient.SignalR.ListByResourceGroup(resourceGroup.Name);

            Assert.Single(signalrByResourceGroup);
            signalr = signalrByResourceGroup.FirstOrDefault(r => StringComparer.OrdinalIgnoreCase.Equals(r.Name, signalr.Name));
            SignalRTestUtilities.ValidateResourceDefaultTags(signalr);

            // Get the SignalR instance by name
            signalr = signalrClient.SignalR.Get(resourceGroup.Name, signalr.Name);
            SignalRTestUtilities.ValidateResourceDefaultTags(signalr);

            // List keys
            var keys = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);

            Assert.NotNull(keys);
            Assert.NotEmpty(keys.PrimaryKey);
            Assert.NotEmpty(keys.PrimaryConnectionString);
            Assert.NotEmpty(keys.SecondaryKey);
            Assert.NotEmpty(keys.SecondaryConnectionString);

            // Update the SignalR instance
            capacity = isStandard ? 1 : 5;
            signalr  = signalrClient.SignalR.Update(resourceGroup.Name, signalr.Name, new SignalRUpdateParameters
            {
                Tags = SignalRTestUtilities.DefaultNewTags,
                Sku  = new ResourceSku
                {
                    Name     = isStandard ? "Free_F1" : "Standard_S1",
                    Tier     = isStandard ? "Free" : "Standard",
                    Size     = isStandard ? "F1" : "S1",
                    Capacity = capacity,
                },
                Properties = new SignalRCreateOrUpdateProperties
                {
                    HostNamePrefix = TestUtilities.GenerateName("signalr-service-test"),
                },
            });

            // Validate the updated SignalR instance
            SignalRTestUtilities.ValidateResourceDefaultNewTags(signalr);
            Assert.NotNull(signalr.Sku);
            if (isStandard)
            {
                Assert.Equal(SignalRSkuTier.Free, signalr.Sku.Tier);
                Assert.Equal("Free_F1", signalr.Sku.Name);
                Assert.Equal("F1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            else
            {
                Assert.Equal(SignalRSkuTier.Standard, signalr.Sku.Tier);
                Assert.Equal("Standard_S1", signalr.Sku.Name);
                Assert.Equal("S1", signalr.Sku.Size);
                Assert.Equal(capacity, signalr.Sku.Capacity);
            }
            Assert.Null(signalr.HostNamePrefix);
            Assert.Equal(ProvisioningState.Succeeded, signalr.ProvisioningState);
            Assert.NotEmpty(signalr.HostName);
            Assert.NotEmpty(signalr.ExternalIP);
            Assert.NotNull(signalr.PublicPort);
            Assert.NotNull(signalr.ServerPort);
            Assert.NotEmpty(signalr.Version);

            // List keys of the updated SignalR instance
            keys = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);
            Assert.NotNull(keys);
            Assert.NotEmpty(keys.PrimaryKey);
            Assert.NotEmpty(keys.PrimaryConnectionString);
            Assert.NotEmpty(keys.SecondaryKey);
            Assert.NotEmpty(keys.SecondaryConnectionString);

            // Regenerate primary key
            var newKeys1 = signalrClient.SignalR.RegenerateKey(resourceGroup.Name, signalr.Name, new RegenerateKeyParameters
            {
                KeyType = "Primary",
            });

            Assert.NotNull(newKeys1);
            Assert.NotEqual(keys.PrimaryKey, newKeys1.PrimaryKey);
            Assert.NotEqual(keys.PrimaryConnectionString, newKeys1.PrimaryConnectionString);
            Assert.Null(newKeys1.SecondaryKey);
            Assert.Null(newKeys1.SecondaryConnectionString);

            // Ensure only the primary key is regenerated
            newKeys1 = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);
            Assert.NotNull(newKeys1);
            Assert.NotEqual(keys.PrimaryKey, newKeys1.PrimaryKey);
            Assert.NotEqual(keys.PrimaryConnectionString, newKeys1.PrimaryConnectionString);
            Assert.Equal(keys.SecondaryKey, newKeys1.SecondaryKey);
            Assert.Equal(keys.SecondaryConnectionString, newKeys1.SecondaryConnectionString);

            // Regenerate secondary key
            var newKeys2 = signalrClient.SignalR.RegenerateKey(resourceGroup.Name, signalr.Name, new RegenerateKeyParameters
            {
                KeyType = "Secondary",
            });

            Assert.NotNull(newKeys2);
            Assert.Null(newKeys2.PrimaryKey);
            Assert.Null(newKeys2.PrimaryConnectionString);
            Assert.NotEqual(keys.SecondaryKey, newKeys2.SecondaryKey);
            Assert.NotEqual(keys.SecondaryConnectionString, newKeys2.SecondaryConnectionString);

            // ensure only the secondary key is regenerated
            newKeys2 = signalrClient.SignalR.ListKeys(resourceGroup.Name, signalr.Name);
            Assert.NotNull(newKeys2);
            Assert.Equal(newKeys1.PrimaryKey, newKeys2.PrimaryKey);
            Assert.Equal(newKeys1.PrimaryConnectionString, newKeys2.PrimaryConnectionString);
            Assert.NotEqual(newKeys1.SecondaryKey, newKeys2.SecondaryKey);
            Assert.NotEqual(newKeys1.SecondaryConnectionString, newKeys2.SecondaryConnectionString);

            // Delete the SignalR instance
            signalrClient.SignalR.Delete(resourceGroup.Name, signalr.Name);

            // Delete again, should be no-op
            signalrClient.SignalR.Delete(resourceGroup.Name, signalr.Name);
        }