示例#1
0
        public async Task Should_add_assets_id_and_versions_as_dependency()
        {
            var image1 = CreateAsset(Guid.NewGuid(), 1, AssetType.Image);
            var image2 = CreateAsset(Guid.NewGuid(), 2, AssetType.Image);

            var document1 = CreateAsset(Guid.NewGuid(), 3, AssetType.Unknown);
            var document2 = CreateAsset(Guid.NewGuid(), 4, AssetType.Unknown);

            var contents = new[]
            {
                CreateContent(
                    new[] { document1.Id, image1.Id },
                    new[] { document1.Id }),
                CreateContent(
                    new[] { document1.Id },
                    new[] { document2.Id, image2.Id })
            };

            A.CallTo(() => assetQuery.QueryAsync(A <Context> .That.Matches(x => !x.ShouldEnrichAsset()), null, A <Q> .That.Matches(x => x.Ids.Count == 4)))
            .Returns(ResultList.CreateFrom(4, image1, image2, document1, document2));

            await sut.EnrichAsync(requestContext, contents, schemaProvider);

            A.CallTo(() => requestCache.AddDependency(image1.Id, image1.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(image2.Id, image2.Version))
            .MustHaveHappened();
        }
示例#2
0
        public async Task Should_add_assets_id_and_versions_as_dependency()
        {
            var doc1 = CreateAsset(DomainId.NewGuid(), 3, AssetType.Unknown, "Document1.docx");
            var doc2 = CreateAsset(DomainId.NewGuid(), 4, AssetType.Unknown, "Document2.docx");

            var contents = new[]
            {
                CreateContent(
                    new[] { doc1.Id },
                    new[] { doc1.Id }),
                CreateContent(
                    new[] { doc2.Id },
                    new[] { doc2.Id })
            };

            A.CallTo(() => assetQuery.QueryAsync(A <Context> .That.Matches(x => !x.ShouldEnrichAsset()), null, A <Q> .That.HasIds(doc1.Id, doc2.Id)))
            .Returns(ResultList.CreateFrom(4, doc1, doc2));

            await sut.EnrichAsync(requestContext, contents, schemaProvider);

            A.CallTo(() => requestCache.AddDependency(doc1.UniqueId, doc1.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(doc2.UniqueId, doc2.Version))
            .MustHaveHappened();
        }
示例#3
0
        private async Task ResolveReferencesAsync(Context context, ISchemaEntity schema, IEnumerable <ContentEntity> contents, ILookup <Guid, IEnrichedContentEntity> references, ProvideSchema schemas)
        {
            var formatted = new Dictionary <IContentEntity, JsonObject>();

            foreach (var field in schema.SchemaDef.ResolvingReferences())
            {
                foreach (var content in contents)
                {
                    if (content.ReferenceData == null)
                    {
                        content.ReferenceData = new NamedContentData();
                    }

                    var fieldReference = content.ReferenceData.GetOrAdd(field.Name, _ => new ContentFieldData()) !;

                    try
                    {
                        if (content.Data.TryGetValue(field.Name, out var fieldData) && fieldData != null)
                        {
                            foreach (var(partition, partitionValue) in fieldData)
                            {
                                var referencedContents =
                                    field.GetReferencedIds(partitionValue)
                                    .Select(x => references[x])
                                    .SelectMany(x => x)
                                    .ToList();

                                if (referencedContents.Count == 1)
                                {
                                    var reference = referencedContents[0];

                                    var referencedSchema = await schemas(reference.SchemaId.Id);

                                    requestCache.AddDependency(referencedSchema.Id, referencedSchema.Version);
                                    requestCache.AddDependency(reference.Id, reference.Version);

                                    var value = formatted.GetOrAdd(reference, x => Format(x, context, referencedSchema));

                                    fieldReference.AddJsonValue(partition, value);
                                }
                                else if (referencedContents.Count > 1)
                                {
                                    var value = CreateFallback(context, referencedContents);

                                    fieldReference.AddJsonValue(partition, value);
                                }
                            }
                        }
                    }
                    catch (DomainObjectNotFoundException)
                    {
                        continue;
                    }
                }
            }
        }
示例#4
0
        public async Task Should_add_app_version_and_schema_as_dependency()
        {
            var content = CreateContent();

            await sut.EnrichAsync(requestContext, Enumerable.Repeat(content, 1), schemaProvider, default);

            A.CallTo(() => requestCache.AddDependency(content.UniqueId, content.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(schema.UniqueId, schema.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(requestContext.App.UniqueId, requestContext.App.Version))
            .MustHaveHappened();
        }
示例#5
0
        private void GenerateSchemasOperations(IEnumerable <ISchemaEntity> schemas, IAppEntity app)
        {
            requestCache.AddDependency(app.UniqueId, app.Version);

            var appBasePath = $"/content/{app.Name}";

            foreach (var schema in schemas.Where(x => x.SchemaDef.IsPublished))
            {
                requestCache.AddDependency(schema.UniqueId, schema.Version);

                var partition = app.PartitionResolver();

                new SchemaOpenApiGenerator(document, app.Name, appBasePath, schema.SchemaDef, AppendSchema, statusSchema, partition)
                .GenerateSchemaOperations();
            }
        }
示例#6
0
        public async Task <IReadOnlyList <IEnrichedAssetEntity> > EnrichAsync(IEnumerable <IAssetEntity> assets, Context context,
                                                                              CancellationToken ct)
        {
            Guard.NotNull(assets);
            Guard.NotNull(context);

            using (Telemetry.Activities.StartActivity("ContentQueryService/EnrichAsync"))
            {
                var results = assets.Select(x => SimpleMapper.Map(x, new AssetEntity())).ToList();

                foreach (var asset in results)
                {
                    requestCache.AddDependency(asset.UniqueId, asset.Version);
                }

                if (!context.ShouldSkipAssetEnrichment())
                {
                    await EnrichTagsAsync(results, ct);

                    EnrichWithMetadataText(results);

                    if (!context.IsFrontendClient)
                    {
                        ComputeTokens(results);
                    }
                }

                return(results);
            }
        }
示例#7
0
        public async Task EnrichAsync(Context context, IEnumerable <ContentEntity> contents, ProvideSchema schemas)
        {
            var app = context.App;

            foreach (var group in contents.GroupBy(x => x.SchemaId.Id))
            {
                var schema = await schemas(group.Key);

                foreach (var content in group)
                {
                    requestCache.AddDependency(content.Id, content.Version);
                    requestCache.AddDependency(app.Id, app.Version);
                    requestCache.AddDependency(schema.Id, schema.Version);
                }
            }
        }
示例#8
0
        public async Task <IReadOnlyList <IEnrichedAssetEntity> > EnrichAsync(IEnumerable <IAssetEntity> assets, Context context,
                                                                              CancellationToken ct)
        {
            Guard.NotNull(assets, nameof(assets));
            Guard.NotNull(context, nameof(context));

            using (Profiler.TraceMethod <AssetEnricher>())
            {
                var results = assets.Select(x => SimpleMapper.Map(x, new AssetEntity())).ToList();

                foreach (var asset in results)
                {
                    requestCache.AddDependency(asset.UniqueId, asset.Version);
                }

                if (!context.ShouldSkipAssetEnrichment())
                {
                    await EnrichTagsAsync(results, ct);

                    EnrichWithMetadataText(results);
                }

                return(results);
            }
        }
示例#9
0
        public async Task <OpenApiDocument> GenerateAsync(HttpContext httpContext, IAppEntity app, IEnumerable <ISchemaEntity> schemas, bool flat)
        {
            var document = CreateApiDocument(httpContext, app);

            var schemaResolver = new OpenApiSchemaResolver(document, schemaSettings);

            requestCache.AddDependency(app.UniqueId, app.Version);

            foreach (var schema in schemas)
            {
                requestCache.AddDependency(schema.UniqueId, schema.Version);
            }

            var builder = new Builder(app, document, schemaResolver, schemaGenerator);

            var validSchemas =
                schemas.Where(x =>
                              x.SchemaDef.IsPublished &&
                              x.SchemaDef.Type != SchemaDefType.Component &&
                              x.SchemaDef.Fields.Count > 0);

            var partitionResolver = app.PartitionResolver();

            foreach (var schema in validSchemas)
            {
                var components = await appProvider.GetComponentsAsync(schema, httpContext.RequestAborted);

                GenerateSchemaOperations(builder.Schema(schema.SchemaDef, partitionResolver, components, flat));
            }

            GenerateSharedOperations(builder.Shared());

            var context =
                new DocumentProcessorContext(document,
                                             Enumerable.Empty <Type>(),
                                             Enumerable.Empty <Type>(),
                                             schemaResolver,
                                             schemaGenerator,
                                             schemaSettings);

            foreach (var processor in schemaSettings.DocumentProcessors)
            {
                processor.Process(context);
            }

            return(document);
        }
示例#10
0
        public async Task Should_not_enrich_if_statistics_not_found()
        {
            var source = CreateRule();

            var result = await sut.EnrichAsync(source, requestContext);

            Assert.Equal(0, result.NumFailed);
            Assert.Equal(0, result.NumSucceeded);

            Assert.Null(result.LastExecuted);

            A.CallTo(() => requestCache.AddDependency(source.UniqueId, source.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(null))
            .MustNotHaveHappened();
        }
示例#11
0
        public async Task EnrichAsync(Context context, IEnumerable <ContentEntity> contents, ProvideSchema schemas,
                                      CancellationToken ct)
        {
            var app = context.App;

            foreach (var group in contents.GroupBy(x => x.SchemaId.Id))
            {
                ct.ThrowIfCancellationRequested();

                var(schema, _) = await schemas(group.Key);

                foreach (var content in group)
                {
                    requestCache.AddDependency(content.UniqueId, content.Version);
                    requestCache.AddDependency(schema.UniqueId, schema.Version);
                    requestCache.AddDependency(app.UniqueId, app.Version);
                }
            }
        }
示例#12
0
        public async Task Should_enrich_with_cache_dependencies()
        {
            var source = new AssetEntity {
                AppId = appId, Id = DomainId.NewGuid(), Version = 13
            };

            var result = await sut.EnrichAsync(source, requestContext, default);

            A.CallTo(() => requestCache.AddDependency(result.UniqueId, result.Version))
            .MustHaveHappened();
        }
示例#13
0
        public async Task <IReadOnlyList <IEnrichedRuleEntity> > EnrichAsync(IEnumerable <IRuleEntity> rules, Context context,
                                                                             CancellationToken ct)
        {
            Guard.NotNull(rules);
            Guard.NotNull(context);

            using (Telemetry.Activities.StartActivity("RuleEnricher/EnrichAsync"))
            {
                var results = new List <RuleEntity>();

                foreach (var rule in rules)
                {
                    var result = SimpleMapper.Map(rule, new RuleEntity());

                    results.Add(result);
                }

                foreach (var group in results.GroupBy(x => x.AppId.Id))
                {
                    var statistics = await ruleEventRepository.QueryStatisticsByAppAsync(group.Key, ct);

                    foreach (var rule in group)
                    {
                        requestCache.AddDependency(rule.UniqueId, rule.Version);

                        var statistic = statistics.FirstOrDefault(x => x.RuleId == rule.Id);

                        if (statistic != null)
                        {
                            rule.LastExecuted = statistic.LastExecuted;
                            rule.NumFailed    = statistic.NumFailed;
                            rule.NumSucceeded = statistic.NumSucceeded;

                            requestCache.AddDependency(rule.LastExecuted);
                        }
                    }
                }

                return(results);
            }
        }
        public OpenApiDocument Generate(HttpContext httpContext, IAppEntity app, IEnumerable <ISchemaEntity> schemas, bool flat = false)
        {
            var document = CreateApiDocument(httpContext, app);

            var schemaResolver = new OpenApiSchemaResolver(document, schemaSettings);

            requestCache.AddDependency(app.UniqueId, app.Version);

            var builder = new Builder(
                app,
                document,
                schemaResolver,
                schemaGenerator);

            foreach (var schema in schemas.Where(x => x.SchemaDef.IsPublished))
            {
                requestCache.AddDependency(schema.UniqueId, schema.Version);

                GenerateSchemaOperations(builder.Schema(schema.SchemaDef, flat));
            }

            GenerateSharedOperations(builder.Shared());

            var context =
                new DocumentProcessorContext(document,
                                             Enumerable.Empty <Type>(),
                                             Enumerable.Empty <Type>(),
                                             schemaResolver,
                                             schemaGenerator,
                                             schemaSettings);

            foreach (var processor in schemaSettings.DocumentProcessors)
            {
                processor.Process(context);
            }

            return(document);
        }
示例#15
0
        private void ResolveAssetsUrls(ISchemaEntity schema, ResolvedComponents components,
                                       IGrouping <DomainId, ContentEntity> contents, ILookup <DomainId, IEnrichedAssetEntity> assets)
        {
            foreach (var field in schema.SchemaDef.ResolvingAssets())
            {
                foreach (var content in contents)
                {
                    content.ReferenceData ??= new ContentData();

                    var fieldReference = content.ReferenceData.GetOrAdd(field.Name, _ => new ContentFieldData()) !;

                    if (content.Data.TryGetValue(field.Name, out var fieldData) && fieldData != null)
                    {
                        foreach (var(partitionKey, partitionValue) in fieldData)
                        {
                            var referencedAsset =
                                field.GetReferencedIds(partitionValue, components)
                                .Select(x => assets[x])
                                .SelectMany(x => x)
                                .FirstOrDefault();

                            if (referencedAsset != null)
                            {
                                IJsonValue array;

                                if (IsImage(referencedAsset))
                                {
                                    var url = urlGenerator.AssetContent(
                                        referencedAsset.AppId,
                                        referencedAsset.Id.ToString());

                                    array = JsonValue.Array(url, referencedAsset.FileName);
                                }
                                else
                                {
                                    array = JsonValue.Array(referencedAsset.FileName);
                                }

                                requestCache.AddDependency(referencedAsset.UniqueId, referencedAsset.Version);

                                fieldReference.AddLocalized(partitionKey, array);
                            }
                        }
                    }
                }
            }
        }
示例#16
0
        private void ResolveAssetsUrls(ISchemaEntity schema, IGrouping <Guid, ContentEntity> contents, ILookup <Guid, IEnrichedAssetEntity> assets)
        {
            foreach (var field in schema.SchemaDef.ResolvingAssets())
            {
                foreach (var content in contents)
                {
                    if (content.ReferenceData == null)
                    {
                        content.ReferenceData = new NamedContentData();
                    }

                    var fieldReference = content.ReferenceData.GetOrAdd(field.Name, _ => new ContentFieldData()) !;

                    if (content.Data.TryGetValue(field.Name, out var fieldData) && fieldData != null)
                    {
                        foreach (var(partitionKey, partitionValue) in fieldData)
                        {
                            var referencedImage =
                                field.GetReferencedIds(partitionValue)
                                .Select(x => assets[x])
                                .SelectMany(x => x)
                                .FirstOrDefault(x => x.Type == AssetType.Image);

                            if (referencedImage != null)
                            {
                                var url = assetUrlGenerator.GenerateUrl(referencedImage.Id.ToString());

                                requestCache.AddDependency(referencedImage.Id, referencedImage.Version);

                                fieldReference.AddJsonValue(partitionKey, JsonValue.Create(url));
                            }
                        }
                    }
                }
            }
        }
示例#17
0
        public async Task Should_add_referenced_id_and__as_dependency()
        {
            var ref1_1 = CreateRefContent(Guid.NewGuid(), 1, "ref1_1", 13, refSchemaId1);
            var ref1_2 = CreateRefContent(Guid.NewGuid(), 2, "ref1_2", 17, refSchemaId1);
            var ref2_1 = CreateRefContent(Guid.NewGuid(), 3, "ref2_1", 23, refSchemaId2);
            var ref2_2 = CreateRefContent(Guid.NewGuid(), 4, "ref2_2", 29, refSchemaId2);

            var contents = new[]
            {
                CreateContent(new[] { ref1_1.Id }, new[] { ref2_1.Id }),
                CreateContent(new[] { ref1_2.Id }, new[] { ref2_2.Id })
            };

            A.CallTo(() => contentQuery.QueryAsync(A <Context> .Ignored, A <IReadOnlyList <Guid> > .That.Matches(x => x.Count == 4)))
            .Returns(ResultList.CreateFrom(4, ref1_1, ref1_2, ref2_1, ref2_2));

            await sut.EnrichAsync(requestContext, contents, schemaProvider);

            var enriched1 = contents[0];

            A.CallTo(() => requestCache.AddDependency(refSchemaId1.Id, 0))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(refSchemaId2.Id, 0))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref1_1.Id, ref1_1.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref2_1.Id, ref2_1.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref1_2.Id, ref1_2.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref2_2.Id, ref2_2.Version))
            .MustHaveHappened();
        }
示例#18
0
        public async Task Should_add_referenced_id_and_as_dependency()
        {
            var ref1_1 = CreateRefContent(DomainId.NewGuid(), 1, "ref1_1", 13, refSchemaId1);
            var ref1_2 = CreateRefContent(DomainId.NewGuid(), 2, "ref1_2", 17, refSchemaId1);
            var ref2_1 = CreateRefContent(DomainId.NewGuid(), 3, "ref2_1", 23, refSchemaId2);
            var ref2_2 = CreateRefContent(DomainId.NewGuid(), 4, "ref2_2", 29, refSchemaId2);

            var contents = new[]
            {
                CreateContent(new[] { ref1_1.Id }, new[] { ref2_1.Id }),
                CreateContent(new[] { ref1_2.Id }, new[] { ref2_2.Id })
            };

            A.CallTo(() => contentQuery.QueryAsync(
                         A <Context> .That.Matches(x => x.ShouldSkipContentEnrichment() && x.ShouldSkipTotal()), A <Q> .That.HasIds(ref1_1.Id, ref1_2.Id, ref2_1.Id, ref2_2.Id), A <CancellationToken> ._))
            .Returns(ResultList.CreateFrom(4, ref1_1, ref1_2, ref2_1, ref2_2));

            await sut.EnrichAsync(requestContext, contents, schemaProvider, default);

            A.CallTo(() => requestCache.AddDependency(DomainId.Combine(appId, refSchemaId1.Id), 0))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(DomainId.Combine(appId, refSchemaId2.Id), 0))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref1_1.UniqueId, ref1_1.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref2_1.UniqueId, ref2_1.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref1_2.UniqueId, ref1_2.Version))
            .MustHaveHappened();

            A.CallTo(() => requestCache.AddDependency(ref2_2.UniqueId, ref2_2.Version))
            .MustHaveHappened();
        }