Example #1
0
        public async Task <bool> DoesPackageExistAsync(string id, NuGetVersion version)
        {
            var indexUrl = RegistrationUrlBuilder.GetIndexUrl(_endpoint, id);
            var index    = await _registrationClient.GetIndexOrNullAsync(indexUrl);

            if (index == null)
            {
                return(false);
            }

            var matchingPageItem = index
                                   .Items
                                   .FirstOrDefault(x => NuGetVersion.Parse(x.Lower) <= version && version <= NuGetVersion.Parse(x.Upper));

            if (matchingPageItem == null)
            {
                return(false);
            }

            var items = matchingPageItem.Items;

            if (items == null)
            {
                try
                {
                    var page = await _registrationClient.GetPageAsync(matchingPageItem.Url);

                    items = page.Items;
                }
                catch (SimpleHttpClientException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
                {
                    return(false);
                }
            }

            var matchingItem = items
                               .FirstOrDefault(x => NuGetVersion.Parse(x.CatalogEntry.Version) == version);

            if (matchingItem == null)
            {
                return(false);
            }

            return(true);
        }
Example #2
0
        private V3SearchPackage ToV3SearchPackage(SearchDocument.Full result, string registrationsBaseUrl)
        {
            var registrationIndexUrl = RegistrationUrlBuilder.GetIndexUrl(registrationsBaseUrl, result.PackageId);

            return(new V3SearchPackage
            {
                AtId = registrationIndexUrl,
                Type = "Package",
                Registration = registrationIndexUrl,
                Id = result.PackageId,
                Version = result.FullVersion,
                Description = result.Description ?? string.Empty,
                Summary = result.Summary ?? string.Empty,
                Title = TitleThenId(result),
                IconUrl = GetIconUrl(result),
                LicenseUrl = result.LicenseUrl,
                ProjectUrl = result.ProjectUrl,
                Tags = result.Tags ?? Array.Empty <string>(),
                Authors = new[] { result.Authors ?? string.Empty },
                TotalDownloads = AuxiliaryData.GetTotalDownloadCount(result.PackageId),
                Verified = AuxiliaryData.IsVerified(result.PackageId),
                PackageTypes = GetV3SearchPackageTypes(result),
                Versions = result
                           .Versions
                           .Select(x =>
                {
                    // Each of these versions is the full version.
                    var lowerVersion = NuGetVersion.Parse(x).ToNormalizedString().ToLowerInvariant();
                    return new V3SearchVersion
                    {
                        Version = x,
                        Downloads = AuxiliaryData.GetDownloadCount(result.PackageId, lowerVersion),
                        AtId = RegistrationUrlBuilder.GetLeafUrl(registrationsBaseUrl, result.PackageId, x),
                    };
                })
                           .ToList(),
            });
        }
Example #3
0
        public async Task CopyAsync(ICloudBlobContainer container, string oldBaseUrl, string newBaseUrl, string id, bool gzip)
        {
            var normalizedOldBaseUrl = oldBaseUrl.TrimEnd('/');
            var normalizedNewBaseUrl = newBaseUrl.TrimEnd('/');

            var indexUrl = RegistrationUrlBuilder.GetIndexUrl(normalizedOldBaseUrl, id);

            _logger.LogInformation("Downloading index {IndexUrl}...", indexUrl);

            await Throttle.WaitAsync();

            RegistrationIndex index;

            try
            {
                index = await _registrationClient.GetIndexOrNullAsync(indexUrl);
            }
            finally
            {
                Throttle.Release();
            }

            if (index == null)
            {
                return;
            }

            var pageUrls = new List <string>();
            var itemUrls = new List <string>();

            var pageTasks = index
                            .Items
                            .Select(async pageItem =>
            {
                await Task.Yield();
                await Throttle.WaitAsync();
                try
                {
                    List <RegistrationLeafItem> leafItems;
                    if (pageItem.Items != null)
                    {
                        leafItems = pageItem.Items;
                    }
                    else
                    {
                        pageUrls.Add(pageItem.Url);
                        _logger.LogInformation("Downloading page {PageUrl}...", pageItem.Url);
                        var page  = await _registrationClient.GetPageAsync(pageItem.Url);
                        leafItems = page.Items;
                    }

                    foreach (var leafItem in leafItems)
                    {
                        itemUrls.Add(leafItem.Url);
                    }
                }
                finally
                {
                    Throttle.Release();
                }
            })
                            .ToList();
            await Task.WhenAll(pageTasks);

            var copyTasks = itemUrls
                            .Concat(pageUrls)
                            .Concat(new[] { indexUrl })
                            .Select(async url =>
            {
                await Task.Yield();
                await CopyUrlAsync(container, normalizedOldBaseUrl, normalizedNewBaseUrl, url, gzip);
            })
                            .ToList();
            await Task.WhenAll(copyTasks);
        }
Example #4
0
        public async Task <LatestCatalogLeaves> GetLatestLeavesAsync(
            string packageId,
            IReadOnlyList <IReadOnlyList <NuGetVersion> > versions)
        {
            if (packageId == null)
            {
                throw new ArgumentNullException(nameof(packageId));
            }

            if (versions == null)
            {
                throw new ArgumentNullException(nameof(versions));
            }

            if (!versions.Any())
            {
                throw new ArgumentException("At least one version list must be provided.", nameof(versions));
            }

            using (_telemetryService.TrackGetLatestLeaves(packageId, versions.SelectMany(v => v).Distinct().Count()))
            {
                var unavailable = new HashSet <NuGetVersion>();
                var fetched     = new Dictionary <NuGetVersion, PackageDetailsCatalogLeaf>();
                var unlisted    = new Dictionary <NuGetVersion, string>();

                var registrationIndexUrl = RegistrationUrlBuilder.GetIndexUrl(_options.Value.RegistrationsBaseUrl, packageId);
                var registrationIndex    = await _registrationClient.GetIndexOrNullAsync(registrationIndexUrl);

                if (registrationIndex == null)
                {
                    _logger.LogWarning(
                        "No registation index was found. ID: {PackageId}, registration index URL: {RegistrationIndexUrl}",
                        packageId,
                        registrationIndexUrl);

                    foreach (var version in versions.SelectMany(x => x))
                    {
                        unavailable.Add(version);
                    }

                    return(new LatestCatalogLeaves(unavailable, fetched));
                }

                var pageUrlToInfo = registrationIndex
                                    .Items
                                    .ToDictionary(x => x.Url, x => new RegistrationPageInfo(x));

                // Make a list of ranges for logging purposes.
                var ranges = pageUrlToInfo
                             .OrderBy(x => x.Value.Range.MinVersion)
                             .Select(x => x.Value.RangeString)
                             .ToList();

                foreach (var versionList in versions)
                {
                    await AddLatestLeafAsync(
                        packageId,
                        versionList,
                        pageUrlToInfo,
                        ranges,
                        unavailable,
                        fetched,
                        unlisted);
                }

                // Fetch the unlisted version's metadata in parallel. This can be many versions in the case of a bulk
                // unlist.
                var allWork    = new ConcurrentBag <KeyValuePair <NuGetVersion, string> >(unlisted);
                var allResults = new ConcurrentBag <KeyValuePair <NuGetVersion, PackageDetailsCatalogLeaf> >();
                var tasks      = Enumerable
                                 .Range(0, _options.Value.MaxConcurrentBatches)
                                 .Select(async x =>
                {
                    await Task.Yield();
                    while (allWork.TryTake(out var work))
                    {
                        var leaf = await _catalogClient.GetPackageDetailsLeafAsync(work.Value);
                        allResults.Add(KeyValuePair.Create(work.Key, leaf));
                    }
                })
                                 .ToList();
                await Task.WhenAll(tasks);

                foreach (var pair in allResults)
                {
                    fetched.Add(pair.Key, pair.Value);
                }

                return(new LatestCatalogLeaves(unavailable, fetched));
            }
        }