private async Task QueryCollectionAsync(HttpContext httpContext, StatefulServiceContext serviceContext, IReliableStateManager stateManager, string collection, Guid partitionId) { if (partitionId != serviceContext.PartitionId) { // Query this partition. await ForwardQueryCollectionAsync(httpContext, serviceContext, stateManager, collection, partitionId).ConfigureAwait(false); return; } // Query the local reliable collection. var query = httpContext.Request.Query.Select(p => new KeyValuePair <string, string>(p.Key, p.Value)); var results = await stateManager.QueryPartitionAsync(collection, query, partitionId, CancellationToken.None).ConfigureAwait(false); httpContext.Response.ContentType = "application/json"; httpContext.Response.StatusCode = (int)HttpStatusCode.OK; // Write the response. var result = new ODataResult { ODataMetadata = "", Value = results, }; string response = JsonConvert.SerializeObject(result); await httpContext.Response.WriteAsync(response).ConfigureAwait(false); }
/// <summary> /// Query the reliable collection with the given name from the reliable state manager using the given query parameters. /// </summary> /// <param name="stateManager">Reliable state manager for the replica.</param> /// <param name="serviceContext">Stateful Service Context.</param> /// <param name="collection">Name of the reliable collection.</param> /// <param name="query">OData query parameters.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>The json serialized results of the query.</returns> public static async Task <IEnumerable <JToken> > QueryAsync(this IReliableStateManager stateManager, StatefulServiceContext serviceContext, HttpContext httpContext, string collection, IEnumerable <KeyValuePair <string, string> > query, bool isStandaloneReplica, CancellationToken cancellationToken) { // Get the list of partitions (excluding the executing partition). var partitions = Enumerable.Empty <Partition>(); if (!isStandaloneReplica) { partitions = await StatefulServiceUtils.GetPartitionsAsync(serviceContext).ConfigureAwait(false); } // Query all service partitions concurrently. var remoteQueries = partitions.Select(p => QueryPartitionAsync(p, serviceContext, collection, query, cancellationToken)); var localQuery = stateManager.QueryPartitionAsync(httpContext, collection, query, serviceContext.PartitionId, cancellationToken); var queries = remoteQueries.Concat(new[] { localQuery }); // Aggregate all query results into a single list. var queryResults = await Task.WhenAll(queries).ConfigureAwait(false); var results = queryResults.SelectMany(r => r); // Run the aggregation query to get the final results (e.g. for top, orderby, project). var reliableState = await stateManager.GetQueryableState(httpContext, collection).ConfigureAwait(false); var entityType = reliableState.GetEntityType(); var objects = results.Select(r => r.ToObject(entityType)); var queryResult = ApplyQuery(objects, entityType, query, aggregate: true); results = queryResult.Select(q => JObject.FromObject(q)); // Return the filtered data as json. return(results); }
Task <IEnumerable <string> > IQueryableService.QueryPartitionAsync(string collection, IEnumerable <KeyValuePair <string, string> > query) { return(StateManager.QueryPartitionAsync(collection, query, CancellationToken.None)); }
/// <summary> /// Query the reliable collection with the given name from the reliable state manager using the given query parameters. /// </summary> /// <param name="stateManager">Reliable state manager for the replica.</param> /// <param name="collection">Name of the reliable collection.</param> /// <param name="query">OData query parameters.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>The json serialized results of the query.</returns> public static async Task <IEnumerable <string> > QueryAsync(this IReliableStateManager stateManager, StatefulServiceContext context, string collection, IEnumerable <KeyValuePair <string, string> > query, CancellationToken cancellationToken) { // Query all service partitions concurrently. var proxies = await GetServiceProxiesAsync <IQueryableService>(context).ConfigureAwait(false); var queries = proxies.Select(p => p.QueryPartitionAsync(collection, query)).Concat(new[] { stateManager.QueryPartitionAsync(collection, query, cancellationToken) }); var queryResults = await Task.WhenAll(queries).ConfigureAwait(false); var results = queryResults.SelectMany(r => r); // Run the aggregation query to get the final results (e.g. for top, orderby, project). if (query.Any()) { var reliableState = await stateManager.GetQueryableState(collection).ConfigureAwait(false); var valueType = reliableState.GetValueType(); var objects = results.Select(r => JsonConvert.DeserializeObject(r, valueType)); var queryResult = ApplyQuery(objects, valueType, query, aggregate: true); results = queryResult.Select(JsonConvert.SerializeObject); } // Return the filtered data as json. return(results); }