Monday, August 19, 2024

Serverless HTTP API - Using AWS API Gateway, Lambda and Python

Table of Content

Create AWS API Gateway Service

Login to your AWS console – you can search API gateway in search box or if you have already visited it will show in recently visited info…

Click on API Gateway service – you will navigate to Build API gateway page where you can find different of options to create API gateway like

Based on Your requirement you can choose any option – in our case we are building HTTP Rest Api with different routes, so we chose HTTP API Option

Choose HTTP API and click on Build – You will navigate to create API page like below

There are 4 steps -

  1. Create API
  2. Configure Routes
  3. Define Stage
  4. Review and Create

Create API

In this page you have to provide two inputs

  1. Integrations: you have to specifybackend service which perform some task execution once this API triggered like Lambda Function or any other HTTP API like below

    at this moment this part is optional you can specify this at later stage as well

  2. API Name: Mandatory, it will be part of your API list so this should meaningful and unique. May be you can choose name related to your project.

Configure Routes

Click Next – you will navigate to Configure routes page like below

In One API Gateway we can create multiple routes of different types of HTTP methods so at this moment don’t add any things and click Next for navigating to next steps

Define Stages

Stages are nothing but different environment for you project like DEV/QA/STAGE/UAT/Production so you have already created different stage in aws you can integrate/ assign here ..

Also Server less API gateway also come with default stage you can proceed with that and at later stage you can create and change the stage .. Default stage provide auto deploy option ..

Review and Create

Verify All steps and click on create – once it is successful it will navigate to New API gateway main page like below

For every API Gateway AWS provide a unique public URL (End Points) so that this can be consumed through that ..

Like this https://xxxxxxx.execute-api.ap-xxxxxx-1.amazonaws.com

If you have already created different stages with your domain or sub domain name this URL will be look like your domain name

Edit API Gateway:

At this moment if want to do some changes in API gateway, you can changes through Edit Option

Once you click Edit button you will navigate to Edit page

From this page you can only change 3 things

  • API Name
  • API Description
  • And you can enable or disable API

You can also add tags here for this cloud resource

Creating New Route:

If you have multiple APIs gateway in API gateway dashboard page it will look like this

Click on Name link in the API List grid in which you want to add new routes then it will navigate to selected API Dashboard

In this page we have we have Left menu with different options like Develop, Deploy, Monitor. In develop section you can find Routes option from this menu we can navigate to Routes management page where we can add/edit/delete different routes for this API.

Currently we have not created any routes for this API that is why this list is empty so lets up go create new route by clicking on Create Button -

Here we need to decide http method like get/put/post/delete/any and route name.

For this demo lets choose get and name like getProductList (name: should be unique for each route in this api)

Click on Create button – once operation is successful it will navigate to route list page

Now we have successfully created new route under out test API as getProductList. So the public URL for this route will be like this

API Gateway URL/getProductList

Eg :https://xxxxxxxxxxx.execute-api.ap-xxxxxxxx.amazonaws.com/getProductList

In this page if you click on GET Link it will show route details like below

In Details section mainly there are two parts

  1. Authorization - For Securing your API using IAM service or any API based custom policy
  2. Integration – For integrating backing service like lambda function which execute some code/task when this route hits or any other HTTP API can trigger

Also there are two more option Delete and Edit for deleting/updating this route

For this demo till now we have created

  1. API Gateway
  2. One Route (getProductList)

Now let us create a simple lambda function which return dummy product name list. Once this lambda is ready, we will integrate the same lambda in this route (getProductList) through Attach Integration option.

Create AWS Lambada Funtion

Click on search option and find lambda function it will navigate to lambda dashboard

Click on Create Function it will navigate to AWS Lambda creation page –

AWS Lambda function can be created from three different way

  1. Author from Scratch – start with simple hallo world example
  2. Use a blueprint – Create based on some template or sample code and configuration
  3. Container Image – if you have already container image select this option to deploy your function

For this demo let’s choose simple first option “Author from Scratch” and Python 3.9 as a Runtime info

Put Function name as getProductListLambda and let’s leave other options as default

And hit Create Function it will new getProdcutListLambda function and navigate to lambda page like below

Go to code section and past this simple python script and click on deploy

Once Deployed Click on Test button it will open test configuration page where we can define any inputs parameter for calling this aws lambda …

But in our can case we are not going to pass any input parameter so just enter event name and test click on save

Now Testing configuration is saved Click on Test button again it will give you result like below ..Meaning our aws lambda is working fine and now we can integrate with API routes

Integarte Lambada Function with API Gateway

There are two ways to configure lambda with API gateway route

  1. From Lambada Configuration tab

    Click on Configuration it will navigate to general configuration details

    In left menu you will find Triggers option and then click on add trigger

    From Trigger Configuration dropdown select API gateway

    After Selecting this choose Use Existing API option and choose already created “testing-Api-service”

    Select stage as $default and security and open for now

    And finally Click on Add it will integrate with already create API gateway.

  2. Navigate to your API Gateway Route and click on GET method you will see the attached integration option and click on that.

    Then you will see Create and attach an integration click on that you will navigate to integration target page

    From integration type select lambda then Integration details section will show. There you must choose AWS Region where you have already created Lambda function In lambda function dropdown select your lambda function which you want to integration with this API.

    Leave other options as default and hit on create once integration is successful it will look like this

Test AWS Serverless API

Time for Testing API Gate way Route (getProductList):

Final URL Of this route is - https://xxxxxx.execute-api.ap-xxxxxxx-1.amazonaws.com/getProductList Open Browser and paste this URL and hit enter – you will see the repose as below which coming from Aws Lambda using API gate way

Another Way Open Postman and create new Get request and paste this URL and see the result

Monday, February 6, 2023

How to Change - Jupyter Notebook (Anaconda3) Startup Directory / Folder - Windows

Jupyter Notebook has default startup directory, In most of the case after installation it's starting directory is under the user folder. If you want to change this default location to any user defined folder in any drive like "D:/MyAllNotebook/" you can follow the below easy steps too change it.

Step 1:

Click on start menu and type "Jupyter", you will see the jupyter App icon like below -

Step 2:

Right Click on Jupyter App Icon and choose "Open file location", It will open file explorer below

Step 3:

Select Jupyter Notebook file and right click and select property option. It will open property dialog box.

In target edit box you can see the text like "%USERPROFILE%/"

Replace this "%USERPROFILE%/" text to your desire path like this "D:/MyAllNotebook/"

Step 4:

Restart Jupyter Notebook App again - Now it will land to your specified location like below

Saturday, January 21, 2023

.Net Core Console Application As Windows Service - Background Activity

We can convert our .Net Core Console Application into regular Windows Service by using third party library like TopShelf, Quartz and for logging  we can utilize NLog.

Windows Service is mainly used when you want a regular running process in the background that do some activity behind the seen. 

Lets try to convert .Net Core Console Application to Windows Service. 


Open Visula Studio 2019 - > Go to New Project -> Select .Net Core(Console) template and Create project

We have to include maily two library

  • Topshelf
  • Quartz

Topshelf

Topshelf is use to initialies HostFactory Like Below

	
        var services = ServiceDependency.ConfigureServices();
        var serviceProvider = services.BuildServiceProvider();

        var rc = HostFactory.Run(x =>
        {
            x.Service(s =>
            {
                s.ConstructUsing(name => serviceProvider.GetService());
                s.WhenStarted(tc => tc.Start());
                s.WhenStopped(tc => tc.Stop());
            });
            x.RunAsLocalSystem();

            x.SetDescription("Windows Service Demo");
            x.SetDisplayName("WinServiceDemo");
            x.SetServiceName("WinServiceDemo");
        });

        var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode());
        Environment.ExitCode = exitCode;

	

Quartz

Quart Library is used to Schedule services like below

	
           public JobTrigger GetCommonJob()
    {

        ReportProcessorJobKey = JobKey.Create("CommonJob", "CommonJob");

        var job = JobBuilder.Create().WithIdentity("CommonJob", "CommonJob").Build();
        int ConfigFrequency;
        int frequency = int.TryParse(ConfigurationManager.AppSettings["CommonJobFrequencyInSecond"], out ConfigFrequency) ? ConfigFrequency : 5;
        var jobTrigger = TriggerBuilder.Create()
            .WithSimpleSchedule(x => x.WithIntervalInSeconds(frequency).RepeatForever())
            .Build();

        return new JobTrigger { Job = job, Trigger = jobTrigger };
    }

	

For Source Code : You can follow the below Link

The Complete Source Code Example is availabe on below link ..

Download

Tuesday, December 27, 2022

Triggering/Calling Azure Data Factory Pipeline from Console/Windows Application (C#/.Net)

Azure data Factory has proper way of calling/triggering pipeline through different types of triggers like http, scheduled on specific time, event base trigger

message base trigger, manual trigger from Azure Portal. But in some scenario we required to call ADF pipeline as on demand basis through your application.

In that scenario Microsoft Azure has provided rich libraries in different language to achieve same activity.

Here I am presenting very easy way to trigger Azure data factory pipeline through code (C#/Net)

Prerequisite

Azure Details

.Net Supporting Library

  • Microsoft.Azure.Management.DataFactory;
  • Microsoft.Rest;
  • Microsoft.IdentityModel.Clients.ActiveDirectory;
  • System.Threading.Tasks;

AzureDataFactoryModel.cs


using System;
using System.Collections.Generic;
using System.Text;

namespace TriggerADFPipeline
{
    public class AzureDataFactoryModel
    {

        public AzureDataFactoryModel()
        {
            if (Parameters == null)
            {
                Parameters = new Dictionary();
            }
        }
        public Dictionary Parameters { get; set; }

        public string ResourceGroupName { get; set; }
        public string FactoryName { get; set; }
        public string PipeLineName { get; set; }

    }
}

ADFHelper.cs


using Microsoft.Azure.Management.DataFactory;
using Microsoft.Rest;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Threading.Tasks;

namespace TriggerADFPipeline
{
    public class ADFHelper
    {
        private TokenCredentials _tokenCredential;
        private DataFactoryManagementClient _dataFactoryClient;

        private readonly string tenantId = "xxxx";
        private readonly string clientId = "xxxx";
        private readonly string clientSecret = "xxxx";
        private readonly string subscriptionId = "xxxx";
        private readonly string windowsManagementUri = "https://management.core.windows.net/";
        private readonly string activeDirectoryEndpoint = "https://login.windows.net/";
        public ADFHelper()
        {
            AuthenticateUser();
            SetupClient();
        }

        private void AuthenticateUser()
        {
            var authority = new Uri(new Uri(activeDirectoryEndpoint), this.tenantId);
            var context = new AuthenticationContext(authority.AbsoluteUri);
            var credential = new ClientCredential(this.clientId, this.clientSecret);

            _tokenCredential = new TokenCredentials(context.AcquireTokenAsync(windowsManagementUri, credential).Result.AccessToken);
        }
        private void SetupClient()
        {
            _dataFactoryClient = new DataFactoryManagementClient(_tokenCredential) { SubscriptionId = subscriptionId };
        }

        
        public async Task TriggerAdfAsync(AzureDataFactoryModel azureDataFactoryModel)
        {
            try
            {
                
                var runResponse = await _dataFactoryClient.Pipelines.CreateRunWithHttpMessagesAsync(
                                                           azureDataFactoryModel.ResourceGroupName,
                                                           azureDataFactoryModel.FactoryName,
                                                          azureDataFactoryModel.PipeLineName,
                                                           parameters: azureDataFactoryModel.Parameters
                ).ConfigureAwait(false);
              
                return runResponse.Body.RunId;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }

    }
}

Program.cs


using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace TriggerADFPipeline
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello I am Calling ADF pipeline from C#....");
            ADFHelper _azureDataFactory = new ADFHelper();
            AzureDataFactoryModel azureDataFactoryModel = new AzureDataFactoryModel();
            azureDataFactoryModel.ResourceGroupName = "xxxx";
            azureDataFactoryModel.FactoryName = "xxxx";
            azureDataFactoryModel.PipeLineName = "xxxx";
            azureDataFactoryModel.Parameters = new Dictionary<string, object>
            {
                { "P1", "parameter 1"},
                { "P2", "parameter 2"},
                { "P3", "parameter 3"}
            };
            var runId = _azureDataFactory.TriggerAdfAsync(azureDataFactoryModel).ConfigureAwait(false);
            Console.WriteLine($"Run Id : {runId}");
        }

    }
}

Download Source Code

ADF Trigger

How to Delete your Blog from Blogger - Permanently

If you want to delete your blog permanently, follow the steps

Login to you blogger account select blog which you want to delete from


Go to setting menu



Scroll down to Manage Blog section



There you find "Remove your blog" option , Click on this link it will give you a warning pop up like this



 

If you want to take backup of your content click on Download Blog Link.

For deleting blog Click on Delete ..

It will redirect to next page ..

 



From here you can delete permanently or undelete.                     

Once click on Permanent delete, it will prompt another warning like this



Click on permanent delete and you are done


Tuesday, July 2, 2019

Azure Service Bus - Message-based Communication Workflows

Introduction

Application being develop frequently  now a days which consist of different parts executing on separate computers and devices, which are in different location around the world. The main concern with these distributed application is how to communicate reliably between the components of a distributed application. we can use azure messaging to deliver the same.

Azure Service bus is a type of messaging system. Its main function is to provide interaction between application and services. It is a multi-tenant cloud messaging service.

In this blog we gonna learn how Azure Service Bus can help build an application that stays reliable during high demand.

Common Messaging Scenarios

  • Messaging: transfer business data, such as sales or purchase orders, journals, or inventory movements.
  • Decouple applications: improve reliability and scalability of applications and services (client and service do not have to be online at the same time).
  • Topics and subscriptions: enable 1:n relationships between publishers and subscribers.
  • Message sessions: implement workflows that require message ordering or message deferral.

Azure Messaging Services Selections

Azure provides three type of messaging service for delivering event messages throughout the solutions.
  • Event Grid
  • Event Hubs
  • Service Bus

Event Grid

It uses a publish-subscribe model. Publishers emit events, but have no expectation about which events are handled. Subscribers decide which events they want to handle. Event Grid isn't a data pipeline, and doesn't deliver the actual object that was updated.

Characteristics:
  • Dynamically scalable
  • Low cost
  • Serverless
  • At least once delivery

Event Hubs

Azure Event Hubs is a big data pipeline. It provides services to capture, retention, replay of telemetry and event stream data. The data can come from many concurrent sources. Event Hubs allows telemetry and event data to be made available to a variety of stream-processing infrastructures and analytics services. It is available either as data streams or bundled event batches. This service provides a single solution that enables rapid data retrieval for real-time processing as well as repeated replay of stored raw data. It can capture the streaming data into a file for processing and analysis.

Characteristics:
  • Low latency
  • Capable of receiving and processing millions of events per second
  • At least once delivery

Service Bus

Service Bus enables cloud-native applications to provide reliable state transition management for business processes. When handling high-value messages that cannot be lost or duplicated, use Azure Service Bus. Service Bus also facilitates highly secure communication across hybrid cloud solutions and can connect existing on-premises systems to cloud solutions.

Service Bus is a brokered messaging system. It stores messages in a "broker" (for example, a queue) until the consuming party is ready to receive the messages.

Characteristics:
  • Reliable asynchronous message delivery (enterprise messaging as a service) that requires polling
  • Advanced messaging features like FIFO, batching/sessions, transactions, dead-lettering, temporal control, routing and filtering, and duplicate detection
  • At least once delivery
  • Optional in-order delivery

Service Bus Learning objectives

  • Choose whether to use Service Bus queues, topics, or relays to communicate in a distributed application
  • Create a Service Bus queue and use it to send and receive messages
  • Create a Service Bus topic and use it to send and receive messages

Service Bus topics, queues, and relays

Azure Service Bus can exchange messages in three different ways: queues, topics, and relays.

Queue:

A queue is a simple temporary storage location for messages. A sending component adds a message to the queue. A destination component picks up the message at the front of the queue. Under ordinary circumstances, each message is received by only one receiver.

image url

During peak times, messages may come in faster than destination components can handle them. Because source components have no direct connection to the destination, the source is unaffected and the queue will grow. Destination components will remove messages from the queue as they are able to handle them. When demand drops, destination components can catch up and the queue shortens.

Topic:

A topic is similar to a queue but can have multiple subscriptions. This means that multiple destination components can subscribe to a single topic, so each message is delivered to multiple receivers. Subscriptions can also filter the messages in the topic to receive only messages that are relevant. Subscriptions provide the same decoupled communications as queues and respond to high demand in the same way. Use a topic if you want each message to be delivered to more than one destination component.
image url

Relay:

A relay is an object that performs synchronous, two-way communication between applications. Unlike queues and topics, it is not a temporary storage location for messages. Instead, it provides bidirectional, unbuffered connections across network boundaries such as firewalls. Use a relay when you want direct communications between components as if they were located on the same network segment but separated by network security devices.

Send messages to the queue

Launch Visual Studio and create a new Console App (.NET Core) project.

Add the Service Bus NuGet package

  1. Right-click the newly created project and select Manage NuGet Packages.
  2. Click the Browse tab, search for Microsoft.Azure.ServiceBus, and then select the Microsoft.Azure.ServiceBus item. Click Install to complete the installation, then close this dialog box.
image url

Write code to send messages to the queue

 
 namespace CoreSenderApp
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;

    class Program
    {
        // Connection String for the namespace can be obtained from the Azure portal under the 
        // 'Shared Access policies' section.
        const string ServiceBusConnectionString = "";
        const string QueueName = "";
        static IQueueClient queueClient;

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }

        static async Task MainAsync()
        {
            const int numberOfMessages = 10;
            queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

            Console.WriteLine("======================================================");
            Console.WriteLine("Press ENTER key to exit after sending all the messages.");
            Console.WriteLine("======================================================");

            // Send Messages
            await SendMessagesAsync(numberOfMessages);

            Console.ReadKey();

            await queueClient.CloseAsync();
        }

        static async Task SendMessagesAsync(int numberOfMessagesToSend)
        {
            try
            {
                for (var i = 0; i < numberOfMessagesToSend; i++)
                {
                    // Create a new message to send to the queue
                    string messageBody = $"Message {i}";
                    var message = new Message(Encoding.UTF8.GetBytes(messageBody));

                    // Write the body of the message to the console
                    Console.WriteLine($"Sending message: {messageBody}");

                    // Send the message to the queue
                    await queueClient.SendAsync(message);
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
            }
        }
    }
}
 
 

Receive messages from the queue

To receive the messages you sent, create another .NET Core console application and install the Microsoft.Azure.ServiceBus NuGet package, similar to the previous sender application.

namespace CoreReceiverApp
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;

    class Program
    {
        // Connection String for the namespace can be obtained from the Azure portal under the
        // 'Shared Access policies' section.
        const string ServiceBusConnectionString = "";
        const string QueueName = "";
        static IQueueClient queueClient;

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }

        static async Task MainAsync()
        {
            queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

            Console.WriteLine("======================================================");
            Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
            Console.WriteLine("======================================================");

            // Register QueueClient's MessageHandler and receive messages in a loop
            RegisterOnMessageHandlerAndReceiveMessages();

            Console.ReadKey();

            await queueClient.CloseAsync();
        }

        static void RegisterOnMessageHandlerAndReceiveMessages()
        {
         
            var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
            {
             
                MaxConcurrentCalls = 1,             
                AutoComplete = false
            };

            // Register the function that will process messages
            queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
        }

        static async Task ProcessMessagesAsync(Message message, CancellationToken token)
        {
            // Process the message
            Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}");
         
            await queueClient.CompleteAsync(message.SystemProperties.LockToken);
       
        }

        static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
        {
            Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
            var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
            Console.WriteLine("Exception context for troubleshooting:");
            Console.WriteLine($"- Endpoint: {context.Endpoint}");
            Console.WriteLine($"- Entity Path: {context.EntityPath}");
            Console.WriteLine($"- Executing Action: {context.Action}");
            return Task.CompletedTask;
        }
    }
}


Send messages to the topic

Launch Visual Studio and create a new Console App (.NET Core) project.

Add the Service Bus NuGet package


  • Right-click the newly created project and select Manage NuGet Packages.
  • Click the Browse tab, search for Microsoft.Azure.ServiceBus, and then select the Microsoft.Azure.ServiceBus item. Click Install to complete the installation, then close this dialog box.

image url

Write code to send messages to the topic


namespace CoreSenderApp
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;

    class Program
    {
        const string ServiceBusConnectionString = "";
        const string TopicName = "";
        static ITopicClient topicClient;

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }

        static async Task MainAsync()
        {
            const int numberOfMessages = 10;
            topicClient = new TopicClient(ServiceBusConnectionString, TopicName);

            Console.WriteLine("======================================================");
            Console.WriteLine("Press ENTER key to exit after sending all the messages.");
            Console.WriteLine("======================================================");

            // Send messages.
            await SendMessagesAsync(numberOfMessages);

            Console.ReadKey();

            await topicClient.CloseAsync();
        }

        static async Task SendMessagesAsync(int numberOfMessagesToSend)
        {
            try
            {
                for (var i = 0; i < numberOfMessagesToSend; i++)
                {
                    // Create a new message to send to the topic
                    string messageBody = $"Message {i}";
                    var message = new Message(Encoding.UTF8.GetBytes(messageBody));

                    // Write the body of the message to the console
                    Console.WriteLine($"Sending message: {messageBody}");

                    // Send the message to the topic
                    await topicClient.SendAsync(message);
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
            }
        }
    }
}

Receive messages from the subscription

To receive the messages you sent, create another .NET Core console application and install the Microsoft.Azure.ServiceBus NuGet package, similar to the previous sender application.

Write code to receive messages from the subscription


namespace CoreReceiverApp
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;

    class Program
    {
        const string ServiceBusConnectionString = "";
        const string TopicName = "";
        const string SubscriptionName = "";
        static ISubscriptionClient subscriptionClient;

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }

        static async Task MainAsync()
        {
            subscriptionClient = new SubscriptionClient(ServiceBusConnectionString, TopicName, SubscriptionName);

            Console.WriteLine("======================================================");
            Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
            Console.WriteLine("======================================================");

            // Register subscription message handler and receive messages in a loop.
            RegisterOnMessageHandlerAndReceiveMessages();

            Console.ReadKey();

            await subscriptionClient.CloseAsync();
        }

        static void RegisterOnMessageHandlerAndReceiveMessages()
        {
          
            var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
            {
                MaxConcurrentCalls = 1,
                AutoComplete = false
            };

            // Register the function that processes messages.
            subscriptionClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
        }

        static async Task ProcessMessagesAsync(Message message, CancellationToken token)
        {
            // Process the message.
            Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}");
           
            await subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);

        }

        static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
        {
            Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
            var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
            Console.WriteLine("Exception context for troubleshooting:");
            Console.WriteLine($"- Endpoint: {context.Endpoint}");
            Console.WriteLine($"- Entity Path: {context.EntityPath}");
            Console.WriteLine($"- Executing Action: {context.Action}");
            return Task.CompletedTask;
        }
    }
}

Popular Articles