Пример #1
0
        public async Task <IActionResult> GetProviderIds([FromBody] SearchPublishedProvidersRequest request)
        {
            PublishedProviderIdSearchModel searchModel = new PublishedProviderIdSearchModel
            {
                Filters      = ExtractFilters(request),
                SearchTerm   = request.SearchTerm,
                SearchFields = request.SearchFields
            };

            ApiResponse <IEnumerable <string> > response = await _publishingApiClient.SearchPublishedProviderIds(searchModel);

            var errorResult = response.IsSuccessOrReturnFailureResult("search");

            if (errorResult != null)
            {
                return(errorResult);
            }

            return(Ok(response.Content));
        }
Пример #2
0
        public async Task <IActionResult> SearchPublishedProviderIds(PublishedProviderIdSearchModel searchModel)
        {
            if (searchModel == null)
            {
                _logger.Error("A null or invalid search model was provided for searching published provider ids");

                return(new BadRequestObjectResult("An invalid search model was provided"));
            }

            try
            {
                IDictionary <string, string[]> searchModelDictionary = searchModel.Filters;
                List <Filter> filters = searchModelDictionary
                                        .Select(keyValueFilterPair => new Filter(
                                                    keyValueFilterPair.Key,
                                                    keyValueFilterPair.Value,
                                                    IntegerFields.Contains(keyValueFilterPair.Key),
                                                    "eq"))
                                        .ToList();
                FilterHelper filterHelper = new FilterHelper(filters);

                IList <string> searchFields           = searchModel.SearchFields?.ToList();
                int            searchResultsBatchSize = 1000;
                IList <string> selectFields           = new[] { "id" };
                IList <string> orderByFields          = new[] { "id" };
                string         filter = filterHelper.BuildAndFilterQuery();

                SearchResults <PublishedProviderIndex> searchResults = await Task.Run(() =>
                {
                    return(SearchRepository.Search(searchModel.SearchTerm, new SearchParameters
                    {
                        Top = searchResultsBatchSize,
                        IncludeTotalResultCount = true,
                        Select = selectFields,
                        OrderBy = orderByFields,
                        SearchFields = searchFields,
                        Filter = filter
                    }));
                });

                ConcurrentBag <string> results = new ConcurrentBag <string>();
                searchResults.Results.ForEach(_ => results.Add(_.Result.Id));

                if (searchResults.TotalCount > searchResultsBatchSize)
                {
                    SemaphoreSlim throttler   = new SemaphoreSlim(10, 10);
                    List <Task>   searchTasks = new List <Task>();
                    int           count       = searchResultsBatchSize;

                    while (count < searchResults.TotalCount)
                    {
                        SearchParameters searchParams = new SearchParameters
                        {
                            Skip = count,
                            Top  = searchResultsBatchSize,
                            IncludeTotalResultCount = true,
                            Select       = selectFields,
                            OrderBy      = orderByFields,
                            SearchFields = searchFields,
                            Filter       = filter
                        };

                        await throttler.WaitAsync();

                        searchTasks.Add(
                            Task.Run(async() =>
                        {
                            try
                            {
                                SearchResults <PublishedProviderIndex> nextSearchResults =
                                    await SearchRepository.Search(searchModel.SearchTerm, searchParams);
                                nextSearchResults.Results.ForEach(_ => results.Add(_.Result.Id));
                            }
                            finally
                            {
                                throttler.Release();
                            }
                        }));

                        count += searchResultsBatchSize;
                    }

                    await TaskHelper.WhenAllAndThrow(searchTasks.ToArray());
                }

                return(new OkObjectResult(results));
            }
            catch (FailedToQuerySearchException exception)
            {
                _logger.Error(exception, $"Failed to query search with term: {searchModel.SearchTerm}");

                return(new InternalServerErrorResult($"Failed to query search, with exception: {exception.Message}"));
            }
        }
        public async Task GetsSearchPublishedProviderIdsShouldBatchAllPageResults()
        {
            string providerId = new RandomString();
            string searchTerm = new RandomString();

            PublishedProviderIdSearchModel searchModel = new PublishedProviderIdSearchModel
            {
                SearchTerm = searchTerm
            };

            SearchParameters searchParametersOne = new SearchParameters {
                Skip = 0
            };
            SearchParameters searchParametersTwo = new SearchParameters {
                Skip = 1000
            };

            List <CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex> > resultsOne =
                new List <CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex> >();

            resultsOne.AddRange(Enumerable.Range(1, 1000).Select(i => new CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex>
            {
                Result = new PublishedProviderIndex
                {
                    Id = $"{providerId}-One-{i}"
                }
            }));

            SearchResults <PublishedProviderIndex> firstPageSearchResults = new SearchResults <PublishedProviderIndex>
            {
                TotalCount = 1500,
                Results    = resultsOne
            };

            List <CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex> > resultsTwo =
                new List <CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex> >();

            resultsTwo.AddRange(Enumerable.Range(1, 500).Select(i => new CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex>
            {
                Result = new PublishedProviderIndex
                {
                    Id = $"{providerId}-Two-{i}"
                }
            }));

            SearchResults <PublishedProviderIndex> secondPageSearchResults = new SearchResults <PublishedProviderIndex>
            {
                TotalCount = 1500,
                Results    = resultsTwo
            };

            AndTheSearchResults(new SearchModel {
                SearchTerm = searchTerm
            }, searchParametersOne, firstPageSearchResults);
            AndTheSearchResults(new SearchModel {
                SearchTerm = searchTerm
            }, searchParametersTwo, secondPageSearchResults);

            IActionResult result = await WhenSearchPublishedProviderIdsIsMade(searchModel);

            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Should()
            .NotBeNull();

            OkObjectResult okObjectResult = result as OkObjectResult;

            okObjectResult
            .Value
            .Should()
            .NotBeNull()
            .And
            .BeOfType <ConcurrentBag <string> >();

            ConcurrentBag <string> publishedProviderIds = okObjectResult.Value as ConcurrentBag <string>;

            publishedProviderIds
            .Should()
            .HaveCount(1500);
        }
 private async Task <IActionResult> WhenSearchPublishedProviderIdsIsMade(
     PublishedProviderIdSearchModel publishedProviderIdSearchModel)
 {
     return(await _service.SearchPublishedProviderIds(publishedProviderIdSearchModel));
 }
        public async Task GetsSearchPublishedProviderIds()
        {
            string providerIdOne = new RandomString();
            string providerIdTwo = new RandomString();

            string searchTerm = new RandomString();

            PublishedProviderIdSearchModel searchModel = new PublishedProviderIdSearchModel
            {
                SearchTerm = searchTerm
            };

            SearchResults <PublishedProviderIndex> searchResults = new SearchResults <PublishedProviderIndex>
            {
                Results = new List <CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex> >
                {
                    new CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex>
                    {
                        Result = new PublishedProviderIndex
                        {
                            Id = providerIdOne
                        }
                    },
                    new CalculateFunding.Repositories.Common.Search.SearchResult <PublishedProviderIndex>
                    {
                        Result = new PublishedProviderIndex
                        {
                            Id = providerIdTwo
                        }
                    }
                }
            };

            AndTheSearchResults(new SearchModel {
                SearchTerm = searchTerm
            }, searchResults);

            IActionResult result = await WhenSearchPublishedProviderIdsIsMade(searchModel);

            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Should()
            .NotBeNull();

            OkObjectResult okObjectResult = result as OkObjectResult;

            okObjectResult
            .Value
            .Should()
            .NotBeNull()
            .And
            .BeOfType <ConcurrentBag <string> >();

            ConcurrentBag <string> publishedProviderIds = okObjectResult.Value as ConcurrentBag <string>;

            publishedProviderIds
            .Should()
            .HaveCount(2);

            publishedProviderIds
            .Should()
            .BeEquivalentTo(new[] { providerIdOne, providerIdTwo });
        }