public async Task <IReadOnlyCollection <ResourceSearchParameterStatus> > GetSearchParameterStatuses() { using var cancellationSource = new CancellationTokenSource(TimeSpan.FromMinutes(1)); var parameterStatus = new List <ResourceSearchParameterStatus>(); using IScoped <Container> clientScope = _containerScopeFactory.Invoke(); do { var query = _queryFactory.Create <SearchParameterStatusWrapper>( clientScope.Value, new CosmosQueryContext( new QueryDefinition("select * from c"), new QueryRequestOptions { PartitionKey = new PartitionKey(SearchParameterStatusWrapper.SearchParameterStatusPartitionKey), })); do { FeedResponse <SearchParameterStatusWrapper> results = await query.ExecuteNextAsync(); parameterStatus.AddRange(results.Select(x => x.ToSearchParameterStatus())); }while (query.HasMoreResults); if (!parameterStatus.Any()) { await Task.Delay(TimeSpan.FromSeconds(1), cancellationSource.Token); } }while (!parameterStatus.Any() && !cancellationSource.IsCancellationRequested); return(parameterStatus); }
private async Task <SearchResult> ExecuteSearchAsync( SqlQuerySpec sqlQuerySpec, SearchOptions searchOptions, CancellationToken cancellationToken) { var feedOptions = new FeedOptions { EnableCrossPartitionQuery = true, MaxItemCount = searchOptions.MaxItemCount, RequestContinuation = searchOptions.ContinuationToken, }; if (searchOptions.CountOnly) { return(new SearchResult( (await _fhirDataStore.ExecuteDocumentQueryAsync <int>(sqlQuerySpec, feedOptions, cancellationToken)).Single(), searchOptions.UnsupportedSearchParams)); } FeedResponse <Document> fetchedResults = await _fhirDataStore.ExecuteDocumentQueryAsync <Document>(sqlQuerySpec, feedOptions, cancellationToken); FhirCosmosResourceWrapper[] wrappers = fetchedResults .Select(r => r.GetPropertyValue <FhirCosmosResourceWrapper>(SearchValueConstants.RootAliasName)).ToArray(); return(new SearchResult( wrappers, searchOptions.UnsupportedSearchParams, fetchedResults.ResponseContinuation)); }
public async Task <ConversationList> GetConversations(string username, string continuationToken, int limit, long lastSeenConversationTime) { try { var feedOptions = new FeedOptions { MaxItemCount = limit, EnableCrossPartitionQuery = false, RequestContinuation = continuationToken, PartitionKey = new PartitionKey($"c_{username}") }; IQueryable <DocumentDbConversationEntity> query = _documentClient.CreateDocumentQuery <DocumentDbConversationEntity>(DocumentCollectionUri, feedOptions) .OrderByDescending(entity => entity.LastModifiedUnixTime) .Where(entity => entity.LastModifiedUnixTime > lastSeenConversationTime); FeedResponse <DocumentDbConversationEntity> feedResponse = await query.AsDocumentQuery().ExecuteNextAsync <DocumentDbConversationEntity>(); return(new ConversationList { ContinuationToken = feedResponse.ResponseContinuation, Conversations = feedResponse.Select(ToConversationsListEntry).ToArray() }); } catch (DocumentClientException e) { if ((int)e.StatusCode == 404) { throw new ConversationNotFoundException($"No conversations associated to user {username} were found in storage"); } throw new StorageErrorException($"Failed to list conversations of user {username}", e); } }
public async Task <IReadOnlyCollection <ResourceSearchParameterStatus> > GetSearchParameterStatuses() { var parameterStatus = new List <ResourceSearchParameterStatus>(); using var clientScope = _documentClientFactory.Invoke(); var query = _queryFactory.Create <SearchParameterStatusWrapper>( clientScope.Value, new CosmosQueryContext( CollectionUri, new SqlQuerySpec("select * from c"), new FeedOptions { PartitionKey = new PartitionKey(SearchParameterStatusWrapper.SearchParameterStatusPartitionKey), })); do { FeedResponse <SearchParameterStatusWrapper> results = await query.ExecuteNextAsync <SearchParameterStatusWrapper>(); parameterStatus.AddRange(results .Select(x => x.ToSearchParameterStatus())); }while (query.HasMoreResults); return(parameterStatus); }
public async Task <T> Load <T>(Guid aggregateId, CancellationToken cancellationToken = default) where T : IAggregate, new() { var aggregate = new T(); var containerName = CosmosExtensions.GetContainerName <T>(); var db = await _client.CreateDatabaseIfNotExistsAsync("LoyaltyCardDB"); var container = await db.Database.CreateContainerIfNotExistsAsync(containerName, "/AggregateId"); QueryDefinition query = new QueryDefinition("select * from t where t.AggregateId = @aggregateId") .WithParameter("@aggregateId", aggregateId.ToString()); FeedIterator <EventData> queryResultSetIterator = container.Container.GetItemQueryIterator <EventData>(query); while (queryResultSetIterator.HasMoreResults) { FeedResponse <EventData> currentResultSet = await queryResultSetIterator.ReadNextAsync(); aggregate.Load( currentResultSet.Last().Version, Enumerable.ToArray(currentResultSet.Select(re => _serializer.DeserializeFromJson(re.Data, re.EventType)))); } return(aggregate); }
public async Task <MessageList> GetMessages(string conversationId, string continuationToken, int limit, long lastSeenMessageTime) { try { var feedOptions = new FeedOptions { MaxItemCount = limit, EnableCrossPartitionQuery = false, RequestContinuation = continuationToken, PartitionKey = new PartitionKey($"m_{conversationId}") }; IQueryable <DocumentDbMessageEntity> query = _documentClient.CreateDocumentQuery <DocumentDbMessageEntity>(DocumentCollectionUri, feedOptions) .OrderByDescending(entity => entity.UnixTime) .Where(entity => entity.UnixTime > lastSeenMessageTime); FeedResponse <DocumentDbMessageEntity> feedResponse = await query.AsDocumentQuery().ExecuteNextAsync <DocumentDbMessageEntity>(); return(new MessageList { ContinuationToken = feedResponse.ResponseContinuation, Messages = feedResponse.Select(ToMessagesResponseEntry).ToArray() }); } catch (DocumentClientException e) { if ((int)e.StatusCode == 404) { throw new ConversationNotFoundException($"ConversationId {conversationId} was not found in storage"); } throw new StorageErrorException($"Failed to list messages in conversation {conversationId}", e); } }
public async Task <GetAccountsResult> GetAccounts(string continuationToken, int limit, string role) { try { var feedOptions = new FeedOptions { MaxItemCount = limit, EnableCrossPartitionQuery = false, RequestContinuation = continuationToken, PartitionKey = new PartitionKey("FYP") }; IQueryable <DocumentDbAccountEntity> query = _documentClient.CreateDocumentQuery <DocumentDbAccountEntity>(DocumentCollectionUri, feedOptions); if (!string.IsNullOrWhiteSpace(role)) { query.Where(x => x.Role.Equals(role)); } FeedResponse <DocumentDbAccountEntity> feedResponse = await query.AsDocumentQuery().ExecuteNextAsync <DocumentDbAccountEntity>(); return(new GetAccountsResult { ContinuationToken = feedResponse.ResponseContinuation, Accounts = feedResponse.Select(ToAccount).ToList() }); } catch (DocumentClientException e) { throw new StorageErrorException($"Failed to list accounts", e, (int)e.StatusCode); } }
public async Task <GetStudentsResult> GetStudents(string courseName, string continuationToken, int limit) { try { var feedOptions = new FeedOptions { MaxItemCount = limit, EnableCrossPartitionQuery = false, RequestContinuation = continuationToken, PartitionKey = new PartitionKey(courseName) }; IQueryable <DocumentDbStudentEntity> query = _documentClient.CreateDocumentQuery <DocumentDbStudentEntity>(DocumentCollectionUri, feedOptions) .OrderByDescending(entity => entity.GradePercentage); // much easier ordering than Azure table! // you can also add a where statement as follows if you needed to get all students with a minimal grade // query = query.Where(entity => entity.GradePercentage > 90); FeedResponse <DocumentDbStudentEntity> feedResponse = await query.AsDocumentQuery().ExecuteNextAsync <DocumentDbStudentEntity>(); return(new GetStudentsResult { ContinuationToken = feedResponse.ResponseContinuation, Students = feedResponse.Select(ToStudent).ToList() }); } catch (DocumentClientException e) { throw new StorageErrorException($"Failed to list students from course {courseName}", e, (int)e.StatusCode); } }
private async Task <SearchResult> ExecuteSearchAsync( SqlQuerySpec sqlQuerySpec, SearchOptions searchOptions, CancellationToken cancellationToken) { string ct = null; if (!string.IsNullOrEmpty(searchOptions.ContinuationToken)) { ct = await _continuationTokenCache.GetContinuationTokenAsync(searchOptions.ContinuationToken, cancellationToken); } var feedOptions = new FeedOptions { EnableCrossPartitionQuery = true, MaxItemCount = searchOptions.MaxItemCount, RequestContinuation = ct, }; if (searchOptions.CountOnly) { IDocumentQuery <int> documentCountQuery = _cosmosDataStore.CreateDocumentQuery <int>(sqlQuerySpec, feedOptions); using (documentCountQuery) { return(new SearchResult(Enumerable.Empty <ResourceWrapper>(), null) { TotalCount = (await documentCountQuery.ExecuteNextAsync <int>(cancellationToken)).Single(), }); } } IDocumentQuery <Document> documentQuery = _cosmosDataStore.CreateDocumentQuery <Document>( sqlQuerySpec, feedOptions); using (documentQuery) { Debug.Assert(documentQuery != null, $"The {nameof(documentQuery)} should not be null."); FeedResponse <Document> fetchedResults = await documentQuery.ExecuteNextAsync <Document>(cancellationToken); CosmosResourceWrapper[] wrappers = fetchedResults .Select(r => r.GetPropertyValue <CosmosResourceWrapper>(SearchValueConstants.RootAliasName)).ToArray(); string continuationTokenId = null; // TODO: Eventually, we will need to take a snapshot of the search and manage the continuation // tokens ourselves since there might be multiple continuation token involved depending on // the search. if (!string.IsNullOrEmpty(fetchedResults.ResponseContinuation)) { continuationTokenId = await _continuationTokenCache.SaveContinuationTokenAsync(fetchedResults.ResponseContinuation, cancellationToken); } return(new SearchResult(wrappers, continuationTokenId)); } }
public async Task <IEnumerable <DomainEventWrapper> > GetAggregateEvents(Guid aggregateRootId, int startSequenceNumber) { IDocumentQuery <TEventSet> eventQuery = Client .CreateDocumentQuery <TEventSet>(_databaseCollectionUri) .Where(eventSet => eventSet.AggregateId == aggregateRootId && eventSet.Sequence > startSequenceNumber) .AsDocumentQuery(); FeedResponse <TEventSet> result = await eventQuery.ExecuteNextAsync <TEventSet>(); return(result.Select(GetDomainEventWrapperFromEvent)); }
public async Task <IEnumerable <DomainEventWrapper> > GetAggregateEvents(Guid aggregateRootId, IEnumerable <Type> domainEventTypes) { HashSet <string> domainEventTypeNames = new HashSet <string>(domainEventTypes.Select(t => t.FullName)); IDocumentQuery <TEventSet> eventQuery = Client .CreateDocumentQuery <TEventSet>(_databaseCollectionUri) .Where(eventSet => eventSet.AggregateId == aggregateRootId && domainEventTypeNames.Contains(eventSet.Name)) .AsDocumentQuery(); FeedResponse <TEventSet> result = await eventQuery.ExecuteNextAsync <TEventSet>(); return(result.Select(GetDomainEventWrapperFromEvent)); }
public async Task <IEnumerable <DomainEventWrapper> > GetAggregateEvents <TDomainEvent>(Guid aggregateRootId) where TDomainEvent : IDomainEvent { string domainEventName = typeof(TDomainEvent).FullName; IDocumentQuery <TEventSet> eventQuery = Client .CreateDocumentQuery <TEventSet>(_databaseCollectionUri) .Where(eventSet => eventSet.AggregateId == aggregateRootId && eventSet.Name.Equals(domainEventName)) .AsDocumentQuery(); FeedResponse <TEventSet> result = await eventQuery.ExecuteNextAsync <TEventSet>(); return(result.Select(GetDomainEventWrapperFromEvent)); }
public async Task <List <string> > GetRegistrantsForEvent(string eventKey) { //return await Task.FromResult(default(List<string>)); IDocumentQuery <GeneralRegistration> query = Client.CreateDocumentQuery <GeneralRegistration>(Collection.SelfLink).Where(r => r.EventKey == eventKey).AsDocumentQuery(); List <string> registrants = new List <string>(); while (query.HasMoreResults) { FeedResponse <GeneralRegistration> results = await query.ExecuteNextAsync <GeneralRegistration>(); IEnumerable <string> resultNames = results.Select(r => $"{r.FirstName} {r.LastName}"); registrants.AddRange(resultNames); } return(registrants); }
public async Task <GetMessagesResult> GetMessages(string conversationId, string continuationToken, int limit, long lastSeenMessageTime) { try { var feedOptions = new FeedOptions { MaxItemCount = limit, EnableCrossPartitionQuery = false, RequestContinuation = continuationToken, PartitionKey = new PartitionKey("m_" + conversationId) }; IQueryable <DocumentDbMessageEntity> query = _documentClient.CreateDocumentQuery <DocumentDbMessageEntity>(DocumentCollectionUri, feedOptions) .Where(message => message.UnixTime > lastSeenMessageTime).OrderByDescending(entity => entity.UnixTime); FeedResponse <DocumentDbMessageEntity> feedResponse = await query.AsDocumentQuery().ExecuteNextAsync <DocumentDbMessageEntity>(); var messages = new List <MessagesInfo>(); var messagesList = feedResponse.Select(ToMessage).ToList(); foreach (var message in messagesList) { var messageInfo = new MessagesInfo { Text = message.Text, SenderUsername = message.SenderUsername, UnixTime = message.UnixTime }; messages.Add(messageInfo); } return(new GetMessagesResult { ContinuationToken = feedResponse.ResponseContinuation, Messages = messages }); } catch (DocumentClientException e) { if (e.StatusCode == HttpStatusCode.NotFound) { throw new MessageNotFoundException($"Conversation with id {conversationId} was not found"); } throw new StorageErrorException($"Failed to get {limit} messages from conversation {conversationId}", e, (int)e.StatusCode); } }
public async Task <GetConversationsResult> GetConversations(string username, string continuationToken, int limit, long lastSeenConversationTime) { try { var feedOptions = new FeedOptions { MaxItemCount = limit, EnableCrossPartitionQuery = false, RequestContinuation = continuationToken, PartitionKey = new PartitionKey("c_" + username) }; IQueryable <DocumentDbConversationEntity> query = _documentClient.CreateDocumentQuery <DocumentDbConversationEntity>(DocumentCollectionUri, feedOptions) .Where(conversation => conversation.LastModifiedUnixTime > lastSeenConversationTime).OrderByDescending(entity => entity.LastModifiedUnixTime); FeedResponse <DocumentDbConversationEntity> feedResponse = await query.AsDocumentQuery().ExecuteNextAsync <DocumentDbConversationEntity>(); var conversationsInfo = new List <ConversationsInfo>(); var conversationsList = feedResponse.Select(ToConversation).ToList(); foreach (var conversation in conversationsList) { var conversationInfo = new ConversationsInfo { Id = conversation.Id.Remove(0, 2), LastModifiedUnixTime = conversation.LastModifiedUnixTime, Recipient = new UserProfile() }; conversationsInfo.Add(conversationInfo); } return(new GetConversationsResult { ContinuationToken = feedResponse.ResponseContinuation, Conversations = conversationsInfo }); } catch (DocumentClientException e) { if (e.StatusCode == HttpStatusCode.NotFound) { throw new ConversationNotFoundException($"{username} was not found"); } throw new StorageErrorException($"Failed to retrieve conversations from User {username}", e, (int)e.StatusCode); } }
private async Task <SearchResult> ExecuteSearchAsync( SqlQuerySpec sqlQuerySpec, SearchOptions searchOptions, CancellationToken cancellationToken) { var feedOptions = new FeedOptions { EnableCrossPartitionQuery = true, MaxItemCount = searchOptions.MaxItemCount, RequestContinuation = searchOptions.ContinuationToken, }; if (searchOptions.CountOnly) { IDocumentQuery <int> documentCountQuery = _fhirDataStore.CreateDocumentQuery <int>(sqlQuerySpec, feedOptions); using (documentCountQuery) { return(new SearchResult( (await documentCountQuery.ExecuteNextAsync <int>(cancellationToken)).Single(), searchOptions.UnsupportedSearchParams)); } } IDocumentQuery <Document> documentQuery = _fhirDataStore.CreateDocumentQuery <Document>( sqlQuerySpec, feedOptions); using (documentQuery) { Debug.Assert(documentQuery != null, $"The {nameof(documentQuery)} should not be null."); FeedResponse <Document> fetchedResults = await documentQuery.ExecuteNextAsync <Document>(cancellationToken); FhirCosmosResourceWrapper[] wrappers = fetchedResults .Select(r => r.GetPropertyValue <FhirCosmosResourceWrapper>(SearchValueConstants.RootAliasName)).ToArray(); return(new SearchResult( wrappers, searchOptions.UnsupportedSearchParams, fetchedResults.ResponseContinuation)); } }
private async Task <SearchResult> ExecuteSearchAsync( SqlQuerySpec sqlQuerySpec, SearchOptions searchOptions, CancellationToken cancellationToken, bool calculateTotalCount = false) { var feedOptions = new FeedOptions { EnableCrossPartitionQuery = true, MaxItemCount = searchOptions.MaxItemCount, RequestContinuation = searchOptions.ContinuationToken, }; if (searchOptions.CountOnly || calculateTotalCount) { return(new SearchResult( (await _fhirDataStore.ExecuteDocumentQueryAsync <int>(sqlQuerySpec, feedOptions, cancellationToken)).Single(), searchOptions.UnsupportedSearchParams)); } FeedResponse <Document> fetchedResults = await _fhirDataStore.ExecuteDocumentQueryAsync <Document>(sqlQuerySpec, feedOptions, cancellationToken); SearchResultEntry[] wrappers = fetchedResults .Select(r => new SearchResultEntry(r.GetPropertyValue <FhirCosmosResourceWrapper>(SearchValueConstants.RootAliasName))).ToArray(); IReadOnlyList <(string parameterName, string reason)> unsupportedSortingParameters; if (searchOptions.Sort?.Count > 0) { // we don't currently support sort unsupportedSortingParameters = searchOptions.UnsupportedSortingParams.Concat(searchOptions.Sort.Select(s => (s.searchParameterInfo.Name, Core.Resources.SortNotSupported))).ToList(); } else { unsupportedSortingParameters = searchOptions.UnsupportedSortingParams; } return(new SearchResult( wrappers, searchOptions.UnsupportedSearchParams, unsupportedSortingParameters, fetchedResults.ResponseContinuation)); }
/// <inheritdoc/> public async Task <IEnumerable <string> > GetMatchingWorkflowInstanceIdsForSubjectsAsync( IEnumerable <string> subjects, int pageSize, int pageNumber) { QueryDefinition spec = BuildFindInstanceIdsSpec(subjects, pageSize, pageNumber); FeedIterator <dynamic> iterator = this.Container.GetItemQueryIterator <dynamic>(spec); var matchingIds = new List <string>(); while (iterator.HasMoreResults) { FeedResponse <dynamic> results = await Retriable.RetryAsync(() => iterator.ReadNextAsync()).ConfigureAwait(false); matchingIds.AddRange(results.Select(x => (string)x.id)); } return(matchingIds); }
public async Task <FetchModelCollectionResult <TestModel2> > FetchTestModel2ByDateAsync(DateTime filterDate) { var result = new FetchModelCollectionResult <TestModel2>(); var allItems = new List <TestModel2>(); //all stored dates are in utc - make sure apples == apples filterDate = filterDate.ToUniversalTime(); try { result.Notification = CheckServiceCanOperate(); if (!result.IsValid()) { return(result); } var queryable = _container.GetItemLinqQueryable <CosmosDocument <TestModel2> >(allowSynchronousQueryExecution: true, requestOptions: PartitionRequestOptions); var query = queryable.Where(cd => cd.Model.Date >= filterDate.Date && cd.Model.Date <= filterDate.AddDays(1).Date); var iterator = query.ToFeedIterator(); using (iterator) { while (iterator.HasMoreResults) { FeedResponse <CosmosDocument <TestModel2> > response = await iterator.ReadNextAsync(); allItems.AddRange(response.Select(d => d.Model)); } } result.ModelCollection = allItems; } catch { Debug.WriteLine($"Error while trying to fetch all {typeof(TestModel2).Name} items from cosmos"); result.Fail("Error"); } return(result); }
public async Task <FetchModelCollectionResult <T> > FetchModelCollectionAsync <T>() where T : ModelBase, new() { //doc: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/ItemManagement/Program.cs var result = new FetchModelCollectionResult <T>(); var allItems = new List <T>(); try { result.Notification = CheckServiceCanOperate(); if (!result.IsValid()) { return(result); } var queryable = _container.GetItemLinqQueryable <CosmosDocument <T> >(requestOptions: PartitionRequestOptions); var query = queryable.Where(cd => cd.Type == typeof(T).Name); var iterator = query.ToFeedIterator(); using (iterator) { while (iterator.HasMoreResults) { FeedResponse <CosmosDocument <T> > response = await iterator.ReadNextAsync(); allItems.AddRange(response.Select(d => d.Model)); } } result.ModelCollection = allItems; } catch { Debug.WriteLine($"Error while trying to fetch all {typeof(T).Name} items from cosmos"); result.Fail("Error"); } return(result); }
public async Task <CosmosDbViewModel> AccessCosmosDb() { Container container = _cosmosClient.GetContainer(_settings.CosmosDbDatabaseId, _settings.CosmosDbContainerId); FeedIterator <CosmosItemModel> iterator = container.GetItemQueryIterator <CosmosItemModel>("SELECT * FROM c"); var result = new CosmosDbViewModel { Documents = new List <CosmosDocumentModel>() }; while (iterator.HasMoreResults) { FeedResponse <CosmosItemModel> response = await iterator.ReadNextAsync(); result.Documents.AddRange(response.Select(x => new CosmosDocumentModel { Id = x.Id, Value = x.Value })); } return(result); }