/// <summary>
        /// Uploads a given image to the converted images container
        ///
        /// The given image should already have the desired filter applied
        /// </summary>
        /// <param name="jobEntity"></param>
        /// <param name="blobName"></param>
        /// <param name="convertedImage"></param>
        public async void UploadConvertedImage(JobEntity jobEntity, string blobName, MemoryStream convertedImage)
        {
            CloudBlobContainer convertedImagesContainer = _blobClient.GetContainerReference(ConfigSettings.CONVERTED_IMAGES_CONTAINER_NAME);
            CloudBlockBlob     convertedBlockBlob       = convertedImagesContainer.GetBlockBlobReference(blobName);

            convertedBlockBlob.Metadata.Add(ConfigSettings.JOBID_METADATA_NAME, jobEntity.JobId);
            convertedBlockBlob.Metadata.Add(ConfigSettings.IMAGE_CONVERSION_MODE_METADATA_NAME, jobEntity.ImageConversionMode);
            convertedBlockBlob.Metadata.Add(ConfigSettings.IMAGE_SOURCE_METADATA_NAME, jobEntity.ImageSource);
            convertedBlockBlob.Properties.ContentType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
            await convertedBlockBlob.UploadFromStreamAsync(convertedImage);
        }
        public static async void Run([BlobTrigger(route, Connection = ConfigSettings.STORAGE_CONNECTIONSTRING_NAME)] Stream myBlob, string name, ILogger log)
        {
            log.LogInformation("[PENDING] Connecting to blob storage...");
            BlobStorage blobStorage = new BlobStorage();

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

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

            string jobId = Guid.NewGuid().ToString();

            JobEntity initialJobEntity = JobEntity.New(jobId, ConversionModeNames.SEPIA, JobStatusCodes.IMAGE_OBTAINED, JobStatusMessages.IMAGE_OBTAINED, imageSourceURI, "");

            log.LogInformation("[PENDING] Adding initial job entry to table...");
            await Shared.UpdateJobTableWithStatus(log, initialJobEntity);

            log.LogInformation("[SUCCESS] Initial job entry added to table");

            string convertedBlobName = $"{Guid.NewGuid()}-{name}";

            try
            {
                log.LogInformation("[PENDING] Applying sepia filter to image...");
                MemoryStream convertedMemoryStream = ImageConverter.ConvertImageToSepia(myBlob);
                log.LogInformation("[SUCCESS] Applied sepia filter to image");

                JobEntity convertInProgressJobEntity = JobEntity.New(jobId, ConversionModeNames.SEPIA, JobStatusCodes.BEING_CONVERTED, JobStatusMessages.BEING_CONVERTED, imageSourceURI, "");

                log.LogInformation("[PENDING] Updating job status to conversion-in-progress");
                await Shared.UpdateJobTableWithStatus(log, convertInProgressJobEntity);

                log.LogInformation("[SUCCESS] Job status updated to conversion-in-progress");

                log.LogInformation("[PENDING] Uploading converted image to converted images container...");
                blobStorage.UploadConvertedImage(initialJobEntity, convertedBlobName, convertedMemoryStream);
                log.LogInformation("[SUCCESS] Converted image uploaded to converted images container");
            }
            catch (Exception e)
            {
                log.LogError("An error occured while converting the image");

                try
                {
                    log.LogInformation("[PENDING} Uploading original image to failed container...");
                    blobStorage.UploadFailedImage(initialJobEntity, convertedBlobName, myBlob);
                    log.LogInformation("[SUCCESS] Original image uploaded to failed container");
                }
                catch (Exception ex)
                {
                    log.LogError("Failed to upload image to failed container");
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Replace the corresponding job entity with the
        /// given job entity
        /// </summary>
        /// <param name="jobEntity"></param>
        /// <returns></returns>
        public async Task <bool> UpdateJobEntity(JobEntity jobEntity)
        {
            TableOperation replaceOperation = TableOperation.Replace(jobEntity);
            TableResult    result           = await _table.ExecuteAsync(replaceOperation);

            if (result.HttpStatusCode > 199 && result.HttpStatusCode < 300)
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Uploads a given image to the failed images container
        ///
        /// The given image is expected to be the original source
        /// </summary>
        /// <param name="jobEntity"></param>
        /// <param name="blobName"></param>
        /// <param name="originalImage"></param>
        public async void UploadFailedImage(JobEntity jobEntity, string blobName, Stream originalImage)
        {
            CloudBlobContainer failedImagesContainer = _blobClient.GetContainerReference(ConfigSettings.FAILED_IMAGES_CONTAINER_NAME);
            CloudBlockBlob     failedBlobBlock       = failedImagesContainer.GetBlockBlobReference(blobName);

            failedBlobBlock.Metadata.Add(ConfigSettings.JOBID_METADATA_NAME, jobEntity.JobId);
            failedBlobBlock.Metadata.Add(ConfigSettings.IMAGE_CONVERSION_MODE_METADATA_NAME, jobEntity.ImageConversionMode);
            failedBlobBlock.Metadata.Add(ConfigSettings.IMAGE_SOURCE_METADATA_NAME, jobEntity.ImageSource);

            originalImage.Seek(0, SeekOrigin.Begin);
            await failedBlobBlock.UploadFromStreamAsync(originalImage);
        }
        /// <summary>
        /// Updates the job entity status.
        /// </summary>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="status">The status.</param>
        /// <param name="message">The message.</param>
        /// <param name="imageResult">The url string for the converted/failed image.</param>
        public async Task UpdateJobEntityStatus(string jobId, int status, string message, string imageResult)
        {
            JobEntity jobEntityToReplace = await RetrieveJobEntity(jobId);

            if (jobEntityToReplace != null)
            {
                jobEntityToReplace.status            = status;
                jobEntityToReplace.statusDescription = message;
                jobEntityToReplace.imageResult       = imageResult;
                await UpdateJobEntity(jobEntityToReplace);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Updates the status of a job entity
        /// </summary>
        /// <param name="jobId"></param>
        /// <param name="status"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task UpdateJobEntityStatus(JobEntity jobEntity)
        {
            JobEntity jobEntityToReplace = await RetrieveJobEntity(jobEntity.JobId);

            if (jobEntityToReplace != null)
            {
                jobEntityToReplace.ImageConversionMode = jobEntity.ImageConversionMode;
                jobEntityToReplace.Status            = jobEntity.Status;
                jobEntityToReplace.StatusDescription = jobEntity.StatusDescription;
                jobEntityToReplace.ImageSource       = jobEntity.ImageSource;
                jobEntityToReplace.ImageResult       = jobEntity.ImageResult;
                await UpdateJobEntity(jobEntityToReplace);
            }
        }
        /// <summary>
        /// Inserts the or replace job entity.
        /// </summary>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="status">The status.</param>
        /// <param name="message">The message.</param>
        /// <param name="imageSource">The url string for the uploaded image.</param>
        /// <param name="imageConversionMode">The type of conversion to be processed.</param>
        public async Task InsertOrReplaceJobEntity(string jobId, int status, string message, string imageSource, string imageConversionMode)
        {
            // Map parameters to JobEntity attributes
            JobEntity jobEntityToInsertOrReplace = new JobEntity();

            jobEntityToInsertOrReplace.RowKey = jobId;
            jobEntityToInsertOrReplace.imageConversionMode = imageConversionMode;
            jobEntityToInsertOrReplace.status            = status;
            jobEntityToInsertOrReplace.statusDescription = message;
            jobEntityToInsertOrReplace.imageSource       = imageSource;
            jobEntityToInsertOrReplace.PartitionKey      = _partitionKey;

            TableOperation insertReplaceOperation = TableOperation.InsertOrReplace(jobEntityToInsertOrReplace);
            TableResult    result = await _table.ExecuteAsync(insertReplaceOperation);
        }
Esempio n. 8
0
        /// <summary>
        /// Upserts the given job entity
        /// </summary>
        /// <param name="jobEntity"></param>
        /// <returns></returns>
        public async Task InsertOrReplaceJobEntity(JobEntity jobEntity)
        {
            JobEntity jobEntityToInsertOrReplace = new JobEntity()
            {
                RowKey = jobEntity.JobId,
                ImageConversionMode = jobEntity.ImageConversionMode,
                Status            = jobEntity.Status,
                StatusDescription = jobEntity.StatusDescription,
                ImageSource       = jobEntity.ImageSource,
                ImageResult       = jobEntity.ImageResult,
                PartitionKey      = _partitionKey,
            };

            TableOperation insertReplaceOperation = TableOperation.InsertOrReplace(jobEntityToInsertOrReplace);
            TableResult    result = await _table.ExecuteAsync(insertReplaceOperation);
        }
        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));
        }