示例#1
0
        public async Task Should_find_asset_by_id_and_version_and_enrich_it()
        {
            var asset = CreateAsset(DomainId.NewGuid());

            A.CallTo(() => assetLoader.GetAsync(appId.Id, asset.Id, 2))
            .Returns(asset);

            var result = await sut.FindAsync(requestContext, asset.Id, 2);

            AssertAsset(asset, result);
        }
示例#2
0
        public async Task <IEnrichedAssetEntity?> FindAsync(Context context, DomainId id, long version = EtagVersion.Any,
                                                            CancellationToken ct = default)
        {
            Guard.NotNull(context, nameof(context));

            using (Profiler.TraceMethod <AssetQueryService>())
            {
                IAssetEntity?asset;

                if (version > EtagVersion.Empty)
                {
                    asset = await assetLoader.GetAsync(context.App.Id, id, version);
                }
                else
                {
                    asset = await assetRepository.FindAssetAsync(context.App.Id, id, ct);
                }

                if (asset == null)
                {
                    return(null);
                }

                return(await TransformAsync(context, asset, ct));
            }
        }
示例#3
0
        public async Task <IEnrichedAssetEntity?> FindAsync(Context context, DomainId id, long version = EtagVersion.Any,
                                                            CancellationToken ct = default)
        {
            Guard.NotNull(context, nameof(context));

            using (Telemetry.Activities.StartActivity("AssetQueryService/FindAsync"))
            {
                IAssetEntity?asset;

                if (version > EtagVersion.Empty)
                {
                    asset = await assetLoader.GetAsync(context.App.Id, id, version);
                }
                else
                {
                    asset = await FindCoreAsync(context, id, ct);
                }

                if (asset == null)
                {
                    return(null);
                }

                return(await TransformAsync(context, asset, ct));
            }
        }
示例#4
0
        protected override async Task <EnrichedAssetEvent> CreateEnrichedEventAsync(Envelope <AssetEvent> @event)
        {
            var result = new EnrichedAssetEvent();

            var asset = await assetLoader.GetAsync(@event.Payload.AssetId, @event.Headers.EventStreamNumber());

            SimpleMapper.Map(asset, result);

            switch (@event.Payload)
            {
            case AssetCreated _:
                result.Type = EnrichedAssetEventType.Created;
                break;

            case AssetAnnotated _:
                result.Type = EnrichedAssetEventType.Annotated;
                break;

            case AssetUpdated _:
                result.Type = EnrichedAssetEventType.Updated;
                break;

            case AssetDeleted _:
                result.Type = EnrichedAssetEventType.Deleted;
                break;
            }

            result.Name = $"Asset{result.Type}";

            return(result);
        }
示例#5
0
        public async Task Should_enrich_events(AssetEvent @event, EnrichedAssetEventType type)
        {
            var envelope = Envelope.Create <AppEvent>(@event).SetEventStreamNumber(12);

            A.CallTo(() => assetLoader.GetAsync(@event.AssetId, 12))
            .Returns(new AssetEntity());

            var result = await sut.CreateEnrichedEventAsync(envelope) as EnrichedAssetEvent;

            Assert.Equal(type, result !.Type);
        }
示例#6
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, [FromQuery] AssetContentQueryDto queries, string?more = null)
        {
            var asset = await assetRepository.FindAssetAsync(AppId, DomainId.Create(idOrSlug));

            if (asset == null)
            {
                asset = await assetRepository.FindAssetBySlugAsync(AppId, idOrSlug);
            }

            if (asset != null && queries.Version > EtagVersion.Any && asset.Version != queries.Version)
            {
                asset = await assetLoader.GetAsync(App.Id, asset.Id, queries.Version);
            }

            return(DeliverAsset(asset, queries));
        }
示例#7
0
        protected override async Task <EnrichedAssetEvent?> CreateEnrichedEventAsync(Envelope <AssetEvent> @event)
        {
            if (@event.Payload is AssetMoved)
            {
                return(null);
            }

            var result = new EnrichedAssetEvent();

            var asset = await assetLoader.GetAsync(
                @event.Payload.AppId.Id,
                @event.Payload.AssetId,
                @event.Headers.EventStreamNumber());

            if (asset == null)
            {
                throw new DomainObjectNotFoundException(@event.Payload.AssetId.ToString());
            }

            SimpleMapper.Map(asset, result);

            result.AssetType = asset.Type;

            switch (@event.Payload)
            {
            case AssetCreated _:
                result.Type = EnrichedAssetEventType.Created;
                break;

            case AssetAnnotated _:
                result.Type = EnrichedAssetEventType.Annotated;
                break;

            case AssetUpdated _:
                result.Type = EnrichedAssetEventType.Updated;
                break;

            case AssetDeleted _:
                result.Type = EnrichedAssetEventType.Deleted;
                break;
            }

            result.Name = $"Asset{result.Type}";

            return(result);
        }
示例#8
0
        public async Task Should_create_enriched_events(AssetEvent @event, EnrichedAssetEventType type)
        {
            var ctx = Context();

            @event.AppId = ctx.AppId;

            var envelope = Envelope.Create <AppEvent>(@event).SetEventStreamNumber(12);

            A.CallTo(() => assetLoader.GetAsync(ctx.AppId.Id, @event.AssetId, 12))
            .Returns(new AssetEntity());

            var result = await sut.CreateEnrichedEventsAsync(envelope, ctx, default).ToListAsync();

            var enrichedEvent = result.Single() as EnrichedAssetEvent;

            Assert.Equal(type, enrichedEvent !.Type);
        }
        public async IAsyncEnumerable <EnrichedEvent> CreateEnrichedEventsAsync(Envelope <AppEvent> @event, RuleContext context,
                                                                                [EnumeratorCancellation] CancellationToken ct)
        {
            var assetEvent = (AssetEvent)@event.Payload;

            var result = new EnrichedAssetEvent();

            var asset = await assetLoader.GetAsync(
                assetEvent.AppId.Id,
                assetEvent.AssetId,
                @event.Headers.EventStreamNumber());

            if (asset != null)
            {
                SimpleMapper.Map(asset, result);

                result.PixelHeight = asset.Metadata?.GetPixelHeight();
                result.PixelWidth  = asset.Metadata?.GetPixelWidth();
                result.AssetType   = asset.Type;
            }

            switch (@event.Payload)
            {
            case AssetCreated:
                result.Type = EnrichedAssetEventType.Created;
                break;

            case AssetAnnotated:
                result.Type = EnrichedAssetEventType.Annotated;
                break;

            case AssetUpdated:
                result.Type = EnrichedAssetEventType.Updated;
                break;

            case AssetDeleted:
                result.Type = EnrichedAssetEventType.Deleted;
                break;
            }

            yield return(result);
        }
示例#10
0
        private async Task <IActionResult> DeliverAssetAsync(IAssetEntity?asset, AssetContentQueryDto query)
        {
            query ??= new AssetContentQueryDto();

            if (asset == null)
            {
                return(NotFound());
            }

            if (asset.IsProtected && !Resources.CanReadEvents)
            {
                return(StatusCode(403));
            }

            if (query.Version > EtagVersion.Any && asset.Version != query.Version)
            {
                asset = await assetLoader.GetAsync(asset.Id, query.Version);
            }

            var resizeOptions = query.ToResizeOptions(asset);

            FileCallback callback;

            Response.Headers[HeaderNames.ETag] = asset.FileVersion.ToString();

            if (query.CacheDuration > 0)
            {
                Response.Headers[HeaderNames.CacheControl] = $"public,max-age={query.CacheDuration}";
            }

            var contentLength = (long?)null;

            if (asset.Type == AssetType.Image && resizeOptions.IsValid)
            {
                callback = new FileCallback(async(bodyStream, range, ct) =>
                {
                    var resizedAsset = $"{asset.Id}_{asset.FileVersion}_{resizeOptions}";

                    if (query.ForceResize)
                    {
                        await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, true, ct);
                    }
                    else
                    {
                        try
                        {
                            await assetStore.DownloadAsync(resizedAsset, bodyStream);
                        }
                        catch (AssetNotFoundException)
                        {
                            await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, false, ct);
                        }
                    }
                });
            }
            else
            {
                contentLength = asset.FileSize;

                callback = new FileCallback(async(bodyStream, range, ct) =>
                {
                    await assetFileStore.DownloadAsync(asset.Id, asset.FileVersion, bodyStream, range, ct);
                });
            }

            return(new FileCallbackResult(asset.MimeType, callback)
            {
                EnableRangeProcessing = contentLength > 0,
                ErrorAs404 = true,
                FileDownloadName = asset.FileName,
                FileSize = contentLength,
                LastModified = asset.LastModified.ToDateTimeOffset(),
                SendInline = query.Download != 1
            });
        }
示例#11
0
        private async Task <IActionResult> DeliverAssetAsync(Context context, IAssetEntity?asset, AssetContentQueryDto request)
        {
            request ??= new AssetContentQueryDto();

            if (asset == null)
            {
                return(NotFound());
            }

            if (asset.IsProtected && !Resources.CanReadAssets)
            {
                Response.Headers[HeaderNames.CacheControl] = "public,max-age=0";

                return(StatusCode(403));
            }

            if (asset != null && request.Version > EtagVersion.Any && asset.Version != request.Version)
            {
                if (context.App != null)
                {
                    asset = await assetQuery.FindAsync(context, asset.Id, request.Version, HttpContext.RequestAborted);
                }
                else
                {
                    // Fallback for old endpoint. Does not set the surrogate key.
                    asset = await assetLoader.GetAsync(asset.AppId.Id, asset.Id, request.Version);
                }
            }

            if (asset == null)
            {
                return(NotFound());
            }

            var resizeOptions = request.ToResizeOptions(asset);

            FileCallback callback;

            Response.Headers[HeaderNames.ETag] = asset.FileVersion.ToString();

            if (request.CacheDuration > 0)
            {
                Response.Headers[HeaderNames.CacheControl] = $"public,max-age={request.CacheDuration}";
            }

            var contentLength = (long?)null;

            if (asset.Type == AssetType.Image && resizeOptions.IsValid)
            {
                callback = async(bodyStream, range, ct) =>
                {
                    var resizedAsset = $"{asset.AppId.Id}_{asset.Id}_{asset.FileVersion}_{resizeOptions}";

                    if (request.ForceResize)
                    {
                        await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, true, ct);
                    }
                    else
                    {
                        try
                        {
                            await assetStore.DownloadAsync(resizedAsset, bodyStream, ct : ct);
                        }
                        catch (AssetNotFoundException)
                        {
                            await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, false, ct);
                        }
                    }
                };
            }
            else
            {
                contentLength = asset.FileSize;

                callback = async(bodyStream, range, ct) =>
                {
                    await assetFileStore.DownloadAsync(asset.AppId.Id, asset.Id, asset.FileVersion, bodyStream, range, ct);
                };
            }

            return(new FileCallbackResult(asset.MimeType, callback)
            {
                EnableRangeProcessing = contentLength > 0,
                ErrorAs404 = true,
                FileDownloadName = asset.FileName,
                FileSize = contentLength,
                LastModified = asset.LastModified.ToDateTimeOffset(),
                SendInline = request.Download != 1
            });
        }