Tuesday, 6 June 2023

Publish messages to Azure Service Bus using c# console app.

In this article, I will explain and provide the working code to pusblish message to Azure service bus using C# console app.


First of all install the Server Bus package and include below ref

    using Azure.Messaging.ServiceBus;

Define service bus connection string and queue name

        private const string serviceBusConnectionString = "Copy and paste service bus connection string";

        private const string queueName = "demo-servicebusqueue";

Define variables to use

         private const int numOfMessages = 200;

        static ServiceBusClient client = default!;

        static ServiceBusSender sender = default!;

        static ServiceBusProcessor processor = default!;

Below is the main method calls Message publisher method which generates message and push to service bus

 public static async Task Main(string[] args)

        {

            try

             {

                await MessagePublisher();

             }

            catch (Exception ex)

             {

                Console.WriteLine($"Exception: {ex.Message}");

             }

          }


Define publisher method, in this case, which generates message

        private static async Task<string> MessagePublisher()

        {

            // create service bus client

            client = new ServiceBusClient(serviceBusConnectionString);

            // Create message sender

            sender = client.CreateSender(queueName);

            // create service message batch

            using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

            var msg = "";

            for (int i =1; i <= numOfMessages; i++)

            {

                msg= $"{{\"id\": {i},\"createdOn\": \"2023-04-05T13:04:57\",\"description\": \"This is very good product with 1 year wanranty\",\"isDone\": false}}";

                // add message to batch

                if (!messageBatch.TryAddMessage(new ServiceBusMessage(msg)))

                {

                    throw new Exception($"An exception has been thrown");

                }

            }

            try

            {

                // finally send message to azure service bus

                await sender.SendMessagesAsync(messageBatch);

                Console.WriteLine($"A batch of {numOfMessages} messages has been published to the queue.");

            }

            finally

            {

                await sender.DisposeAsync();

                await client.DisposeAsync();

            }

            return "All messages have been published to the queue";

        } 


Complete code 

using System;

using System.Diagnostics;

using System.Threading.Tasks;

using Azure.Messaging.ServiceBus;

using Microsoft.Azure.Amqp.Framing;

namespace AzServiceBus

{

    public class Program

    {

        private const string serviceBusConnectionString = "Copy and paste service bus connection string";

        private const string queueName = "demo-servicebusqueue";

        private const int numOfMessages = 200;

        static ServiceBusClient client = default!;

        static ServiceBusSender sender = default!;

        static ServiceBusProcessor processor = default!;

        public static async Task Main(string[] args)

        {

            try

            {

                await MessagePublisher();

            }

            catch (Exception ex)

            {

                Console.WriteLine($"Exception: {ex.Message}");

            }

        }

        private static async Task<string> MessagePublisher()

        {

            client = new ServiceBusClient(serviceBusConnectionString);

            sender = client.CreateSender(queueName);

            using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

            var msg = "";

            for (int i =1; i <= numOfMessages; i++)

            {

                msg= $"{{\"id\": {i},\"createdOn\": \"2023-04-05T13:04:57\",\"description\": \"This is very good product with 1 year wanranty\",\"isDone\": false}}";

                if (!messageBatch.TryAddMessage(new ServiceBusMessage(msg)))

                {

                    throw new Exception($"An exception has been thrown");

                }

            }

            try

            {

                await sender.SendMessagesAsync(messageBatch);

                Console.WriteLine($"A batch of {numOfMessages} messages has been published to the queue.");

            }

            finally

            {

                await sender.DisposeAsync();

                await client.DisposeAsync();

            }

            return "All messages have been published to the queue";

        }

    }

}




Tuesday, 30 May 2023

Access and insert data to Azure Cosmos database using C# console app

In the below code example, I insert datd to Azure Cosmos DB using C# console app. The code read a JSON file and serialize JSON to C# object callled Model and Product.


using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using System.Threading.Tasks;

using System.Text.Json;

using System.IO;

using Microsoft.Azure.Cosmos;

 

namespace AzCosmosDB

{

    internal class Program

    {

        // in prod below variable must be stored in app settings

        private const string EndpointUrl = "https://demo-cosmosdb-retail.documents.azure.com:443/";

        private const string AuthorizationKey = "eKXwigOPIGlu7NHzBEEr1lqc8zRACDbaJ0t9Q==";

        private const string DatabaseName = "Retail";

        private const string ContainerName = "Online";

        private const string PartitionKey = "/Category";

        private const string JsonFilePath = "D:\\Project\\Azure\\AzCosmosDB\\models.json";

 

        static private int amountToInsert;

        static List<Model> models;

        static async Task Main(string[] args)

        {

            try

            {

                // <CreateClient>

                CosmosClient cosmosClient = new CosmosClient(EndpointUrl, AuthorizationKey, new CosmosClientOptions() { AllowBulkExecution = true });

                // </CreateClient>

                // <Initialize>

                Console.WriteLine($"Creating a database if not already exists...");

                Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync(Program.DatabaseName);

 

                // Configure indexing policy to exclude all attributes to maximize RU/s usage

                Console.WriteLine($"Creating a container if not already exists...");

                await database.DefineContainer(Program.ContainerName, PartitionKey)

                        .WithIndexingPolicy()

                            .WithIndexingMode(IndexingMode.Consistent)

                            .WithIncludedPaths()

                                .Attach()

                            .WithExcludedPaths()

                                .Path("/*")

                                .Attach()

                        .Attach()

                    .CreateAsync();

                // </Initialize>

 

                using (StreamReader reader = new StreamReader(File.OpenRead(JsonFilePath)))

                {

                    string json = await reader.ReadToEndAsync();

                    models = JsonSerializer.Deserialize<List<Model>>(json);

                    amountToInsert = models.Count;

                }

 

                // Prepare items for insertion

                Console.WriteLine($"Preparing {amountToInsert} items to insert...");

 

                // Create the list of Tasks

                Console.WriteLine($"Starting...");

                Stopwatch stopwatch = Stopwatch.StartNew();

                // <ConcurrentTasks>

                Container container = database.GetContainer(ContainerName);

 

                List<Task> tasks = new List<Task>(amountToInsert);

                foreach (Model model in models)

                {

                    tasks.Add(container.CreateItemAsync(model, new PartitionKey(model.Category))

                        .ContinueWith(itemResponse =>

                        {

                            if (!itemResponse.IsCompletedSuccessfully)

                            {

                                AggregateException innerExceptions = itemResponse.Exception.Flatten();

                                if (innerExceptions.InnerExceptions.FirstOrDefault(innerEx => innerEx is CosmosException) is CosmosException cosmosException)

                                {

                                    Console.WriteLine($"Received {cosmosException.StatusCode} ({cosmosException.Message}).");

                                }

                                else

                                {

                                    Console.WriteLine($"Exception {innerExceptions.InnerExceptions.FirstOrDefault()}.");

                                }

                            }

                        }));

                }

                // Wait until all are done

                await Task.WhenAll(tasks);

                // </ConcurrentTasks>

                stopwatch.Stop();

 

                Console.WriteLine($"Finished writing {amountToInsert} items in {stopwatch.Elapsed}.");

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex);

            }

        }

    }

    public class Model

        {

            public string id { get; set; }

            public string Name { get; set; }

            public string Category { get; set; }

            public string Description { get; set; }

            public string Photo { get; set; }

            public IList<Product> Products { get; set; }

        }

 

    public class Product

        {

            public string id { get; set; }

            public string Name { get; set; }

            public string Number { get; set; }

            public string Category { get; set; }

            public string Color { get; set; }

            public string Size { get; set; }

            public decimal? Weight { get; set; }

            public decimal ListPrice { get; set; }

            public string Photo { get; set; }

        }

}


JSON Example:

[

  {

    "id": "0481d7e1-4970-4efa-a560-020f6579918d",

    "Name": "LL Fork",

    "Category": "Forks",

    "Description": "Stout design absorbs shock and offers more precise steering.",

    "Products": [

      {

        "id": "fb8502be-07eb-4134-ab06-c3a9959a52ae",

        "Name": "LL Fork",

        "Number": "FK-1639",

        "Category": "Forks",

        "Color": null,

        "Size": null,

        "Weight": null,

        "ListPrice": 148.22,

        "Photo": "fork.jpg"

      }

    ],

    "Photo": "fork.jpg"

  },

  {

    "id": "ca18ecfd-2023-4fa7-a556-0321153bca34",

    "Name": "ML Road Frame-W",

    "Category": "Road Frames",

    "Description": "Made from the same aluminum alloy as our top-of-the line HL frame, the ML features a lightweight down-tube milled to the perfect diameter for optimal strength. Women's version.",

    "Products": [

      {

        "id": "22df26f2-60bc-493e-a14a-5500633e9f7e",

        "Name": "ML Road Frame-W - Yellow, 40",

        "Number": "FR-R72Y-40",

        "Category": "Road Frames",

        "Color": "Yellow",

        "Size": "40",

        "Weight": 1006.97,

        "ListPrice": 594.83,

        "Photo": "no_image_available.jpg"

      },

      {

        "id": "207b54da-5404-415d-8578-9a45082e3bf1",

        "Name": "ML Road Frame-W - Yellow, 42",

        "Number": "FR-R72Y-42",

        "Category": "Road Frames",

        "Color": "Yellow",

        "Size": "42",

        "Weight": 1025.11,

        "ListPrice": 594.83,

        "Photo": "no_image_available.jpg"

      },

      {

        "id": "22976fa7-0ad0-40f9-b4f9-ba10279ea1a3",

        "Name": "ML Road Frame-W - Yellow, 38",

        "Number": "FR-R72Y-38",

        "Category": "Road Frames",

        "Color": "Yellow",

        "Size": "38",

        "Weight": 988.83,

        "ListPrice": 594.83,

        "Photo": "no_image_available.jpg"

      },

      {

        "id": "a0fad492-ac24-4fcf-8d2a-d21d06386ae1",

        "Name": "ML Road Frame-W - Yellow, 44",

        "Number": "FR-R72Y-44",

        "Category": "Road Frames",

        "Color": "Yellow",

        "Size": "44",

        "Weight": 1043.26,

        "ListPrice": 594.83,

        "Photo": "no_image_available.jpg"

      },

      {

        "id": "8487bfe0-2138-471e-9c6d-fdb3a67e7d86",

        "Name": "ML Road Frame-W - Yellow, 48",

        "Number": "FR-R72Y-48",

        "Category": "Road Frames",

        "Color": "Yellow",

        "Size": "48",

        "Weight": 1061.4,

        "ListPrice": 594.83,

        "Photo": "no_image_available.jpg"

      }

    ],

    "Photo": "no_image_available.jpg"

  }

 ]