public async Task CreatePoisonThumbnailSetAsync(
            CreateThumbnailsMessage message,
            ICloudStorageAccount cloudStorageAccount,
            ILogger logger,
            int dequeueCount,
            CancellationToken cancellationToken)
        {
            try
            {
                logger.Warn("Failed to resize image from blob {0}/{1}", message.ContainerName, message.InputBlobName);
                var startProcessingTime = DateTime.UtcNow;
                await this.thumbnailProcessor.CreatePoisonThumbnailSetAsync(
                    message,
                    cloudStorageAccount,
                    logger,
                    cancellationToken);

                var completeProcessingTime = DateTime.UtcNow;

                await this.setFileProcessingComplete.ExecuteAsync(
                    message.FileId,
                    dequeueCount * -1,
                    startProcessingTime,
                    completeProcessingTime,
                    1,
                    1);
            }
            catch (Exception t)
            {
                logger.Error(t);
                throw;
            }
        }
        private async Task PopulateExists(CreateThumbnailsMessage message, CancellationToken cancellationToken, Dictionary <ThumbnailDefinition, ThumbnailSetItemData> cache)
        {
            foreach (var item in cache.Values)
            {
                item.Exists = await item.BlockBlob.ExistsAsync(cancellationToken);

                item.ShouldCreate = message.Overwrite || !item.Exists;
            }
        }
        private Dictionary <ThumbnailDefinition, ThumbnailSetItemData> GetItemsCache(CreateThumbnailsMessage message, ICloudStorageAccount cloudStorageAccount)
        {
            var client    = cloudStorageAccount.CreateCloudBlobClient();
            var container = client.GetContainerReference(message.ContainerName);
            var cache     = new Dictionary <ThumbnailDefinition, ThumbnailSetItemData>();

            this.GetItemsCache(container, cache, message.Items);
            return(cache);
        }
        public async Task HandleAsync(IQueueService queueService, FileId fileId, string containerName, string blobName, string filePurpose)
        {
            var outputMessage = new CreateThumbnailsMessage(
                fileId,
                containerName,
                blobName,
                this.Items.Select(v => v.ToMessage(blobName)).ToList(),
                false);

            await queueService.AddMessageToQueueAsync(Fifthweek.WebJobs.Thumbnails.Shared.Constants.ThumbnailsQueueName, outputMessage);
        }
Example #5
0
 public static Task ProcessPoisonMessage(
     [QueueTrigger(Shared.Constants.ThumbnailsQueueName + "-poison")] CreateThumbnailsMessage message,
     CloudStorageAccount cloudStorageAccount,
     TextWriter webJobsLogger,
     int dequeueCount,
     CancellationToken cancellationToken)
 {
     return(ThumbnailProcessor.CreatePoisonThumbnailSetAsync(
                message,
                new FifthweekCloudStorageAccount(cloudStorageAccount),
                CreateLogger(webJobsLogger),
                dequeueCount,
                cancellationToken));
 }
Example #6
0
 public static Task CreateThumbnailSetAsync(
     [QueueTrigger(Shared.Constants.ThumbnailsQueueName)] CreateThumbnailsMessage message,
     [Blob("{ContainerName}/{InputBlobName}")] CloudBlockBlob input,
     CloudStorageAccount cloudStorageAccount,
     TextWriter webJobsLogger,
     int dequeueCount,
     CancellationToken cancellationToken)
 {
     return(ThumbnailProcessor.CreateThumbnailSetAsync(
                message,
                new FifthweekCloudBlockBlob(input),
                new FifthweekCloudStorageAccount(cloudStorageAccount),
                CreateLogger(webJobsLogger),
                dequeueCount,
                cancellationToken));
 }
        public async Task CreatePoisonThumbnailSetAsync(
            CreateThumbnailsMessage message,
            ICloudStorageAccount cloudStorageAccount,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (message.Items == null || message.Items.Count == 0)
            {
                return;
            }

            var cache = this.GetItemsCache(message, cloudStorageAccount);

            await this.PopulateExists(message, cancellationToken, cache);

            if (message.Overwrite == false && cache.Values.All(v => v.Exists))
            {
                return;
            }

            // Create a small black 1x1 png.
            using (var image = new MagickImage(new MagickColor(0, 0, 0), 1, 1))
            {
                image.Format = MagickFormat.Png;

                foreach (var itemData in cache.Values)
                {
                    if (itemData.ShouldCreate)
                    {
                        if (itemData.Exists)
                        {
                            await itemData.BlockBlob.FetchAttributesAsync(cancellationToken);
                        }

                        itemData.BlockBlob.Properties.ContentType = image.FormatInfo.MimeType;

                        using (var outputStream = await itemData.BlockBlob.OpenWriteAsync(cancellationToken))
                        {
                            image.Write(outputStream);
                            await Task.Factory.FromAsync(outputStream.BeginCommit(null, null), outputStream.EndCommit);
                        }
                    }
                }
            }
        }
        public async Task WhenCropping_TestHandleAsync()
        {
            CreateThumbnailsMessage outputMessage = null;

            this.queueService.Setup(v => v.AddMessageToQueueAsync(Constants.ThumbnailsQueueName, It.IsAny <CreateThumbnailsMessage>()))
            .Callback <string, CreateThumbnailsMessage>((s, v) => outputMessage = v)
            .Returns(Task.FromResult(0));

            var target = new CreateThumbnailsTask(new Thumbnail(1000, 1000, "alias", ResizeBehaviour.CropToAspectRatio));
            await target.HandleAsync(this.queueService.Object, FileId, ContainerName, BlobName, FilePurpose);

            Assert.AreEqual(FileId, outputMessage.FileId);
            Assert.AreEqual(ContainerName, outputMessage.ContainerName);
            Assert.AreEqual(BlobName, outputMessage.InputBlobName);
            Assert.AreEqual(string.Format("{0}/{1}", BlobName, target.Items[0].Alias), outputMessage.Items[0].OutputBlobName);
            Assert.AreEqual(target.Items[0].Width, outputMessage.Items[0].Width);
            Assert.AreEqual(target.Items[0].Height, outputMessage.Items[0].Height);
            Assert.AreEqual(target.Items[0].ResizeBehaviour, outputMessage.Items[0].ResizeBehaviour);
            Assert.AreEqual(false, outputMessage.Overwrite);
        }
        public async Task CreateThumbnailSetAsync(
            CreateThumbnailsMessage message,
            ICloudBlockBlob input,
            ICloudStorageAccount cloudStorageAccount,
            ILogger logger,
            int dequeueCount,
            CancellationToken cancellationToken)
        {
            try
            {
                var startProcessingTime = DateTime.UtcNow;
                var result = await this.thumbnailProcessor.CreateThumbnailSetAsync(
                    message,
                    input,
                    cloudStorageAccount,
                    logger,
                    cancellationToken);

                var completeProcessingTime = DateTime.UtcNow;

                if (result != null)
                {
                    await this.setFileProcessingComplete.ExecuteAsync(
                        message.FileId,
                        dequeueCount,
                        startProcessingTime,
                        completeProcessingTime,
                        result.RenderWidth,
                        result.RenderHeight);
                }
            }
            catch (Exception t)
            {
                logger.Error(t);
                throw;
            }
        }
        public async Task <CreateThumbnailSetResult> CreateThumbnailSetAsync(
            CreateThumbnailsMessage message,
            ICloudBlockBlob input,
            ICloudStorageAccount cloudStorageAccount,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            CreateThumbnailSetResult result = null;
            var sw = new Stopwatch();

            sw.Start();
            logger.Info("StartFileProcessor: " + sw.ElapsedMilliseconds);

            if (message.Items == null || message.Items.Count == 0)
            {
                return(null);
            }

            var cache = this.GetItemsCache(message, cloudStorageAccount);

            logger.Info("GetBlockBlobs: " + sw.ElapsedMilliseconds);
            await this.PopulateExists(message, cancellationToken, cache);

            logger.Info("CheckExists: " + sw.ElapsedMilliseconds);

            if (message.Overwrite == false && cache.Values.All(v => v.Exists))
            {
                return(null);
            }

            await input.FetchAttributesAsync(cancellationToken);

            var cacheControl = input.Properties.CacheControl;

            this.PopulateCacheControl(cacheControl, cache);

            using (var image = await this.OpenImageAsync(input, cancellationToken, logger, sw))
            {
                logger.Info("OpenImage: " + sw.ElapsedMilliseconds);
                var outputMimeType = image.FormatInfo.MimeType;
                if (!SupportedOutputMimeTypes.Contains(outputMimeType))
                {
                    outputMimeType = DefaultOutputMimeType;
                    image.Format   = DefaultOutputFormat;
                    logger.Info("ConvertToJpeg: " + sw.ElapsedMilliseconds);
                }

                if (image.Format == MagickFormat.Jpg || image.Format == MagickFormat.Jpeg)
                {
                    var colorProfile = image.GetColorProfile();
                    if (colorProfile == null)
                    {
                        image.AddProfile(ColorProfile.SRGB);
                        logger.Info("AddColorProfile: " + sw.ElapsedMilliseconds);
                    }

                    if (image.Quality > 85)
                    {
                        image.Quality = 85;
                    }

                    await this.OrientAndSetMetadataAsync(image, input, cancellationToken, logger, sw);
                }
                else
                {
                    await SetAndSaveMetadata(input, image);
                }

                var jobData = new JobData(outputMimeType);

                logger.Info("Processing: " + sw.ElapsedMilliseconds);
                result = new CreateThumbnailSetResult(image.Width, image.Height);
                await this.ProcessThumbnailItems(message.Items, cache, image, jobData, logger, cancellationToken);

                logger.Info("ProcessingComplete: " + sw.ElapsedMilliseconds);
            }

            logger.Info("Disposed: " + sw.ElapsedMilliseconds);
            return(result);
        }