/**
         * Azure Event Hub sample for managing geo disaster recovery pairing -
         *   - Create two event hub namespaces
         *   - Create a pairing between two namespaces
         *   - Create an event hub in the primary namespace and retrieve it from the secondary namespace
         *   - Retrieve the pairing connection string
         *   - Fail over so that secondary namespace become primary.
         */
        public static void RunSample(IAzure azure)
        {
            Region region = Region.USEast;
            string rgName = SdkContext.RandomResourceName("rgeh", 15);
            string primaryNamespaceName   = SdkContext.RandomResourceName("ns", 15);
            string secondaryNamespaceName = SdkContext.RandomResourceName("ns", 15);
            string geoDRName           = SdkContext.RandomResourceName("geodr", 14);
            string eventHubName        = SdkContext.RandomResourceName("eh", 14);
            bool   isFailOverSucceeded = false;
            IEventHubDisasterRecoveryPairing pairing = null;

            try
            {
                //============================================================
                // Create resource group for the namespaces and recovery pairings
                //
                IResourceGroup resourceGroup = azure.ResourceGroups.Define(rgName)
                                               .WithRegion(Region.USSouthCentral)
                                               .Create();

                Utilities.Log($"Creating primary event hub namespace {primaryNamespaceName}");

                IEventHubNamespace primaryNamespace = azure.EventHubNamespaces
                                                      .Define(primaryNamespaceName)
                                                      .WithRegion(Region.USSouthCentral)
                                                      .WithExistingResourceGroup(resourceGroup)
                                                      .Create();

                Utilities.Log("Primary event hub namespace created");
                Utilities.Print(primaryNamespace);

                Utilities.Log($"Creating secondary event hub namespace {primaryNamespaceName}");

                IEventHubNamespace secondaryNamespace = azure.EventHubNamespaces
                                                        .Define(secondaryNamespaceName)
                                                        .WithRegion(Region.USNorthCentral)
                                                        .WithExistingResourceGroup(resourceGroup)
                                                        .Create();

                Utilities.Log("Secondary event hub namespace created");
                Utilities.Print(secondaryNamespace);

                //============================================================
                // Create primary and secondary namespaces and recovery pairing
                //

                Utilities.Log($"Creating geo-disaster recovery pairing {geoDRName}");

                pairing = azure.EventHubDisasterRecoveryPairings
                          .Define(geoDRName)
                          .WithExistingPrimaryNamespace(primaryNamespace)
                          .WithExistingSecondaryNamespace(secondaryNamespace)
                          .Create();

                while (pairing.ProvisioningState != ProvisioningStateDR.Succeeded)
                {
                    pairing = pairing.Refresh();
                    SdkContext.DelayProvider.Delay(15 * 1000);
                    if (pairing.ProvisioningState == ProvisioningStateDR.Failed)
                    {
                        throw new Exception("Provisioning state of the pairing is FAILED");
                    }
                }

                Utilities.Log($"Created geo-disaster recovery pairing {geoDRName}");
                Utilities.Print(pairing);

                //============================================================
                // Create an event hub and consumer group in primary namespace
                //

                Utilities.Log("Creating an event hub and consumer group in primary namespace");

                IEventHub eventHubInPrimaryNamespace = azure.EventHubs
                                                       .Define(eventHubName)
                                                       .WithExistingNamespace(primaryNamespace)
                                                       .WithNewConsumerGroup("consumerGrp1")
                                                       .Create();

                Utilities.Log("Created event hub and consumer group in primary namespace");
                Utilities.Print(eventHubInPrimaryNamespace);

                Utilities.Log("Waiting for 60 seconds to allow metadata to sync across primary and secondary");
                SdkContext.DelayProvider.Delay(60 * 1000); // Wait for syncing to finish

                Utilities.Log("Retrieving the event hubs in secondary namespace");

                IEventHub eventHubInSecondaryNamespace = azure.EventHubs.GetByName(rgName, secondaryNamespaceName, eventHubName);

                Utilities.Log("Retrieved the event hubs in secondary namespace");
                Utilities.Print(eventHubInSecondaryNamespace);

                //============================================================
                // Retrieving the connection string
                //
                var rules = pairing.ListAuthorizationRules();
                foreach (IDisasterRecoveryPairingAuthorizationRule rule in rules)
                {
                    IDisasterRecoveryPairingAuthorizationKey key = rule.GetKeys();
                    Utilities.Print(key);
                }

                Utilities.Log("Initiating fail over");

                pairing.FailOver();
                isFailOverSucceeded = true;

                Utilities.Log("Fail over initiated");
            }
            finally
            {
                try
                {
                    try
                    {
                        // It is necessary to break pairing before deleting resource group
                        //
                        if (pairing != null && !isFailOverSucceeded)
                        {
                            pairing.BreakPairing();
                        }
                    }
                    catch (Exception ex)
                    {
                        Utilities.Log("Pairing breaking failed:" + ex.Message);
                    }
                    azure.ResourceGroups.BeginDeleteByName(rgName);
                }
                catch (NullReferenceException)
                {
                    Utilities.Log("Did not create any resources in Azure. No clean up is necessary");
                }
                catch (Exception ex)
                {
                    Utilities.Log(ex);
                }
            }
        }
        public void CanManageGeoDisasterRecoveryPairing()
        {
            using (var context = FluentMockContext.Start(GetType().FullName))
            {
                var region         = Region.USEast;
                var groupName      = TestUtilities.GenerateName("rgns");
                var geodrName      = TestUtilities.GenerateName("geodr");
                var namespaceName1 = TestUtilities.GenerateName("ns111");
                var namespaceName2 = TestUtilities.GenerateName("ns222");

                var azure = TestHelper.CreateRollupClient();
                try
                {
                    IEventHubNamespace primaryNamespace = azure.EventHubNamespaces
                                                          .Define(namespaceName1)
                                                          .WithRegion(Region.USSouthCentral)
                                                          .WithNewResourceGroup(groupName)
                                                          .Create();

                    IEventHubNamespace secondaryNamespace = azure.EventHubNamespaces
                                                            .Define(namespaceName2)
                                                            .WithRegion(Region.USNorthCentral)
                                                            .WithExistingResourceGroup(groupName)
                                                            .Create();

                    Exception exception      = null;
                    Exception breakingFailed = null;
                    IEventHubDisasterRecoveryPairing pairing = null;
                    try
                    {
                        pairing = azure.EventHubDisasterRecoveryPairings
                                  .Define(geodrName)
                                  .WithExistingPrimaryNamespace(primaryNamespace)
                                  .WithExistingSecondaryNamespace(secondaryNamespace)
                                  .Create();

                        while (pairing.ProvisioningState != ProvisioningStateDR.Succeeded)
                        {
                            pairing = pairing.Refresh();
                            SdkContext.DelayProvider.Delay(15 * 1000);
                            if (pairing.ProvisioningState == ProvisioningStateDR.Failed)
                            {
                                Assert.True(false, "Provisioning state of the pairing is FAILED");
                            }
                        }

                        Assert.Equal(pairing.Name, geodrName, ignoreCase: true);
                        Assert.Equal(pairing.PrimaryNamespaceResourceGroupName, groupName, ignoreCase: true);
                        Assert.Equal(pairing.PrimaryNamespaceName, primaryNamespace.Name, ignoreCase: true);
                        Assert.Equal(pairing.SecondaryNamespaceId, secondaryNamespace.Id, ignoreCase: true);

                        var rules = pairing.ListAuthorizationRules();
                        Assert.True(rules.Count() > 0);
                        foreach (IDisasterRecoveryPairingAuthorizationRule rule in rules)
                        {
                            IDisasterRecoveryPairingAuthorizationKey keys = rule.GetKeys();
                            Assert.NotNull(keys.AliasPrimaryConnectionString);
                            Assert.NotNull(keys.AliasPrimaryConnectionString);
                            Assert.NotNull(keys.PrimaryKey);
                            Assert.NotNull(keys.SecondaryKey);
                        }

                        IEventHubDisasterRecoveryPairings pairingsCol = azure.EventHubDisasterRecoveryPairings;
                        var pairings = pairingsCol
                                       .ListByNamespace(primaryNamespace.ResourceGroupName, primaryNamespace.Name);

                        Assert.True(pairings.Count() > 0);

                        bool found = false;
                        foreach (IEventHubDisasterRecoveryPairing pairing1 in pairings)
                        {
                            if (pairing1.Name.Equals(pairing.Name, StringComparison.OrdinalIgnoreCase))
                            {
                                found = true;
                                Assert.Equal(pairing1.PrimaryNamespaceResourceGroupName, groupName);
                                Assert.Equal(pairing1.PrimaryNamespaceName, primaryNamespace.Name);
                                Assert.Equal(pairing1.SecondaryNamespaceId, secondaryNamespace.Id);
                            }
                        }
                        Assert.True(found);
                    }
                    catch (Exception ex)
                    {
                        exception = ex;
                    }
                    finally
                    {
                        if (exception != null && pairing != null)
                        {
                            // Resource group cannot be deleted if the pairing-replication is
                            // (backgroud work by RP) progress so pairing must forcefully break.
                            try
                            {
                                pairing.BreakPairing();
                            }
                            catch (Exception ex)
                            {
                                breakingFailed = ex;
                            }
                        }
                    }
                    if (exception != null && breakingFailed != null)
                    {
                        AggregateException cex = new AggregateException(exception, breakingFailed);
                        throw cex;
                    }
                    if (exception != null)
                    {
                        throw exception;
                    }
                    if (breakingFailed != null)
                    {
                        throw breakingFailed;
                    }
                    pairing.Refresh();
                    pairing.FailOver();
                }
                finally
                {
                    try
                    {
                        azure.ResourceGroups.BeginDeleteByName(groupName);
                    }
                    catch
                    { }
                }
            }
        }