public async Task NotifyRegisteredOwner(
            [EventGridTrigger] EventGridEvent eventGridEvent,
            ILogger logger
            )
        {
            StorageBlobCreatedEventData blobCreatedEventData =
                ((JObject)eventGridEvent.Data).ToObject <StorageBlobCreatedEventData>();

            string blobName = BlobHelper.GetBlobName(blobCreatedEventData.Url);

            #region Logging

            logger.LogInformation(
                new EventId((int)LoggingConstants.EventId.NotifyVehicleOwnerStarted),
                LoggingConstants.Template,
                LoggingConstants.EventId.NotifyVehicleOwnerStarted.ToString(),
                blobName,
                LoggingConstants.ProcessingFunction.NotifyRegisteredOwner.ToString(),
                LoggingConstants.ProcessStatus.Started.ToString(),
                "Execution Started"
                );

            #endregion


            try
            {
                var speedingTicket = await _dmvDbHandler
                                     .GetSpeedingTicketInfoAsync(blobName)
                                     .ConfigureAwait(false);

                var registeredOwnerInfo = await _dmvDbHandler
                                          .GetOwnerInformationAsync(
                    vehicleRegistrationNumber : speedingTicket.VehicleResgistrationNumber)
                                          .ConfigureAwait(false);

                var infractionImage = await _blobHandler
                                      .DownloadBlobAsync(blobCreatedEventData.Url)
                                      .ConfigureAwait(false);


                var attachments = new List <OwnerNotificationMessageAttachment>
                {
                    new OwnerNotificationMessageAttachment
                    {
                        Name        = speedingTicket.TicketNumber,
                        Content     = Convert.ToBase64String(infractionImage),
                        ContentType = "image/jpeg"
                    }
                };

                var notificationMessage =
                    CreateNotificationMessage
                    (
                        vehicleOwnerInfo: registeredOwnerInfo,
                        attachments: attachments,
                        ticketNumber: speedingTicket.TicketNumber,
                        infractionDate: speedingTicket.Date,
                        infractionDistrict: speedingTicket.District
                    );

                await _ownerNotificationHandler
                .NotifyOwnerAsync(notificationMessage)
                .ConfigureAwait(false);

                #region Logging

                logger.LogInformation(
                    new EventId((int)LoggingConstants.EventId.NotifyVehicleOwnerFinished),
                    LoggingConstants.Template,
                    LoggingConstants.EventId.NotifyVehicleOwnerFinished.ToString(),
                    blobName,
                    LoggingConstants.ProcessingFunction.NotifyRegisteredOwner.ToString(),
                    LoggingConstants.ProcessStatus.Finished.ToString(),
                    "Execution Finished"
                    );

                #endregion
            }
            catch (Exception ex)
            {
                CustomEventData customEventData = new CustomEventData
                {
                    ImageUrl = blobCreatedEventData.Url,

                    CustomEvent = CustomEvent.Exceptioned.ToString()
                };

                await _eventHandler.PublishEventToTopicAsync(customEventData)
                .ConfigureAwait(false);

                #region Logging

                logger.LogInformation(
                    new EventId((int)LoggingConstants.EventId.NotifyVehicleOwnerFinished),
                    LoggingConstants.Template,
                    LoggingConstants.EventId.NotifyVehicleOwnerFinished.ToString(),
                    blobName,
                    LoggingConstants.ProcessingFunction.NotifyRegisteredOwner.ToString(),
                    LoggingConstants.ProcessStatus.Failed.ToString(),
                    $"Execution Failed. Reason: {ex.Message}"
                    );

                #endregion
            }
        }
        public async Task DetectAndBlurFaces(
            [EventGridTrigger] EventGridEvent eventGridEvent,
            ILogger logger
            )
        {
            CustomEventData inputEventData =
                ((JObject)eventGridEvent.Data).ToObject <CustomEventData>();

            var correlationId = LoggingHelper.GetCorrelationId(inputEventData);

            #region Logging

            logger.LogInformation(
                new EventId((int)LoggingConstants.EventId.DetectAndBlurFacesStarted),
                LoggingConstants.Template,
                LoggingConstants.EventId.DetectAndBlurFacesStarted.ToString(),
                correlationId,
                LoggingConstants.ProcessingFunction.DetectAndBlurFaces.ToString(),
                LoggingConstants.ProcessStatus.Started,
                "Execution Started"
                );

            #endregion

            CustomEventData outputEventData = new CustomEventData
            {
                ImageUrl             = inputEventData.ImageUrl,
                TicketNumber         = inputEventData.TicketNumber,
                DistrictOfInfraction = inputEventData.DistrictOfInfraction,
                DateOfInfraction     = inputEventData.DateOfInfraction
            };

            try
            {
                var detectedFaces = await _faceHandler
                                    .DetectFacesWithUrlAsync(inputEventData.ImageUrl)
                                    .ConfigureAwait(false);

                var imageBytes = await _blobHandler
                                 .DownloadBlobAsync(inputEventData.ImageUrl)
                                 .ConfigureAwait(false);

                var blurredImageBytes = await _faceHandler
                                        .BlurFacesAsync(imageBytes, detectedFaces.ToList());

                using (MemoryStream ms = new MemoryStream(blurredImageBytes))
                {
                    await _blobHandler.UploadStreamAsBlobAsync(
                        containerName : _options.BlurredImageContainerName,
                        stream : ms,
                        contentType : _options.UploadContentType,
                        blobName : BlobHelper.GetBlobNameWithExtension(inputEventData.TicketNumber)
                        )
                    .ConfigureAwait(false);
                }

                outputEventData.CustomEvent = CustomEvent.FaceDetectionAndBlurringCompleted.ToString();

                #region Logging

                logger.LogInformation(
                    new EventId((int)LoggingConstants.EventId.DetectAndBlurFacesFinished),
                    LoggingConstants.Template,
                    LoggingConstants.EventId.DetectAndBlurFacesFinished.ToString(),
                    correlationId,
                    LoggingConstants.ProcessingFunction.DetectAndBlurFaces.ToString(),
                    LoggingConstants.ProcessStatus.Finished,
                    "Execution Finished"
                    );

                #endregion
            }
            catch (Exception ex)
            {
                outputEventData.CustomEvent = CustomEvent.Exceptioned.ToString();

                #region Logging

                logger.LogInformation(
                    new EventId((int)LoggingConstants.EventId.DetectAndBlurFacesFinished),
                    LoggingConstants.Template,
                    LoggingConstants.EventId.DetectAndBlurFacesFinished.ToString(),
                    correlationId,
                    LoggingConstants.ProcessingFunction.DetectAndBlurFaces.ToString(),
                    LoggingConstants.ProcessStatus.Failed,
                    $"Execution Failed. Reason: {ex.Message}"
                    );

                #endregion
            }


            await _eventhandler.PublishEventToTopicAsync(outputEventData)
            .ConfigureAwait(false);
        }