// GET: /<controller>/ public async Task <IActionResult> Index(int?brandFilterApplied, int?typesFilterApplied, int?page) { var itemsPage = 10; var catalog = await _catalogService.GetCatalogItems(page ?? 0, itemsPage, brandFilterApplied, typesFilterApplied); var vm = new CatalogIndex() { CatalogItems = catalog.Data, Brands = await _catalogService.GetBrands(), Types = await _catalogService.GetTypes(), BrandFilterApplied = brandFilterApplied ?? 0, TypesFilterApplied = typesFilterApplied ?? 0, PaginationInfo = new PaginationInfo() { ActualPage = page ?? 0, ItemsPerPage = catalog.Data.Count, TotalItems = catalog.Count, TotalPages = int.Parse(Math.Ceiling(((decimal)catalog.Count / itemsPage)).ToString()) } }; vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : ""; vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : ""; return(View(vm)); }
private async Task <IEnumerable <CatalogLeafItem> > GetCatalogLeafItems( ICatalogClient catalogClient, CatalogIndex catalogIndex, DateTimeOffset cursor, CancellationToken cancellationToken) { var catalogLeafItems = new ConcurrentBag <CatalogLeafItem>(); var catalogPageUrls = new ConcurrentBag <string>( catalogIndex .Items .Where(i => i.CommitTimestamp > cursor) .Select(i => i.CatalogPageUrl)); await ParallelHelper.ProcessInParallel( catalogPageUrls, ProcessCatalogPageUrlAsync, cancellationToken); return(catalogLeafItems); async Task ProcessCatalogPageUrlAsync(string catalogPageUrl, CancellationToken token) { _logger.LogInformation("Processing catalog page {CatalogPageUrl}...", catalogPageUrl); var page = await catalogClient.GetPageAsync(catalogPageUrl, token); foreach (var catalogLeafItem in page.Items.Where(i => i.CommitTimestamp > cursor)) { catalogLeafItems.Add(catalogLeafItem); } _logger.LogInformation("Processed catalog page {CatalogPageUrl}", catalogPageUrl); } }
/// <summary> /// Gets the pages that may have catalog leaves within the provided commit timestamp bounds. The result is /// sorted by commit timestamp. /// </summary> /// <param name="catalogIndex">The catalog index to fetch pages from.</param> /// <param name="minCommitTimestamp">The exclusive lower time bound on <see cref="CatalogPageItem.CommitTimestamp"/>.</param> /// <param name="maxCommitTimestamp">The inclusive upper time bound on <see cref="CatalogPageItem.CommitTimestamp"/>.</param> public static List <CatalogPageItem> GetPagesInBounds( this CatalogIndex catalogIndex, DateTimeOffset minCommitTimestamp, DateTimeOffset maxCommitTimestamp) { return(catalogIndex .GetPagesInBoundsLazy(minCommitTimestamp, maxCommitTimestamp) .ToList()); }
private static IEnumerable <CatalogPageItem> GetPagesInBoundsLazy( this CatalogIndex catalogIndex, DateTimeOffset minCommitTimestamp, DateTimeOffset maxCommitTimestamp) { // Filter out pages that fall entirely before the minimum commit timestamp and sort the remaining pages by // commit timestamp. var upperRange = catalogIndex .Items .Where(x => x.CommitTimestamp > minCommitTimestamp) .OrderBy(x => x.CommitTimestamp); // Take pages from the sorted list until the commit timestamp goes past the maximum commit timestamp. This // essentially LINQ's TakeWhile plus one more element. foreach (var page in upperRange) { yield return(page); if (page.CommitTimestamp > maxCommitTimestamp) { break; } } }
public async Task RunAsync_WhenPackageIdSpansCommitsAndVariesInCasing_BatchesAcrossCommitsByLowerCasePackageId() { var pageUri = new Uri(_baseUri, "v3-catalog0/page0.json"); var indexUri = new Uri(_baseUri, "v3-catalog0/index.json"); var contentBaseUri = new Uri(_baseUri, "packages"); SharedInit(useLegacy: true, useSemVer2: true, baseUri: _baseUri, indexUri: indexUri, contentBaseUri: contentBaseUri); var commitId1 = Guid.NewGuid().ToString(); var commitId2 = Guid.NewGuid().ToString(); var commitTimeStamp1 = DateTimeOffset.UtcNow.AddMinutes(-1); var commitTimeStamp2 = commitTimeStamp1.AddMinutes(1); var independentPackageDetails1 = new CatalogIndependentPackageDetails( id: "ABC", version: "1.0.0", baseUri: _baseUri.AbsoluteUri, commitId: commitId1, commitTimeStamp: commitTimeStamp1); var independentPackageDetails2 = new CatalogIndependentPackageDetails( id: "AbC", version: "1.0.1", baseUri: _baseUri.AbsoluteUri, commitId: commitId1, commitTimeStamp: commitTimeStamp1); var independentPackageDetails3 = new CatalogIndependentPackageDetails( id: "abc", version: "1.0.2", baseUri: _baseUri.AbsoluteUri, commitId: commitId2, commitTimeStamp: commitTimeStamp2); var packageDetails = new[] { CatalogPackageDetails.Create(independentPackageDetails1), CatalogPackageDetails.Create(independentPackageDetails2), CatalogPackageDetails.Create(independentPackageDetails3) }; var independentPage = new CatalogIndependentPage( pageUri.AbsoluteUri, CatalogConstants.CatalogPage, commitId2, commitTimeStamp2.ToString(CatalogConstants.CommitTimeStampFormat), packageDetails.Length, indexUri.AbsoluteUri, packageDetails, _contextKeyword); var index = CatalogIndex.Create(independentPage, _contextKeyword); var catalogStorage = new MemoryStorage(_baseUri); catalogStorage.Content.TryAdd(indexUri, CreateStringStorageContent(index)); catalogStorage.Content.TryAdd(pageUri, CreateStringStorageContent(independentPage)); catalogStorage.Content.TryAdd( new Uri(independentPackageDetails1.IdKeyword), CreateStringStorageContent(independentPackageDetails1)); catalogStorage.Content.TryAdd( new Uri(independentPackageDetails2.IdKeyword), CreateStringStorageContent(independentPackageDetails2)); catalogStorage.Content.TryAdd( new Uri(independentPackageDetails3.IdKeyword), CreateStringStorageContent(independentPackageDetails3)); await _mockServer.AddStorageAsync(catalogStorage); await _target.RunAsync(CancellationToken.None); var expectedPage = new ExpectedPage(independentPackageDetails1, independentPackageDetails2, independentPackageDetails3); Verify(_legacyStorage, expectedPage); Verify(_semVer2Storage, expectedPage); }