public static async void Run([BlobTrigger(route, Connection = ConfigSettings.STORAGE_CONNECTIONSTRING_NAME)] CloudBlockBlob blockBlob, string name, ILogger log)
        {
            await blockBlob.FetchAttributesAsync();

            log.LogInformation("[PENDING] Checking for required metadata on job entry...");
            if (blockBlob.Metadata.ContainsKey(ConfigSettings.JOBID_METADATA_NAME) && blockBlob.Metadata.ContainsKey(ConfigSettings.IMAGE_CONVERSION_MODE_METADATA_NAME) && blockBlob.Metadata.ContainsKey(ConfigSettings.IMAGE_SOURCE_METADATA_NAME))
            {
                log.LogInformation("[SUCCESS] job entry contains required metadata");

                string jobId = blockBlob.Metadata[ConfigSettings.JOBID_METADATA_NAME];

                string imageConversionMode = blockBlob.Metadata[ConfigSettings.IMAGE_CONVERSION_MODE_METADATA_NAME];

                string imageSource = blockBlob.Metadata[ConfigSettings.IMAGE_SOURCE_METADATA_NAME];

                log.LogInformation("[PENDING] Connecting to jobs table...");
                JobTable jobTable = new JobTable(log, ConfigSettings.IMAGEJOBS_PARTITIONKEY);
                log.LogInformation("[SUCCESS] Connected to Jobs Table");

                string imageResult = $"{Environment.GetEnvironmentVariable(ConfigSettings.STORAGE_DOMAIN_METADATA_NAME)}/{ConfigSettings.CONVERTED_IMAGES_CONTAINER_NAME}/{name}";

                JobEntity successJobEntity = JobEntity.New(jobId, imageConversionMode, JobStatusCodes.CONVERT_SUCCESS, JobStatusMessages.CONVERT_SUCCESS, imageSource, imageResult);

                log.LogInformation("[PENDING] Updating job entry with success status...");
                await jobTable.UpdateJobEntityStatus(successJobEntity);

                log.LogInformation("[SUCCESS] Job entry updated with success status");
            }
            else
            {
                log.LogError("The specified job does not contain the required metadata and cannot be updated.");
            }
        }
        public static ActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "jobs")] HttpRequest req, ILogger log)
        {
            log.LogInformation("[PENDING] Connecting to jobs table...");
            JobTable jobTable = new JobTable(log, ConfigSettings.IMAGEJOBS_PARTITIONKEY);

            log.LogInformation("[SUCCESS] Connected to Jobs Table");

            log.LogInformation("[PENDING] Getting all job entities...");
            List <JobEntityResponse> jobEntityList = jobTable.RetrieveAllJobEntities();

            log.LogInformation("[SUCCESS] Retrieved all job entities");

            return(new OkObjectResult(jobEntityList));
        }
        public static async Task <IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "jobs/{id}")] HttpRequest req, string id, ILogger log)
        {
            if (string.IsNullOrEmpty(id))
            {
                return(new BadRequestObjectResult("The query string id is required"));
            }

            if (id.Length > 36)
            {
                return(new BadRequestObjectResult("An id cannot be greater than 36 characters"));
            }

            log.LogInformation("[PENDING] Connecting to jobs table...");
            JobTable jobTable = new JobTable(log, ConfigSettings.IMAGEJOBS_PARTITIONKEY);

            log.LogInformation("[SUCCESS] Connected to Jobs Table");

            log.LogInformation("[PENDING] Searching for Job Entity {id}...");
            JobEntity jobEntity = await jobTable.RetrieveJobEntity(id);

            if (jobEntity == null)
            {
                log.LogError("Job Entity {id} was not found");

                ErrorResponse errorResponse = ErrorResponse.New(ErrorResponseCodes.NOT_FOUND, "JobId", id, ErrorResponseMessages.NOT_FOUND);

                return(new NotFoundObjectResult(errorResponse));
            }

            log.LogInformation("[SUCCESS] Job Entity {id} was found");

            JobEntityResponse jobEntityResponse = JobEntityResponse.New(
                jobEntity.RowKey, jobEntity.ImageConversionMode, jobEntity.Status, jobEntity.StatusDescription, jobEntity.ImageSource, jobEntity.ImageResult);

            return(new OkObjectResult(jobEntityResponse));
        }
        public static void Run([TimerTrigger("*/2 * * * *")] TimerInfo myTimer, ILogger log)
        {
            log.LogInformation("[PENDING] Connecting to jobs table...");
            JobTable jobTable = new JobTable(log, ConfigSettings.IMAGEJOBS_PARTITIONKEY);

            log.LogInformation("[SUCCESS] Connected to Jobs Table");


            log.LogInformation("[PENDING] Searching for successful jobs...");
            List <JobEntity> jobEntityList = jobTable.RetrieveAllSuccessJobEntities();

            log.LogInformation("[SUCCESS] Successful jobs found");


            log.LogInformation("[PENDING] Connecting to blob storage...");
            BlobStorage blobStorage = new BlobStorage();

            log.LogInformation("[SUCCESS] Connected to blob storage");


            log.LogInformation("[PENDING] Deleting successful jobs...");
            blobStorage.DeleteConvertedImages(jobEntityList);
            log.LogInformation("[SUCCESS] Successful jobs deleted");
        }