Ejemplo n.º 1
0
        public HashSet <int> FindDependencyPackages(HashSet <int> roots)
        {
            var result = new HashSet <int>();
            var next   = new HashSet <int>(roots);
            var seen   = new HashSet <int>(roots);

            do
            {
                var dependencies = _galleryContext.PackageRegistrations
                                   .Join(
                    _galleryContext.Set <PackageDependency>(),
                    registration => registration.Id,
                    dependency => dependency.Id,
                    (registration, dependency) => new
                {
                    DependencyRegistrationKey = registration.Key,
                    ParentRegistrationKey     = dependency.Package.PackageRegistrationKey
                })
                                   .Where(j => next.Contains(j.ParentRegistrationKey))
                                   .Select(j => j.DependencyRegistrationKey)
                                   .Distinct()
                                   .ToList();

                next.Clear();
                next.UnionWith(dependencies);
                next.ExceptWith(seen);

                result.UnionWith(next);
                seen.UnionWith(next);
            }while (next.Count() > 0);

            return(result);
        }
Ejemplo n.º 2
0
        private async Task <bool> IsDeleted(PackageRevalidation revalidation)
        {
            var packageStatus = await _galleryContext.Set <Package>()
                                .Where(p => p.PackageRegistration.Id == revalidation.PackageId)
                                .Where(p => p.NormalizedVersion == revalidation.PackageNormalizedVersion)
                                .Select(p => (PackageStatus?)p.PackageStatusKey)
                                .FirstOrDefaultAsync();

            return(packageStatus == null || packageStatus == PackageStatus.Deleted);
        }
Ejemplo n.º 3
0
 public Repository(IGalleryContext dbContext)
 {
     MainDbContext = dbContext;
     EntityDbSet   = dbContext.Set <TEntity>();
 }
Ejemplo n.º 4
0
        private async Task <IReadOnlyList <PackageRevalidation> > FilterCompletedRevalidationsAsync(IReadOnlyList <PackageRevalidation> revalidations)
        {
            if (!revalidations.Any())
            {
                return(revalidations);
            }

            var completed   = new List <PackageRevalidation>();
            var uncompleted = revalidations.ToDictionary(
                r => $"{r.PackageId}/{r.PackageNormalizedVersion}",
                r => r);

            // Packages that already have a repository signature do not need to be revalidated.
            _logger.LogInformation("Finding revalidations that can be skipped because their packages are already repository signed...");

            var hasRepositorySignatures = await _validationContext.PackageSigningStates
                                          .Select(s => new {
                IdAndVersion = s.PackageId + "/" + s.PackageNormalizedVersion,
                s.PackageSignatures
            })
                                          .Where(s => uncompleted.Keys.Contains(s.IdAndVersion))
                                          .Where(s => s.PackageSignatures.Any(sig => sig.Type == PackageSignatureType.Repository))
                                          .Select(s => s.IdAndVersion)
                                          .ToListAsync();

            _logger.LogInformation(
                "Found {RevalidationCount} revalidations that can be skipped because their packages are already repository signed",
                hasRepositorySignatures.Count);

            foreach (var idAndVersion in hasRepositorySignatures)
            {
                completed.Add(uncompleted[idAndVersion]);
                uncompleted.Remove(idAndVersion);
            }

            // Packages that are no longer available should not be revalidated.
            _logger.LogInformation("Finding revalidations' package statuses...");

            var packageStatuses = await _galleryContext.Set <Package>()
                                  .Select(p => new
            {
                Identity = p.PackageRegistration.Id + "/" + p.NormalizedVersion,
                p.PackageStatusKey
            })
                                  .Where(p => uncompleted.Keys.Contains(p.Identity))
                                  .ToDictionaryAsync(
                p => p.Identity,
                p => p.PackageStatusKey);

            _logger.LogInformation("Found {PackageStatusCount} revalidations' package statuses", packageStatuses.Count);

            foreach (var key in uncompleted.Keys.ToList())
            {
                // Packages that are hard deleted won't have a status.
                if (!packageStatuses.TryGetValue(key, out var status) || status == PackageStatus.Deleted)
                {
                    completed.Add(uncompleted[key]);
                    uncompleted.Remove(key);
                    continue;
                }
            }

            _logger.LogInformation(
                "Found {CompletedRevalidations} revalidations that can be skipped. There are {UncompletedRevalidations} " +
                "revalidations remaining in this batch",
                completed.Count,
                uncompleted.Count);

            // Update revalidations that were determined to be completed and return the remaining revalidations.
            if (completed.Any())
            {
                await MarkRevalidationsAsCompletedAsync(completed);
            }

            return(uncompleted.Values.ToList());
        }