public static async Task Run([BlobTrigger(Constants.FailureOutputContainerName + "/{name}", Connection = Constants.AzureStorageConnectionStringEntry)] CloudBlockBlob cloudBlockBlob, string name, ILogger log)
        {
            log.LogInformation("Running ImageStatusUpdaterFailed");

            await cloudBlockBlob.FetchAttributesAsync();

            if (cloudBlockBlob.Metadata.ContainsKey(Constants.JobIdMetaData))
            {
                string jobId = cloudBlockBlob.Metadata[Constants.JobIdMetaData];

                log.LogInformation($"Found unsuccessfully converted blob {cloudBlockBlob.Name} with JobId {jobId}");
                try
                {
                    Jobs.JobsTable jobTable = new Jobs.JobsTable();
                    await jobTable.UpdateJobStatus(jobId, Jobs.JobStatusCode.Failure, null, cloudBlockBlob.Uri.AbsoluteUri);

                    log.LogInformation($"Successfully updated JobId {jobId} to status Failure");
                }
                catch (Exception ex)
                {
                    log.LogError($"Could not update status of jobId: {jobId}: {ex.Message}");
                }
            }
            else
            {
                log.LogError($"Error: {cloudBlockBlob.Name} has no {Constants.JobIdMetaData} metadata key.");
            }
        }
        public static async Task Run([TimerTrigger("0 */2 * * * *")] TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"Cleanup starting at: {DateTime.Now}");

            Jobs.JobsTable  jobTable    = new Jobs.JobsTable();
            List <Jobs.Job> jobsToClean = (await jobTable.RetrieveAllJobs())
                                          .Where(j => j.status == (int)Jobs.JobStatusCode.Success && j.imageSource != null)
                                          .ToList();

            log.LogInformation($"Found {jobsToClean.Count} successful conversion jobs to clean up");

            CloudStorageAccount storageAccount = Access.GetCloudStorageAccount();
            await Task.WhenAll(
                jobsToClean.Select(j =>
            {
                CloudBlockBlob blob = new CloudBlockBlob(new Uri(j.imageSource), storageAccount.Credentials);
                return(blob.DeleteIfExistsAsync()
                       // Then update table to have no image source
                       .ContinueWith(c => {
                    j.imageSource = null;
                    return jobTable.UpdateJob(j);
                }));
            })
                );
        }
Exemplo n.º 3
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "v1/jobs")] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("Getting status of all jobs");

            try
            {
                Jobs.JobsTable jobTable = new Jobs.JobsTable();
                return(new OkObjectResult(
                           (await jobTable.RetrieveAllJobs())
                           .ConvertAll <DTOJobStatus>(j => new DTOJobStatus(j))
                           .ToList()
                           ));
            }
            catch (Exception ex)
            {
                log.LogError($"Unable to retrieve jobs from job table: {ex.Message}");
                return(new OkObjectResult(new List <DTOJobStatus>()));
            }
        }
Exemplo n.º 4
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "v1/jobs/{id}")] HttpRequest req,
            string id,
            ILogger log)
        {
            log.LogInformation($"Getting status of job {id}");

            try
            {
                Jobs.JobsTable jobTable = new Jobs.JobsTable();
                return(new OkObjectResult(
                           new DTOJobStatus(
                               await jobTable.RetrieveJob(id)
                               )
                           ));
            }
            catch (Exception ex)
            {
                log.LogError($"Unable to retrieve job {id}: {ex.Message}");
                return(new NotFoundObjectResult(new ErrorResponse(ErrorCode.NotFound, "id", id)));
            }
        }
        public static async Task Run([BlobTrigger(Constants.GreyScaleInputContainerName + "/{name}", Connection = Constants.AzureStorageConnectionStringEntry)] CloudBlockBlob cloudBlockBlob, string name, ILogger log)
        {
            log.LogInformation("Running ImageConsumerGreyScale");
            string convertedBlobName = $"{Guid.NewGuid().ToString()}-{name}";
            string jobId             = Guid.NewGuid().ToString();

            log.LogInformation($"Associations: Converted Name: {convertedBlobName}, JobId: {jobId}");

            // Add job to jobs table
            // (if fails, will not put image into failure container
            Jobs.JobsTable jobTable = new Jobs.JobsTable();
            await jobTable.InsertOrReplaceJob(new Jobs.Job(
                                                  jobId,
                                                  Constants.GreyScaleMode,
                                                  Jobs.JobStatusCode.Received,
                                                  cloudBlockBlob.Uri.AbsoluteUri
                                                  ));


            // Try to open image
            // (if can't open, then no way we can put it in failure container!)
            using (Stream blobStream = await cloudBlockBlob.OpenReadAsync())
            {
                try {
                    // Try to get output container
                    // (if fails, will try to put image in failure container)
                    // (doing now so we can fail early if something is wrong!)
                    CloudBlobContainer successContainer = Access.GetSuccessOutputContainer();
                    await successContainer.CreateIfNotExistsAsync();

                    // Update job status to converting
                    // (if fails, will log and still try to convert image)
                    try
                    {
                        await jobTable.UpdateJobStatus(jobId, Jobs.JobStatusCode.Converting);
                    } catch (Exception ex)
                    {
                        log.LogError($"Could not update status of jobId: {jobId}: {ex.Message}");
                    }

                    // Try to convert and upload
                    // (if fails, will try to put image in failure container)
                    blobStream.Seek(0, SeekOrigin.Begin);
                    using (MemoryStream convertedMemoryStream = new MemoryStream())
                        using (Image <Rgba32> image = Image.Load(blobStream)) {
                            log.LogInformation($"Starting conversion of image {convertedBlobName}");

                            image.Mutate(x => x.Grayscale());
                            image.SaveAsJpeg(convertedMemoryStream);

                            convertedMemoryStream.Seek(0, SeekOrigin.Begin);

                            log.LogInformation($"Completed conversion of image {convertedBlobName}");
                            log.LogInformation($"Storing image {convertedBlobName} into {Constants.SuccessOutputContainerName} container");

                            // Upload to success container
                            CloudBlockBlob convertedBlockBlob = successContainer.GetBlockBlobReference(convertedBlobName);
                            convertedBlockBlob.Metadata.Add(Constants.JobIdMetaData, jobId);
                            convertedBlockBlob.Properties.ContentType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
                            await convertedBlockBlob.UploadFromStreamAsync(convertedMemoryStream);

                            log.LogInformation($"Stored image {convertedBlobName} into {Constants.SuccessOutputContainerName} container");
                        }
                } catch (Exception ex) {
                    log.LogError($"Failed to convert blob {name}. {ex.Message}");
                    log.LogInformation($"Storing image {convertedBlobName} into {Constants.FailureOutputContainerName} container");
                    try {
                        // Try to get failure container
                        // (if fails, then hard fail.)
                        CloudBlobContainer failureContainer = Access.GetFailureOutputContainer();
                        await failureContainer.CreateIfNotExistsAsync();

                        // Try to upload failed image.
                        // (if fails, then hard fail)
                        CloudBlockBlob failedBlockBlob = failureContainer.GetBlockBlobReference(convertedBlobName);
                        failedBlockBlob.Metadata.Add(Constants.JobIdMetaData, jobId);
                        blobStream.Seek(0, SeekOrigin.Begin);
                        await failedBlockBlob.UploadFromStreamAsync(blobStream);

                        log.LogInformation($"Stored image {convertedBlobName} into {Constants.FailureOutputContainerName} container");
                    } catch (Exception ex2) {
                        // Hard fail.
                        log.LogError($"Failed to store blob {name} into {Constants.FailureOutputContainerName}. {ex2.Message}");
                    }
                }
            }
        }