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); } }
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)); }
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()); } }
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); }
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 }); }
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); }
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()); } }
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)); } }
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)); }
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()); }
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()); }
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)); }
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()); }
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()); }
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()); } }
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()); } }
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()); } }
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()); } }
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); } }
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 }; })); }
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)); } }
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)); }
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()); }
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()); } }
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 }); }
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); }