示例#1
0
        private async Task GetReferencesAsync(ScriptExecutionContext context, DomainId appId, ClaimsPrincipal user, JsValue references, Action <JsValue> callback)
        {
            Guard.NotNull(callback, nameof(callback));

            var ids = new List <DomainId>();

            if (references.IsString())
            {
                ids.Add(DomainId.Create(references.ToString()));
            }
            else if (references.IsArray())
            {
                foreach (var value in references.AsArray())
                {
                    if (value.IsString())
                    {
                        ids.Add(DomainId.Create(value.ToString()));
                    }
                }
            }

            if (ids.Count == 0)
            {
                var emptyContents = Array.Empty <IEnrichedContentEntity>();

                callback(JsValue.FromObject(context.Engine, emptyContents));
                return;
            }

            context.MarkAsync();

            try
            {
                var app = await GetAppAsync(appId);

                var requestContext =
                    new Context(user, app).Clone(b => b
                                                 .WithoutContentEnrichment()
                                                 .WithUnpublished()
                                                 .WithoutTotal());

                var contentQuery = serviceProvider.GetRequiredService <IContentQueryService>();

                var contents = await contentQuery.QueryAsync(requestContext, Q.Empty.WithIds(ids), context.CancellationToken);

                // Reset the time contraints and other constraints so that our awaiting does not count as script time.
                context.Engine.ResetConstraints();

                callback(JsValue.FromObject(context.Engine, contents.ToArray()));
            }
            catch (Exception ex)
            {
                context.Fail(ex);
            }
        }
示例#2
0
        public async Task UpdateAsync()
        {
            const int SizeOfBatch = 1000;
            const int SizeOfQueue = 20;

            var collectionOld = database.GetCollection <BsonDocument>("Events");
            var collectionNew = database.GetCollection <BsonDocument>("Events2");

            var batchBlock = new BatchBlock <BsonDocument>(SizeOfBatch, new GroupingDataflowBlockOptions
            {
                BoundedCapacity = SizeOfQueue * SizeOfBatch
            });

            var writeOptions = new BulkWriteOptions
            {
                IsOrdered = false
            };

            var actionBlock = new ActionBlock <BsonDocument[]>(async batch =>
            {
                var writes = new List <WriteModel <BsonDocument> >();

                foreach (var document in batch)
                {
                    var eventStream = document["EventStream"].AsString;

                    if (TryGetAppId(document, out var appId))
                    {
                        if (!eventStream.StartsWith("app-", StringComparison.OrdinalIgnoreCase))
                        {
                            var indexOfType = eventStream.IndexOf('-');
                            var indexOfId   = indexOfType + 1;

                            var indexOfOldId = eventStream.LastIndexOf("--", StringComparison.OrdinalIgnoreCase);

                            if (indexOfOldId > 0)
                            {
                                indexOfId = indexOfOldId + 2;
                            }

                            var domainType = eventStream.Substring(0, indexOfType);
                            var domainId   = eventStream[indexOfId..];

                            var newDomainId   = DomainId.Combine(DomainId.Create(appId), DomainId.Create(domainId)).ToString();
                            var newStreamName = $"{domainType}-{newDomainId}";

                            document["EventStream"] = newStreamName;

                            foreach (var @event in document["Events"].AsBsonArray)
                            {
                                var metadata = @event["Metadata"].AsBsonDocument;

                                metadata["AggregateId"] = newDomainId;
                            }
                        }
        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);
            }

            return(await DeliverAssetAsync(asset, queries));
        }
示例#4
0
        public async Task <IReadOnlyList <DomainId> > QueryIdsAsync(DomainId appId, HashSet <DomainId> ids)
        {
            using (Profiler.TraceMethod <MongoAssetRepository>("QueryAsyncByIds"))
            {
                var assetEntities =
                    await Collection.Find(BuildFilter(appId, ids)).Only(x => x.Id)
                    .ToListAsync();

                return(assetEntities.Select(x => DomainId.Create(x[Fields.AssetId].AsString)).ToList());
            }
        }
示例#5
0
        public async Task <IReadOnlyList <DomainId> > QueryChildIdsAsync(DomainId appId, DomainId parentId)
        {
            using (Profiler.TraceMethod <MongoAssetRepository>())
            {
                var assetEntities =
                    await Collection.Find(x => x.IndexedAppId == appId && !x.IsDeleted && x.ParentId == parentId).Only(x => x.DocumentId)
                    .ToListAsync();

                return(assetEntities.Select(x => DomainId.Create(x[Fields.AssetId].AsString)).ToList());
            }
        }
        public async Task Should_not_replace_content_id_with_schema_id_if_placeholder_not_used()
        {
            var command = new UpdateContent
            {
                ContentId = DomainId.Create("{custom}")
            };

            await HandleAsync(command);

            Assert.NotEqual(schemaId.Id, command.ContentId);
        }
        public async Task Should_not_replace_content_id_with_schema_for_create_command()
        {
            var command = new CreateContent
            {
                ContentId = DomainId.Create("_schemaId_")
            };

            await HandleAsync(command);

            Assert.NotEqual(schemaId.Id, command.ContentId);
        }
示例#8
0
        public override FilterNode <ClrValue> Visit(CompareFilter <ClrValue> nodeIn, Args args)
        {
            var result = nodeIn;

            var(path, op, value) = nodeIn;

            var clrValue = value.Value;

            if (string.Equals(path[0], "id", StringComparison.OrdinalIgnoreCase))
            {
                path = "_id";

                if (clrValue is List <string> idList)
                {
                    value = idList.Select(x => DomainId.Combine(args.AppId, DomainId.Create(x)).ToString()).ToList();
                }
                else if (clrValue is string id)
                {
                    value = DomainId.Combine(args.AppId, DomainId.Create(id)).ToString();
                }
                else if (clrValue is List <Guid> guidIdList)
                {
                    value = guidIdList.Select(x => DomainId.Combine(args.AppId, DomainId.Create(x)).ToString()).ToList();
                }
                else if (clrValue is Guid guidId)
                {
                    value = DomainId.Combine(args.AppId, DomainId.Create(guidId)).ToString();
                }
            }
            else
            {
                path = Adapt.MapPath(path);

                if (clrValue is List <Guid> guidList)
                {
                    value = guidList.Select(x => x.ToString()).ToList();
                }
                else if (clrValue is Guid guid)
                {
                    value = guid.ToString();
                }
                else if (clrValue is Instant &&
                         !string.Equals(path[0], "mt", StringComparison.OrdinalIgnoreCase) &&
                         !string.Equals(path[0], "ct", StringComparison.OrdinalIgnoreCase))
                {
                    value = clrValue.ToString();
                }
            }

            return(result with {
                Path = path, Value = value
            });
        }
示例#9
0
        public async Task Should_return_content_by_special_id()
        {
            var requestContext = CreateContext();

            var content = CreateContent(DomainId.NewGuid());

            A.CallTo(() => contentRepository.FindContentAsync(requestContext.App, schema, schema.Id, SearchScope.Published, A <CancellationToken> ._))
            .Returns(content);

            var result = await sut.FindAsync(requestContext, schemaId.Name, DomainId.Create("_schemaId_"), ct : ct);

            AssertContent(content, result);
        }
示例#10
0
        public async Task <IReadOnlyList <DomainId> > QueryChildIdsAsync(DomainId appId, DomainId parentId)
        {
            using (Profiler.TraceMethod <MongoAssetRepository>())
            {
                var filter = BuildFilter(appId, parentId);

                var assetFolderEntities =
                    await Collection.Find(filter).Only(x => x.Id)
                    .ToListAsync();

                return(assetFolderEntities.Select(x => DomainId.Create(x[Fields.AssetFolderId].AsString)).ToList());
            }
        }
示例#11
0
        private Task <ISchemaEntity?> GetSchemaAsync(string schema)
        {
            if (Guid.TryParse(schema, out var guid))
            {
                var schemaId = DomainId.Create(guid);

                return(appProvider.GetSchemaAsync(AppId, schemaId));
            }
            else
            {
                return(appProvider.GetSchemaAsync(AppId, schema));
            }
        }
示例#12
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, [FromQuery] AssetContentQueryDto queries, string?more = null)
        {
            var requestContext = Context.Clone(b => b.WithoutAssetEnrichment());

            var asset = await assetQuery.FindAsync(requestContext, DomainId.Create(idOrSlug));

            if (asset == null)
            {
                asset = await assetQuery.FindBySlugAsync(requestContext, idOrSlug);
            }

            return(await DeliverAssetAsync(requestContext, asset, queries));
        }
示例#13
0
        public async Task Should_convert_full_text_query_to_filter_with_other_filter()
        {
            A.CallTo(() => textIndex.SearchAsync(requestContext.App, A <TextQuery> .That.Matches(x => x.Text == "Hello"), requestContext.Scope()))
            .Returns(new List <DomainId> {
                DomainId.Create("1"), DomainId.Create("2")
            });

            var query = Q.Empty.WithODataQuery("$search=Hello&$filter=data/firstName/iv eq 'ABC'");

            var q = await sut.ParseAsync(requestContext, query, schema);

            Assert.Equal("Filter: (data.firstName.iv == 'ABC' && id in ['1', '2']); Take: 30; Sort: lastModified Descending, id Ascending", q.Query.ToString());
        }
示例#14
0
        public async Task Should_convert_full_text_query_to_filter_if_single_id_found()
        {
            A.CallTo(() => textIndex.SearchAsync(requestContext.App, A <TextQuery> .That.Matches(x => x.Text == "Hello"), requestContext.Scope()))
            .Returns(new List <DomainId> {
                DomainId.Create("1")
            });

            var query = Q.Empty.WithODataQuery("$search=Hello");

            var q = await sut.ParseAsync(requestContext, query, schema);

            Assert.Equal("Filter: id in ['1']; Take: 30; Sort: lastModified Descending, id Ascending", q.Query.ToString());
        }
示例#15
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, AssetContentQueryDto request, string?more = null)
        {
            var requestContext = Context.Clone(b => b.WithoutAssetEnrichment());

            var asset = await assetQuery.FindAsync(requestContext, DomainId.Create(idOrSlug), ct : HttpContext.RequestAborted);

            if (asset == null)
            {
                asset = await assetQuery.FindBySlugAsync(requestContext, idOrSlug, HttpContext.RequestAborted);
            }

            return(await DeliverAssetAsync(requestContext, asset, request));
        }
示例#16
0
        public async Task Should_convert_geo_query_to_filter_if_single_id_found()
        {
            A.CallTo(() => textIndex.SearchAsync(requestContext.App, new GeoQuery(schemaId.Id, "geo.iv", 10, 20, 30), requestContext.Scope()))
            .Returns(new List <DomainId> {
                DomainId.Create("1")
            });

            var query = Q.Empty.WithODataQuery("$filter=geo.distance(data/geo/iv, geography'POINT(20 10)') lt 30.0");

            var q = await sut.ParseAsync(requestContext, query, schema);

            Assert.Equal("Filter: id in ['1']; Take: 30; Sort: lastModified Descending, id Ascending", q.Query.ToString());
        }
示例#17
0
        private async Task <List <DomainId> > SearchByAppAsync(string queryText, IAppEntity app, SearchScope scope, int limit)
        {
            var bySchema =
                await Collection.Find(
                    Filter.And(
                        Filter.Eq(x => x.AppId, app.Id),
                        Filter.Exists(x => x.SchemaId),
                        Filter_ByScope(scope),
                        Filter.Text(queryText)))
                .Only(x => x.ContentId).Limit(limit)
                .ToListAsync();

            return(bySchema.Select(x => DomainId.Create(x["_ci"].AsString)).Distinct().ToList());
        }
示例#18
0
        public async Task <IReadOnlyList <DomainId> > QueryIdsAsync(DomainId appId, HashSet <DomainId> ids,
                                                                    CancellationToken ct = default)
        {
            using (Telemetry.Activities.StartActivity("ContentQueryService/QueryIdsAsync"))
            {
                var assetEntities =
                    await Collection.Find(BuildFilter(appId, ids)).Only(x => x.Id)
                    .ToListAsync(ct);

                var field = Field.Of <MongoAssetFolderEntity>(x => nameof(x.Id));

                return(assetEntities.Select(x => DomainId.Create(x[field].AsString)).ToList());
            }
        }
示例#19
0
        public async Task <IReadOnlyList <DomainId> > QueryChildIdsAsync(DomainId appId, DomainId parentId,
                                                                         CancellationToken ct = default)
        {
            using (Profiler.TraceMethod <MongoAssetRepository>())
            {
                var assetEntities =
                    await Collection.Find(x => x.IndexedAppId == appId && !x.IsDeleted && x.ParentId == parentId).Only(x => x.Id)
                    .ToListAsync(ct);

                var field = Field.Of <MongoAssetFolderEntity>(x => nameof(x.Id));

                return(assetEntities.Select(x => DomainId.Create(x[field].AsString)).ToList());
            }
        }
示例#20
0
        public async Task <IReadOnlyList <DomainId> > QueryChildIdsAsync(DomainId appId, DomainId parentId,
                                                                         CancellationToken ct = default)
        {
            using (Telemetry.Activities.StartActivity("ContentQueryService/QueryChildIdsAsync"))
            {
                var assetEntities =
                    await Collection.Find(x => x.IndexedAppId == appId && !x.IsDeleted && x.ParentId == parentId).Only(x => x.Id)
                    .ToListAsync(ct);

                var field = Field.Of <MongoAssetFolderEntity>(x => nameof(x.Id));

                return(assetEntities.Select(x => DomainId.Create(x[field].AsString)).ToList());
            }
        }
示例#21
0
        public async Task <IReadOnlyList <DomainId> > QueryIdsAsync(DomainId appId, HashSet <DomainId> ids,
                                                                    CancellationToken ct = default)
        {
            using (Profiler.TraceMethod <MongoAssetRepository>("QueryAsyncByIds"))
            {
                var assetEntities =
                    await Collection.Find(BuildFilter(appId, ids)).Only(x => x.Id)
                    .ToListAsync(ct);

                var field = Field.Of <MongoAssetFolderEntity>(x => nameof(x.Id));

                return(assetEntities.Select(x => DomainId.Create(x[field].AsString)).ToList());
            }
        }
示例#22
0
        private async Task GetReferencesAsync(ExecutionContext context, DomainId appId, ClaimsPrincipal user, JsValue references, Action <JsValue> callback)
        {
            Guard.NotNull(callback, nameof(callback));

            var ids = new List <DomainId>();

            if (references.IsString())
            {
                ids.Add(DomainId.Create(references.ToString()));
            }
            else if (references.IsArray())
            {
                foreach (var value in references.AsArray())
                {
                    if (value.IsString())
                    {
                        ids.Add(DomainId.Create(value.ToString()));
                    }
                }
            }

            if (ids.Count == 0)
            {
                var emptyAssets = Array.Empty <IEnrichedAssetEntity>();

                callback(JsValue.FromObject(context.Engine, emptyAssets));
                return;
            }

            context.MarkAsync();

            try
            {
                var app = await GetAppAsync(appId);

                var requestContext =
                    new Context(user, app).Clone(b => b
                                                 .WithoutTotal());

                var assetQuery = serviceProvider.GetRequiredService <IAssetQueryService>();

                var assets = await assetQuery.QueryAsync(requestContext, null, Q.Empty.WithIds(ids), context.CancellationToken);

                callback(JsValue.FromObject(context.Engine, assets.ToArray()));
            }
            catch (Exception ex)
            {
                context.Fail(ex);
            }
        }
示例#23
0
            public static IFieldResolver Resolver(NamedId <DomainId> appId, NamedId <DomainId> schemaId)
            {
                return(ResolveAsync <IEnrichedContentEntity>(appId, schemaId, c =>
                {
                    var contentPublish = c.GetArgument <bool>("publish");
                    var contentData = GetContentData(c);
                    var contentId = c.GetArgument <string>("id");

                    var id = DomainId.Create(contentId);

                    return new UpsertContent {
                        ContentId = id, Data = contentData, Publish = contentPublish
                    };
                }));
            }
示例#24
0
        private Task <ISchemaEntity?> GetSchemaAsync(DomainId appId, string schemaIdOrName, ClaimsPrincipal user)
        {
            var canCache = !user.IsInClient(DefaultClients.Frontend);

            if (Guid.TryParse(schemaIdOrName, out var guid))
            {
                var schemaId = DomainId.Create(guid);

                return(appProvider.GetSchemaAsync(appId, schemaId, canCache));
            }
            else
            {
                return(appProvider.GetSchemaAsync(appId, schemaIdOrName, canCache));
            }
        }
示例#25
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));
        }
示例#26
0
        private async Task <List <DomainId> > SearchByAppAsync(string queryText, IAppEntity app, SearchScope scope, int limit)
        {
            var bySchema =
                await GetCollection(scope).Find(
                    Filter.And(
                        Filter.Eq(x => x.AppId, app.Id),
                        Filter.Exists(x => x.SchemaId),
                        Filter_ByScope(scope),
                        Filter.Text(queryText, "none")))
                .Limit(limit).Only(x => x.ContentId)
                .ToListAsync();

            var field = Field.Of <MongoTextIndexEntity>(x => nameof(x.ContentId));

            return(bySchema.Select(x => DomainId.Create(x[field].AsString)).Distinct().ToList());
        }
示例#27
0
        public async Task <List <DomainId>?> SearchAsync(IAppEntity app, GeoQuery query, SearchScope scope)
        {
            var byGeo =
                await GetCollection(scope).Find(
                    Filter.And(
                        Filter.Eq(x => x.AppId, app.Id),
                        Filter.Eq(x => x.SchemaId, query.SchemaId),
                        Filter_ByScope(scope),
                        Filter.GeoWithinCenterSphere(x => x.GeoObject, query.Longitude, query.Latitude, query.Radius / 6378100)))
                .Limit(Limit).Only(x => x.ContentId)
                .ToListAsync();

            var field = Field.Of <MongoTextIndexEntity>(x => nameof(x.ContentId));

            return(byGeo.Select(x => DomainId.Create(x[field].AsString)).Distinct().ToList());
        }
        public async Task <IReadOnlyList <DomainId> > QueryChildIdsAsync(DomainId appId, DomainId parentId,
                                                                         CancellationToken ct = default)
        {
            using (Telemetry.Activities.StartActivity("MongoAssetFolderRepository/QueryChildIdsAsync"))
            {
                var filter = BuildFilter(appId, parentId);

                var assetFolderEntities =
                    await Collection.Find(filter).Only(x => x.Id)
                    .ToListAsync(ct);

                var field = Field.Of <MongoAssetFolderEntity>(x => nameof(x.Id));

                return(assetFolderEntities.Select(x => DomainId.Create(x[field].AsString)).ToList());
            }
        }
示例#29
0
        public ContentChangedTriggerSchemaV2 Migrate()
        {
            var conditions = new List <string>();

            if (SendCreate)
            {
                conditions.Add($"event.type == '{EnrichedContentEventType.Created}'");
            }

            if (SendUpdate)
            {
                conditions.Add($"event.type == '{EnrichedContentEventType.Updated}'");
            }

            if (SendPublish)
            {
                conditions.Add($"event.type == '{EnrichedContentEventType.Published}'");
            }

            if (SendArchived)
            {
                conditions.Add($"event.status == 'Archived'");
            }

            if (SendDelete)
            {
                conditions.Add($"event.type == '{EnrichedAssetEventType.Deleted}'");
            }

            var condition = string.Empty;

            if (conditions.Count == 0 && condition.Length < 7)
            {
                condition = "false";
            }
            else if (condition.Length < 7)
            {
                condition = string.Join(" || ", conditions);
            }

            var schemaId = DomainId.Create(SchemaId);

            return(new ContentChangedTriggerSchemaV2 {
                SchemaId = schemaId, Condition = condition
            });
        }
示例#30
0
        private static async Task <Dictionary <string, DomainId> > QueryAsync(IFindFluent <MongoAppEntity, MongoAppEntity> find,
                                                                              CancellationToken ct)
        {
            var entities = await find.SortBy(x => x.IndexedCreated).Only(x => x.DocumentId, x => x.IndexedName).ToListAsync(ct);

            var result = new Dictionary <string, DomainId>();

            foreach (var entity in entities)
            {
                var indexedId   = DomainId.Create(entity["_id"].AsString);
                var indexedName = entity["_an"].AsString;

                result[indexedName] = indexedId;
            }

            return(result);
        }