//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 async Task RunSample(TokenCredential credential)
        {
            string region                 = "eastus";
            string subscriptionId         = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
            string rgName                 = Utilities.RandomResourceName("rgeh", 15);
            string primaryNamespaceName   = Utilities.RandomResourceName("ns", 15);
            string secondaryNamespaceName = Utilities.RandomResourceName("ns", 15);
            string geoDRName              = Utilities.RandomResourceName("geodr", 14);
            string eventHubName           = Utilities.RandomResourceName("eh", 14);
            bool   isFailOverSucceeded    = false;
            ArmDisasterRecovery pairing   = null;

            var eventHubsManagementClient = new EventHubsManagementClient(subscriptionId, credential);
            var namespaces              = eventHubsManagementClient.Namespaces;
            var eventHubs               = eventHubsManagementClient.EventHubs;
            var consumerGroups          = eventHubsManagementClient.ConsumerGroups;
            var disasterRecoveryConfigs = eventHubsManagementClient.DisasterRecoveryConfigs;

            try
            {
                await ResourceGroupHelper.CreateOrUpdateResourceGroup(rgName, region);

                // Create resource group for the namespaces and recovery pairings

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

                var primaryResult = await namespaces.StartCreateOrUpdateAsync(
                    rgName,
                    primaryNamespaceName,
                    new EHNamespace
                {
                    Location = "southcentralus"
                });

                var primaryNamespace = (await primaryResult.WaitForCompletionAsync()).Value;

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

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

                var secondaryResult = await namespaces.StartCreateOrUpdateAsync(
                    rgName,
                    secondaryNamespaceName,
                    new EHNamespace
                {
                    Location = "northcentralus"
                });

                var secondaryNamespace = (await secondaryResult.WaitForCompletionAsync()).Value;

                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 = (await disasterRecoveryConfigs.CreateOrUpdateAsync(
                               rgName,
                               primaryNamespaceName,
                               geoDRName,
                               new ArmDisasterRecovery
                {
                    PartnerNamespace = secondaryNamespace.Id
                }
                               )).Value;
                while ((await disasterRecoveryConfigs.GetAsync(rgName, primaryNamespaceName, geoDRName)).Value.ProvisioningState != ProvisioningStateDR.Succeeded)
                {
                    Utilities.Log("Wait for create disaster recovery");
                    Thread.Sleep(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");

                var primaryEventHub = (await eventHubs.CreateOrUpdateAsync(
                                           rgName,
                                           primaryNamespaceName,
                                           eventHubName,
                                           new Eventhub()
                                           )).Value;
                var primaryConsumerGroup = (await consumerGroups.CreateOrUpdateAsync(
                                                rgName,
                                                primaryNamespaceName,
                                                eventHubName,
                                                "consumerGrp1",
                                                new ConsumerGroup()
                                                )).Value;

                var eventHubInPrimaryNamespace = (await namespaces.GetAsync(rgName, primaryNamespaceName)).Value;

                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");
                Thread.Sleep(60 * 1000); // Wait for syncing to finish

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

                var eventHubInSecondaryNamespace = (await namespaces.GetAsync(rgName, secondaryNamespaceName)).Value;

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

                // Retrieving the connection string

                var rules = await disasterRecoveryConfigs.ListAuthorizationRulesAsync(rgName, primaryNamespaceName, geoDRName).ToEnumerableAsync();

                foreach (var rule in rules)
                {
                    var key = (await disasterRecoveryConfigs.ListKeysAsync(rgName, primaryNamespaceName, geoDRName, rule.Name)).Value;
                    Utilities.Print(key);
                }

                Utilities.Log("Initiating fail over");

                var failOverResult = await disasterRecoveryConfigs.FailOverAsync(rgName, secondaryNamespaceName, geoDRName);

                Thread.Sleep(10 * 1000);
                while ((await disasterRecoveryConfigs.GetAsync(rgName, secondaryNamespaceName, geoDRName)).Value.ProvisioningState == ProvisioningStateDR.Accepted)
                {
                    Utilities.Log("Wait for fail over");
                    Thread.Sleep(10 * 1000);
                }
                if ((await disasterRecoveryConfigs.GetAsync(rgName, secondaryNamespaceName, geoDRName)).Value.ProvisioningState == ProvisioningStateDR.Succeeded)
                {
                    isFailOverSucceeded = true;
                    Utilities.Log("Fail over initiated");
                }
                else
                {
                    Utilities.Log("Fail over is FAILED");
                }
            }
            finally
            {
                try
                {
                    try
                    {
                        // It is necessary to break pairing before deleting resource group
                        if (pairing != null && !isFailOverSucceeded)
                        {
                            await disasterRecoveryConfigs.BreakPairingAsync(rgName, primaryNamespaceName, geoDRName);

                            Thread.Sleep(10 * 1000);
                            while ((await disasterRecoveryConfigs.GetAsync(rgName, primaryNamespaceName, geoDRName)).Value.ProvisioningState == ProvisioningStateDR.Accepted)
                            {
                                Thread.Sleep(10 * 1000);
                            }
                            if ((await disasterRecoveryConfigs.GetAsync(rgName, primaryNamespaceName, geoDRName)).Value.ProvisioningState == ProvisioningStateDR.Failed)
                            {
                                throw new Exception("Provisioning state of the break pairing is FAILED");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Utilities.Log("Pairing breaking failed:" + ex.Message);
                    }
                    await ResourceGroupHelper.DeleteResourceGroup(rgName);
                }
                catch (NullReferenceException)
                {
                    Utilities.Log("Did not create any resources in Azure. No clean up is necessary");
                }
                catch (Exception ex)
                {
                    Utilities.Log(ex);
                }
            }
        }
        public static async Task RunSample(TokenCredential credential)
        {
            string region             = "eastus";
            string subscriptionId     = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
            string rgName             = Utilities.RandomResourceName("rgeh", 15);
            string namespaceName1     = Utilities.RandomResourceName("ns", 15);
            string namespaceName2     = Utilities.RandomResourceName("ns", 15);
            string storageAccountName = Utilities.RandomResourceName("stg", 14);
            string eventHubName1      = Utilities.RandomResourceName("eh", 14);
            string eventHubName2      = Utilities.RandomResourceName("eh", 14);

            var eventHubsManagementClient = new EventHubsManagementClient(subscriptionId, credential);
            var namespaces              = eventHubsManagementClient.Namespaces;
            var eventHubs               = eventHubsManagementClient.EventHubs;
            var consumerGroups          = eventHubsManagementClient.ConsumerGroups;
            var storageManagementClient = new StorageManagementClient(subscriptionId, credential);
            var storageAccounts         = storageManagementClient.StorageAccounts;
            var blobContainers          = storageManagementClient.BlobContainers;

            try
            {
                await ResourceGroupHelper.CreateOrUpdateResourceGroup(rgName, region);

                //============================================================
                // Create an event hub namespace
                //

                Utilities.Log("Creating a namespace");

                var rawResult = await namespaces.StartCreateOrUpdateAsync(
                    rgName,
                    namespaceName1,
                    new EHNamespace
                {
                    Location = "eastus2"
                });

                var namespace1 = (await rawResult.WaitForCompletionAsync()).Value;

                Utilities.Print(namespace1);
                Utilities.Log("Created a namespace");

                //============================================================
                // Create an event hub in the namespace with data capture enabled, with consumer group and auth rule
                //

                var storageAccountCreatable = (await(await storageAccounts.StartCreateAsync(
                                                         rgName,
                                                         storageAccountName,
                                                         new StorageAccountCreateParameters(
                                                             new Azure.ResourceManager.Storage.Models.Sku("Standard_LRS"),
                                                             new Kind("StorageV2"),
                                                             "eastus2")
                                                         )).WaitForCompletionAsync()).Value;
                var container = await blobContainers.CreateAsync(
                    rgName,
                    storageAccountName,
                    "datacpt",
                    new BlobContainer()
                    );

                Utilities.Log("Creating an event hub with data capture enabled with a consumer group and rule in it");

                var eventHub1 = (await eventHubs.CreateOrUpdateAsync(
                                     rgName,
                                     namespace1.Name,
                                     eventHubName1,
                                     new Eventhub
                {
                    MessageRetentionInDays = 4,
                    PartitionCount = 4,
                    Status = EntityStatus.Active,
                    // Optional - configure data capture
                    CaptureDescription = new CaptureDescription
                    {
                        Enabled = true,
                        Encoding = EncodingCaptureDescription.Avro,
                        IntervalInSeconds = 120,
                        SizeLimitInBytes = 10485763,
                        Destination = new Destination
                        {
                            Name = "EventHubArchive.AzureBlockBlob",
                            BlobContainer = "datacpt",
                            ArchiveNameFormat = "{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}",
                            StorageAccountResourceId = "/subscriptions/" + subscriptionId + "/resourcegroups/" + rgName + "/providers/Microsoft.Storage/storageAccounts/" + storageAccountName
                        },
                        SkipEmptyArchives = true
                    }
                }
                                     )).Value;
                // Optional - create one consumer group in event hub
                var consumerGroup1 = await consumerGroups.CreateOrUpdateAsync(
                    rgName,
                    namespaceName1,
                    eventHubName1,
                    "cg1",
                    new ConsumerGroup
                {
                    UserMetadata = "sometadata"
                }
                    );

                // Optional - create an authorization rule for event hub
                var listenRule1 = await eventHubs.CreateOrUpdateAuthorizationRuleAsync(
                    rgName,
                    namespaceName1,
                    eventHubName1,
                    "listenrule1",
                    new AuthorizationRule
                {
                    Rights = new List <AccessRights>()
                    {
                        AccessRights.Listen, AccessRights.Send
                    }
                }
                    );

                Utilities.Log("Created an event hub with data capture enabled with a consumer group and rule in it");

                var result = (await eventHubs.GetAsync(rgName, namespaceName1, eventHubName1)).Value;

                Utilities.Print(result);

                //============================================================
                // Retrieve consumer groups in the event hub
                //
                Utilities.Log("Retrieving consumer groups");

                var listResult = await consumerGroups.ListByEventHubAsync(rgName, namespaceName1, eventHubName1).ToEnumerableAsync();

                Utilities.Log("Retrieved consumer groups");

                foreach (var group in listResult)
                {
                    Utilities.Print(group);
                }

                //============================================================
                // Create another event hub in the namespace
                //

                Utilities.Log("Creating another event hub in the namespace");

                var eventHub2 = (await eventHubs.CreateOrUpdateAsync(
                                     rgName,
                                     namespaceName1,
                                     eventHubName2,
                                     new Eventhub()
                                     )).Value;

                Utilities.Log("Created second event hub");
                Utilities.Print(eventHub2);

                //============================================================
                // Create a consumer group in the event hub
                //

                Utilities.Log("Creating a consumer group in the second event hub");

                var consumerGroup2 = (await consumerGroups.CreateOrUpdateAsync(
                                          rgName,
                                          namespaceName1,
                                          eventHubName2,
                                          "cg2",
                                          // Optional
                                          new ConsumerGroup
                {
                    UserMetadata = "sometadata"
                }
                                          )).Value;

                Utilities.Log("Created a consumer group in the second event hub");
                Utilities.Print(consumerGroup2);

                //============================================================
                // Retrieve consumer groups in the event hub
                //
                Utilities.Log("Retrieving consumer groups in the second event hub");

                listResult = await consumerGroups.ListByEventHubAsync(rgName, namespaceName1, eventHubName2).ToEnumerableAsync();

                Utilities.Log("Retrieved consumer groups in the seoond event hub");

                foreach (var group in listResult)
                {
                    Utilities.Print(group);
                }

                //============================================================
                // Create an event hub namespace with event hub
                //

                Utilities.Log("Creating an event hub namespace along with event hub");

                var rawResult2 = await namespaces.StartCreateOrUpdateAsync(
                    rgName,
                    namespaceName2,
                    new EHNamespace
                {
                    Location = "eastus2"
                });

                var namespace2 = (await rawResult2.WaitForCompletionAsync()).Value;

                var newEventHub2 = (await eventHubs.CreateOrUpdateAsync(
                                        rgName,
                                        namespaceName2,
                                        eventHubName2,
                                        new Eventhub()
                                        )).Value;


                Utilities.Log("Created an event hub namespace along with event hub");
                Utilities.Print(namespace2);

                foreach (var eh in await eventHubs.ListByNamespaceAsync(rgName, namespaceName2).ToEnumerableAsync())
                {
                    Utilities.Print(eh);
                }
            }
            finally
            {
                try
                {
                    await ResourceGroupHelper.DeleteResourceGroup(rgName);
                }
                catch (NullReferenceException)
                {
                    Utilities.Log("Did not create any resources in Azure. No clean up is necessary");
                }
                catch (Exception ex)
                {
                    Utilities.Log(ex);
                }
            }
        }
Example #3
0
        public static async Task RunSample(TokenCredential credential)
        {
            string region         = "eastus";
            string subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
            string rgName         = Utilities.RandomResourceName("rgEvHb", 15);
            string namespaceName  = Utilities.RandomResourceName("ns", 15);
            string eventHubName   = "FirstEventHub";

            var eventHubsManagementClient = new EventHubsManagementClient(subscriptionId, credential);
            var namespaces = eventHubsManagementClient.Namespaces;
            var eventHubs  = eventHubsManagementClient.EventHubs;

            try
            {
                await ResourceGroupHelper.CreateOrUpdateResourceGroup(rgName, region);

                // Creates a Event Hub namespace and an Event Hub in it.
                Utilities.Log("Creating event hub namespace and event hub");

                Utilities.Log("Creating a namespace");

                var rawResult = await namespaces.StartCreateOrUpdateAsync(
                    rgName,
                    namespaceName,
                    new EHNamespace
                {
                    Location = "eastus2"
                });

                var ehNamespace = (await rawResult.WaitForCompletionAsync()).Value;

                Utilities.Print(ehNamespace);
                Utilities.Log("Created a namespace");

                var eventHub = (await eventHubs.CreateOrUpdateAsync(
                                    rgName,
                                    ehNamespace.Name,
                                    eventHubName,
                                    new Eventhub
                {
                    MessageRetentionInDays = 4,
                    PartitionCount = 4,
                    Status = EntityStatus.Active,
                }
                                    )).Value;

                Utilities.Log($"Created event hub namespace {ehNamespace.Name} and event hub {eventHubName}");
                Utilities.Print(ehNamespace);

                // Create a Authorization Rule for Event Hub created.
                Utilities.Log("Creating a Authorization Rule");

                var listenRule = (await eventHubs.CreateOrUpdateAuthorizationRuleAsync(
                                      rgName,
                                      namespaceName,
                                      eventHubName,
                                      "listenrule1",
                                      new AuthorizationRule
                {
                    Rights = new List <AccessRights>()
                    {
                        AccessRights.Listen, AccessRights.Send
                    }
                }
                                      )).Value;

                Utilities.Log("Created a Authorization Rule");

                // Send events using dataplane eventhub sdk.
                Utilities.Log("Sending events");

                var keys           = (await eventHubs.ListKeysAsync(rgName, namespaceName, eventHubName, listenRule.Name)).Value;
                var producerClient = new EventHubProducerClient(keys.PrimaryConnectionString, eventHubName);

                using EventDataBatch eventBatch = await producerClient.CreateBatchAsync();

                eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes("Hello, Event Hubs!")));
                eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes("The middle event is this one")));
                eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes("Goodbye, Event Hubs!")));

                await producerClient.SendAsync(eventBatch);

                Utilities.Log("Sent events");

                Utilities.Log("Reading events");

                var consumerClient = new EventHubConsumerClient(EventHubConsumerClient.DefaultConsumerGroupName, keys.PrimaryConnectionString, eventHubName);
                using CancellationTokenSource cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(TimeSpan.FromSeconds(90));

                int eventsRead    = 0;
                int maximumEvents = 3;

                await foreach (PartitionEvent partitionEvent in consumerClient.ReadEventsAsync(cancellationSource.Token))
                {
                    Utilities.Log($"Event Read: { Encoding.UTF8.GetString(partitionEvent.Data.Body.ToArray()) }");
                    eventsRead++;

                    if (eventsRead >= maximumEvents)
                    {
                        break;
                    }
                }
            }
            finally
            {
                try
                {
                    await ResourceGroupHelper.DeleteResourceGroup(rgName);
                }
                catch (NullReferenceException)
                {
                    Utilities.Log("Did not create any resources in Azure. No clean up is necessary");
                }
                catch (Exception ex)
                {
                    Utilities.Log(ex);
                }
            }
        }