Пример #1
0
        public IActionResult GetManifestItems(string id)
        {
            var response = new ManifestSearchResponse();

            return(new OkObjectResult(response));
        }
Пример #2
0
        /// <inheritdoc />
        public async Task <ApiDataPage <ManifestSearchResponse> > SearchPackageManifests(ManifestSearchRequest manifestSearchRequest, Dictionary <string, string> headers, IQueryCollection queryParameters)
        {
            // Create Working Set and return
            ApiDataPage <ManifestSearchResponse> apiDataPage     = new ApiDataPage <ManifestSearchResponse>();
            List <PackageManifest>        manifests              = new List <PackageManifest>();
            List <ManifestSearchResponse> manifestSearchResponse = new List <ManifestSearchResponse>();

            // Create feed options for inclusion search: -1 so we can get all matches in inclusion, then filter down.
            FeedOptions feedOptions = new FeedOptions
            {
                ResponseContinuationTokenLimitInKb = CosmosConnectionConstants.ResponseContinuationTokenLimitInKb,
                EnableCrossPartitionQuery          = true,
                MaxItemCount        = AllElements,
                RequestContinuation = null,
            };

            if (manifestSearchRequest.FetchAllManifests || (manifestSearchRequest.Inclusions == null && manifestSearchRequest.Query == null))
            {
                IQueryable <CosmosPackageManifest>     query           = this.cosmosDatabase.GetIQueryable <CosmosPackageManifest>(feedOptions);
                IDocumentQuery <CosmosPackageManifest> documentQuery   = query.AsDocumentQuery();
                ApiDataPage <CosmosPackageManifest>    apiDataDocument = await this.cosmosDatabase.GetByDocumentQuery <CosmosPackageManifest>(documentQuery);

                manifests.AddRange(apiDataDocument.Items);
            }
            else
            {
                // Process Inclusions
                Models.Arrays.SearchRequestPackageMatchFilter inclusions = new Models.Arrays.SearchRequestPackageMatchFilter();
                if (manifestSearchRequest.Inclusions != null)
                {
                    inclusions.AddRange(manifestSearchRequest.Inclusions);
                }

                // Convert Query to inclusions to submit to cosmos
                if (manifestSearchRequest.Query != null)
                {
                    inclusions.AddRange(this.queryList.Select(q => new Models.Objects.SearchRequestPackageMatchFilter()
                    {
                        PackageMatchField = q,
                        RequestMatch      = manifestSearchRequest.Query,
                    }));
                }

                // Submit Inclusions to Cosmos
                // Due to join limitation on Cosmos - we are submitting each predicate separately.
                // TODO: Create a more efficient search - but this will suffice for now for a light weight reference.
                if (inclusions.Count > 0)
                {
                    List <Task <ApiDataPage <PackageManifest> > > taskSet = new List <Task <ApiDataPage <PackageManifest> > >();
                    foreach (string packageMatchField in inclusions.Select(inc => inc.PackageMatchField).Distinct())
                    {
                        // Create Predicate for search
                        ExpressionStarter <PackageManifest> inclusionPredicate = PredicateBuilder.New <PackageManifest>();
                        foreach (SearchRequestPackageMatchFilter matchFilter in inclusions.Where(inc => inc.PackageMatchField.Equals(packageMatchField)))
                        {
                            // Some package match fields or types might not be supported by current version of search.
                            // So we will check the supported list before adding any predicates.
                            if (this.IsPackageMatchFieldSupported(matchFilter.PackageMatchField) &&
                                this.IsMatchTypeSupported(matchFilter.RequestMatch.MatchType))
                            {
                                inclusionPredicate.Or(this.QueryPredicate(matchFilter.PackageMatchField, matchFilter.RequestMatch));
                            }
                        }

                        // Create Document Query
                        IQueryable <PackageManifest> query = this.cosmosDatabase.GetIQueryable <PackageManifest>(feedOptions);
                        query = query.Where(inclusionPredicate);
                        IDocumentQuery <PackageManifest> documentQuery = query.AsDocumentQuery();

                        // Submit Query to Cosmos
                        taskSet.Add(Task.Run(() => this.cosmosDatabase.GetByDocumentQuery(documentQuery)));
                    }

                    // Wait for Cosmos Queries to complete
                    await Task.WhenAll(taskSet.ToArray());

                    // Process Manifests from Cosmos
                    foreach (Task <ApiDataPage <PackageManifest> > task in taskSet)
                    {
                        manifests.AddRange(task.Result.Items);
                    }

                    manifests = manifests.Distinct().ToList();
                }
            }

            // Process Filters
            if (manifestSearchRequest.Filters != null)
            {
                ExpressionStarter <PackageManifest> filterPredicate = PredicateBuilder.New <PackageManifest>();
                foreach (SearchRequestPackageMatchFilter matchFilter in manifestSearchRequest.Filters)
                {
                    if (this.IsPackageMatchFieldSupported(matchFilter.PackageMatchField) &&
                        this.IsMatchTypeSupported(matchFilter.RequestMatch.MatchType))
                    {
                        filterPredicate.Or(this.QueryPredicate(matchFilter.PackageMatchField, matchFilter.RequestMatch));
                    }
                }

                manifests = manifests.Where(filterPredicate).ToList();
            }

            foreach (PackageManifest manifest in manifests)
            {
                foreach (ManifestSearchResponse response in ManifestSearchResponse.GetSearchVersions(manifest))
                {
                    manifestSearchResponse.Add(response);
                }
            }

            // Consolidate Results
            manifestSearchResponse = ManifestSearchResponse.Consolidate(manifestSearchResponse).OrderBy(manifest => manifest.PackageIdentifier).ToList();

            // Process results
            if (manifestSearchResponse.Count > manifestSearchRequest.MaximumResults && manifestSearchRequest.MaximumResults > 0)
            {
                manifestSearchResponse = manifestSearchResponse.GetRange(0, manifestSearchRequest.MaximumResults);
            }

            int maxPageCount = manifestSearchRequest.MaximumResults < FunctionSettingsConstants.MaxResultsPerPage && manifestSearchRequest.MaximumResults > 0
                ? manifestSearchRequest.MaximumResults
                : FunctionSettingsConstants.MaxResultsPerPage;

            int totalResults = manifestSearchResponse.Count;

            if (totalResults > maxPageCount)
            {
                // Process Continuation Token
                ApiContinuationToken token = null;
                if (headers.ContainsKey(HeaderConstants.ContinuationToken))
                {
                    token = Parser.StringParser <ApiContinuationToken>(StringEncoder.DecodeContinuationToken(headers[HeaderConstants.ContinuationToken]));
                }
                else
                {
                    token = new ApiContinuationToken()
                    {
                        Index       = 0,
                        MaxPageSize = maxPageCount,
                    };
                }

                // If index miss-match dump results and return no content.
                if (token.Index > manifestSearchResponse.Count - 1)
                {
                    manifestSearchResponse = new List <ManifestSearchResponse>();
                    token = null;
                }
                else
                {
                    int elementsRemaining = totalResults - token.Index;
                    int elements          = elementsRemaining < token.MaxPageSize ? elementsRemaining : token.MaxPageSize;
                    manifestSearchResponse = manifestSearchResponse.GetRange(token.Index, elements);

                    token.Index += elements;
                    if (token.Index == totalResults)
                    {
                        token = null;
                    }
                }

                apiDataPage.ContinuationToken = token != null?StringEncoder.EncodeContinuationToken(FormatJSON.None(token)) : null;
            }

            apiDataPage.Items = ManifestSearchResponse.Consolidate(manifestSearchResponse.ToList());

            return(apiDataPage);
        }