Пример #1
0
 public Package(IPackage package, DerivedPackageData derivedData)
 {
     Id = package.Id;
     Version = package.Version.ToString();
     Title = package.Title;
     Authors = String.Join(",", package.Authors);
     if (package.IconUrl != null)
     {
         IconUrl = package.IconUrl.GetComponents(UriComponents.HttpRequestUrl, UriFormat.Unescaped);
     }
     if (package.LicenseUrl != null)
     {
         LicenseUrl = package.LicenseUrl.GetComponents(UriComponents.HttpRequestUrl, UriFormat.Unescaped);
     }
     if (package.ProjectUrl != null)
     {
         ProjectUrl = package.ProjectUrl.GetComponents(UriComponents.HttpRequestUrl, UriFormat.Unescaped);
     }
     RequireLicenseAcceptance = package.RequireLicenseAcceptance;
     Description = package.Description;
     Summary = package.Summary;
     ReleaseNotes = package.ReleaseNotes;
     Tags = package.Tags;
     Dependencies = String.Join("|", package.DependencySets.SelectMany(ConvertDependencySetToStrings));
     PackageHash = derivedData.PackageHash;
     PackageHashAlgorithm = "SHA512";
     PackageSize = derivedData.PackageSize;
     LastUpdated = derivedData.LastUpdated.UtcDateTime;
     Published = derivedData.Created.UtcDateTime;
     IsAbsoluteLatestVersion = package.IsAbsoluteLatestVersion;
     IsLatestVersion = package.IsLatestVersion;
     Path = derivedData.Path;
     FullPath = derivedData.FullPath;
     MinClientVersion = package.MinClientVersion == null ? null : package.MinClientVersion.ToString();
 }
Пример #2
0
 private void SetData(IPackage package, DerivedPackageData packageData)
 {
     _cacheLock.EnterWriteLock();
     try
     {
         _derivedDataLookup[package] = packageData;
     }
     finally
     {
         _cacheLock.ExitWriteLock();
     }
 }
        /// <summary>
        /// Gives the Package containing both the IPackage and the derived metadata.
        /// The returned Package will be null if <paramref name="package" /> no longer exists in the cache.
        /// </summary>
        public Package GetMetadataPackage(IPackage package)
        {
            Package metadata = null;

            // The cache may have changed, and the metadata may no longer exist
            DerivedPackageData data = null;

            if (PackageCache.TryGetValue(package, out data))
            {
                metadata = new Package(package, data);
            }

            return(metadata);
        }
 /// <summary>
 /// Gets the metadata package.
 /// </summary>
 /// <param name="package">The package.</param>
 /// <returns></returns>
 public Package GetMetadataPackage(IPackage package)
 {
     var derived = new DerivedPackageData() {
         //Created = ?
         //FullPath = ?
         IsAbsoluteLatestVersion = package.IsAbsoluteLatestVersion,
         IsLatestVersion = package.IsLatestVersion
         //LastUpdated = ?
         //PackageHash = package.GetHash(),
         //PackageSize = ??
         //Path = ??
         //SupportedFrameworks = package.GetSupportedFrameworks(),
     };
     //var pkg = new Package(package, new DerivedPackageData());
     return new Package(package, derived);
 }
Пример #5
0
 private void SetData(IPackage package, DerivedPackageData packageData)
 {
     _cacheLock.EnterWriteLock();
     try
     {
         _derivedDataLookup[package] = packageData;
     }
     finally
     {
         _cacheLock.ExitWriteLock();
     }
 }
Пример #6
0
        protected override IPackage OpenPackage(string path)
        {
            IPackage package = base.OpenPackage(path);

            if (EnableDelisting)
            {
                // hidden packages are considered delisted
                var localPackage = package as LocalPackage;
                if (localPackage != null)
                {
                    localPackage.Listed = !File.GetAttributes(FileSystem.GetFullPath(path)).HasFlag(FileAttributes.Hidden);
                }
            }

            _cacheLock.EnterWriteLock();
            try
            {
                DateTime start = DateTime.Now;
                while (true)
                {
                    DerivedPackageData packageData;
                    if (!_derivedDataLookup.TryGetValue(package, out packageData))
                    {
                        // take ownership
                        _derivedDataLookup[package] = null;
                        break;
                    }
                    if (packageData != null)
                    {
                        // derived data has been computed and cached
                        return(package);
                    }
                    if ((DateTime.Now - start).TotalSeconds > MaxWaitMs)
                    {
                        // we're giving up on waiting; potentially other thread is blocked, died, ... take ownership
                        _derivedDataLookup[package] = null;
                        break;
                    }
                    // about to wait; release locks
                    _cacheLock.ExitWriteLock();
                    _derivedDataComputed.WaitOne(MaxWaitMs);

                    _cacheLock.EnterWriteLock();
                }
            }
            finally
            {
                _cacheLock.ExitWriteLock();
            }

            try
            {
                // compute
                DerivedPackageData packageData = CalculateDerivedData(package, path);
                // write value
                SetData(package, packageData);
            }
            catch
            {
                // on failure, clean cache
                DeleteData(package);
                throw;
            }
            finally
            {
                // We've either failed or succeeded => wake up waiting threads, if any.
                _derivedDataComputed.Set();
            }

            return(package);
        }
Пример #7
0
        /// <summary>
        /// CreateCache loads all packages and determines additional metadata such as the hash, IsAbsoluteLatestVersion, and IsLatestVersion.
        /// </summary>
        private IDictionary<IPackage, DerivedPackageData> CreateCache()
        {
            ConcurrentDictionary<IPackage, DerivedPackageData> packages = new ConcurrentDictionary<IPackage, DerivedPackageData>();

            ParallelOptions opts = new ParallelOptions();
            opts.MaxDegreeOfParallelism = 4;

            ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>> absoluteLatest = new ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>>();
            ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>> latest = new ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>>();

            // get settings
            bool checkFrameworks = EnableFrameworkFiltering;
            bool enableDelisting = EnableDelisting;
            // we need to save the current context because it's stored in TLS and we're computing hashes on different threads.
            var context = HttpContext.Current;

            // load and cache all packages.
            // Note that we can't pass GetPackageFiles() to Parallel.ForEach() because
            // the file could be added/deleted from _fileSystem, and if this happens,
            // we'll get error "Collection was modified; enumeration operation may not execute."
            // So we have to materialize the IEnumerable into a list first.
            var packageFiles = GetPackageFiles().ToList();

            Parallel.ForEach(packageFiles, opts, path =>
            {
                OptimizedZipPackage zip = OpenPackage(path);

                Debug.Assert(zip != null, "Unable to open " + path);
                if (zip == null)
                {
                    return;
                }
                if (enableDelisting)
                {
                    // hidden packages are considered delisted
                    zip.Listed = !File.GetAttributes(_fileSystem.GetFullPath(path)).HasFlag(FileAttributes.Hidden);
                }

                string packageHash = null;
                long packageSize = 0;
                string persistedHashFile = EnablePersistNupkgHash ? GetHashFile(path, false) : null;
                bool hashComputeNeeded = true;

                ReadHashFile(context, path, persistedHashFile, ref packageSize, ref packageHash, ref hashComputeNeeded);

                if (hashComputeNeeded)
                {
                    using (var stream = _fileSystem.OpenFile(path))
                    {
                        packageSize = stream.Length;
                        packageHash = Convert.ToBase64String(HashProvider.CalculateHash(stream));
                    }
                    WriteHashFile(context, path, persistedHashFile, packageSize, packageHash);
                }

                var data = new DerivedPackageData
                {
                    PackageSize = packageSize,
                    PackageHash = packageHash,
                    LastUpdated = _fileSystem.GetLastModified(path),
                    Created = _fileSystem.GetCreated(path),
                    Path = path,
                    FullPath = _fileSystem.GetFullPath(path),

                    // default to false, these will be set later
                    IsAbsoluteLatestVersion = false,
                    IsLatestVersion = false
                };

                if (checkFrameworks)
                {
                    data.SupportedFrameworks = zip.GetSupportedFrameworks();
                }

                var entry = new Tuple<IPackage, DerivedPackageData>(zip, data);

                // find the latest versions
                string id = zip.Id.ToLowerInvariant();

                // update with the highest version
                absoluteLatest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);

                // update latest for release versions
                if (zip.IsReleaseVersion())
                {
                    latest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);
                }

                // add the package to the cache, it should not exist already
                Debug.Assert(packages.ContainsKey(zip) == false, "duplicate package added");
                packages.AddOrUpdate(zip, entry.Item2, (oldPkg, oldData) => oldData);
            });

            // Set additional attributes after visiting all packages
            foreach (var entry in absoluteLatest.Values)
            {
                entry.Item2.IsAbsoluteLatestVersion = true;
            }

            foreach (var entry in latest.Values)
            {
                entry.Item2.IsLatestVersion = true;
            }

            return packages;
        }
        private void AddPackageToCache(ConcurrentDictionary<IPackage, DerivedPackageData> packages, ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>> absoluteLatest, ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>> latest, bool checkFrameworks, HttpContext context, string path, IPackage zip)
        {
            string packageHash = null;
            long packageSize = 0;
            string persistedHashFile = EnablePersistNupkgHash ? GetHashFile(path, false) : null;
            bool hashComputeNeeded = true;

            ReadHashFile(context, path, persistedHashFile, ref packageSize, ref packageHash, ref hashComputeNeeded);

            if (hashComputeNeeded)
            {
                using (var stream = _fileSystem.OpenFile(path))
                {
                    packageSize = stream.Length;
                    packageHash = Convert.ToBase64String(HashProvider.CalculateHash(stream));
                }
                WriteHashFile(context, path, persistedHashFile, packageSize, packageHash);
            }

            var data = new DerivedPackageData
            {
                PackageSize = packageSize,
                PackageHash = packageHash,
                LastUpdated = _fileSystem.GetLastModified(path),
                Created = _fileSystem.GetCreated(path),
                Path = path,
                FullPath = _fileSystem.GetFullPath(path),

                // default to false, these will be set later
                IsAbsoluteLatestVersion = false,
                IsLatestVersion = false
            };

            if (checkFrameworks)
            {
                data.SupportedFrameworks = zip.GetSupportedFrameworks();
            }

            var entry = new Tuple<IPackage, DerivedPackageData>(zip, data);

            // find the latest versions
            string id = zip.Id.ToLowerInvariant();

            // update with the highest version
            absoluteLatest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);

            // update latest for release versions
            if (zip.IsReleaseVersion())
            {
                latest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);
            }

            // add the package to the cache, it should not exist already
            Debug.Assert(packages.ContainsKey(zip) == false, "duplicate package added");
            packages.AddOrUpdate(zip, entry.Item2, (oldPkg, oldData) => oldData);
        }
        /// <summary>
        /// CreateCache loads all packages and determines additional metadata such as the hash, IsAbsoluteLatestVersion, and IsLatestVersion.
        /// </summary>
        private IDictionary<IPackage, DerivedPackageData> CreateCache()
        {
            ConcurrentDictionary<IPackage, DerivedPackageData> packages = new ConcurrentDictionary<IPackage, DerivedPackageData>();

            ParallelOptions opts = new ParallelOptions();
            opts.MaxDegreeOfParallelism = 4;

            ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>> absoluteLatest = new ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>>();
            ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>> latest = new ConcurrentDictionary<string, Tuple<IPackage, DerivedPackageData>>();

            // get settings
            bool checkFrameworks = EnableFrameworkFiltering;
            bool enableDelisting = EnableDelisting;

            // load and cache all packages
            Parallel.ForEach(GetPackageFiles(), opts, path =>
            {
                OptimizedZipPackage zip = OpenPackage(path);

                Debug.Assert(zip != null, "Unable to open " + path);
                if (zip != null)
                {
                    if (enableDelisting)
                    {
                        // hidden packages are considered delisted
                        zip.Listed = !File.GetAttributes(_fileSystem.GetFullPath(path)).HasFlag(FileAttributes.Hidden);
                    }

                    byte[] hashBytes;
                    long fileLength;
                    using (Stream stream = _fileSystem.OpenFile(path))
                    {
                        fileLength = stream.Length;
                        hashBytes = HashProvider.CalculateHash(stream);
                    }

                    var data = new DerivedPackageData
                    {
                        PackageSize = fileLength,
                        PackageHash = Convert.ToBase64String(hashBytes),
                        LastUpdated = _fileSystem.GetLastModified(path),
                        Created = _fileSystem.GetCreated(path),
                        Path = path,
                        FullPath = _fileSystem.GetFullPath(path),

                        // default to false, these will be set later
                        IsAbsoluteLatestVersion = false,
                        IsLatestVersion = false
                    };

                    if (checkFrameworks)
                    {
                        data.SupportedFrameworks = zip.GetSupportedFrameworks();
                    }

                    Tuple<IPackage, DerivedPackageData> entry = new Tuple<IPackage, DerivedPackageData>(zip, data);

                    // find the latest versions
                    string id = zip.Id.ToLowerInvariant();

                    // update with the highest version
                    absoluteLatest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);

                    // update latest for release versions
                    if (zip.IsReleaseVersion())
                    {
                        latest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);
                    }

                    // add the package to the cache, it should not exist already
                    Debug.Assert(packages.ContainsKey(zip) == false, "duplicate package added");
                    packages.AddOrUpdate(zip, entry.Item2, (oldPkg, oldData) => oldData);
                }
            });

            // Set additional attributes after visiting all packages
            foreach (var entry in absoluteLatest.Values)
            {
                entry.Item2.IsAbsoluteLatestVersion = true;
            }

            foreach (var entry in latest.Values)
            {
                entry.Item2.IsLatestVersion = true;
            }

            return packages;
        }
        /// <summary>
        /// CreateCache loads all packages and determines additional metadata such as the hash, IsAbsoluteLatestVersion, and IsLatestVersion.
        /// </summary>
        private IDictionary <IPackage, DerivedPackageData> CreateCache()
        {
            ConcurrentDictionary <IPackage, DerivedPackageData> packages = new ConcurrentDictionary <IPackage, DerivedPackageData>();

            ParallelOptions opts = new ParallelOptions();

            opts.MaxDegreeOfParallelism = 4;

            ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> > absoluteLatest = new ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> >();
            ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> > latest         = new ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> >();

            // get settings
            bool checkFrameworks = EnableFrameworkFiltering;
            bool enableDelisting = EnableDelisting;

            // load and cache all packages
            Parallel.ForEach(GetPackageFiles(), opts, path =>
            {
                OptimizedZipPackage zip = OpenPackage(path);

                Debug.Assert(zip != null, "Unable to open " + path);
                if (zip != null)
                {
                    if (enableDelisting)
                    {
                        // hidden packages are considered delisted
                        zip.Listed = !File.GetAttributes(_fileSystem.GetFullPath(path)).HasFlag(FileAttributes.Hidden);
                    }

                    byte[] hashBytes;
                    long fileLength;
                    using (Stream stream = _fileSystem.OpenFile(path))
                    {
                        fileLength = stream.Length;
                        hashBytes  = HashProvider.CalculateHash(stream);
                    }

                    var data = new DerivedPackageData
                    {
                        PackageSize = fileLength,
                        PackageHash = Convert.ToBase64String(hashBytes),
                        LastUpdated = _fileSystem.GetLastModified(path),
                        Created     = _fileSystem.GetCreated(path),
                        Path        = path,
                        FullPath    = _fileSystem.GetFullPath(path),

                        // default to false, these will be set later
                        IsAbsoluteLatestVersion = false,
                        IsLatestVersion         = false
                    };

                    if (checkFrameworks)
                    {
                        data.SupportedFrameworks = zip.GetSupportedFrameworks();
                    }

                    Tuple <IPackage, DerivedPackageData> entry = new Tuple <IPackage, DerivedPackageData>(zip, data);

                    // find the latest versions
                    string id = zip.Id.ToLowerInvariant();

                    // update with the highest version
                    absoluteLatest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);

                    // update latest for release versions
                    if (zip.IsReleaseVersion())
                    {
                        latest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);
                    }

                    // add the package to the cache, it should not exist already
                    Debug.Assert(packages.ContainsKey(zip) == false, "duplicate package added");
                    packages.AddOrUpdate(zip, entry.Item2, (oldPkg, oldData) => oldData);
                }
            });

            // Set additional attributes after visiting all packages
            foreach (var entry in absoluteLatest.Values)
            {
                entry.Item2.IsAbsoluteLatestVersion = true;
            }

            foreach (var entry in latest.Values)
            {
                entry.Item2.IsLatestVersion = true;
            }

            return(packages);
        }
        /// <summary>
        /// CreateCache loads all packages and determines additional metadata such as the hash, IsAbsoluteLatestVersion, and IsLatestVersion.
        /// </summary>
        private IDictionary <IPackage, DerivedPackageData> CreateCache()
        {
            ConcurrentDictionary <IPackage, DerivedPackageData> packages = new ConcurrentDictionary <IPackage, DerivedPackageData>();

            ParallelOptions opts = new ParallelOptions();

            opts.MaxDegreeOfParallelism = 4;

            ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> > absoluteLatest = new ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> >();
            ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> > latest         = new ConcurrentDictionary <string, Tuple <IPackage, DerivedPackageData> >();

            // get settings
            bool checkFrameworks = EnableFrameworkFiltering;
            bool enableDelisting = EnableDelisting;
            // we need to save the current context because it's stored in TLS and we're computing hashes on different threads.
            var context = HttpContext.Current;

            // load and cache all packages.
            // Note that we can't pass GetPackageFiles() to Parallel.ForEach() because
            // the file could be added/deleted from _fileSystem, and if this happens,
            // we'll get error "Collection was modified; enumeration operation may not execute."
            // So we have to materialize the IEnumerable into a list first.
            var packageFiles = GetPackageFiles().ToList();

            Parallel.ForEach(packageFiles, opts, path =>
            {
                OptimizedZipPackage zip = OpenPackage(path);

                Debug.Assert(zip != null, "Unable to open " + path);
                if (zip == null)
                {
                    return;
                }
                if (enableDelisting)
                {
                    // hidden packages are considered delisted
                    zip.Listed = !File.GetAttributes(_fileSystem.GetFullPath(path)).HasFlag(FileAttributes.Hidden);
                }

                string packageHash       = null;
                long packageSize         = 0;
                string persistedHashFile = EnablePersistNupkgHash ? GetHashFile(path, false) : null;
                bool hashComputeNeeded   = true;

                ReadHashFile(context, path, persistedHashFile, ref packageSize, ref packageHash, ref hashComputeNeeded);

                if (hashComputeNeeded)
                {
                    using (var stream = _fileSystem.OpenFile(path))
                    {
                        packageSize = stream.Length;
                        packageHash = Convert.ToBase64String(HashProvider.CalculateHash(stream));
                    }
                    WriteHashFile(context, path, persistedHashFile, packageSize, packageHash);
                }

                var data = new DerivedPackageData
                {
                    PackageSize = packageSize,
                    PackageHash = packageHash,
                    LastUpdated = _fileSystem.GetLastModified(path),
                    Created     = _fileSystem.GetCreated(path),
                    Path        = path,
                    FullPath    = _fileSystem.GetFullPath(path),

                    // default to false, these will be set later
                    IsAbsoluteLatestVersion = false,
                    IsLatestVersion         = false
                };

                if (checkFrameworks)
                {
                    data.SupportedFrameworks = zip.GetSupportedFrameworks();
                }

                var entry = new Tuple <IPackage, DerivedPackageData>(zip, data);

                // find the latest versions
                string id = zip.Id.ToLowerInvariant();

                // update with the highest version
                absoluteLatest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);

                // update latest for release versions
                if (zip.IsReleaseVersion())
                {
                    latest.AddOrUpdate(id, entry, (oldId, oldEntry) => oldEntry.Item1.Version < entry.Item1.Version ? entry : oldEntry);
                }

                // add the package to the cache, it should not exist already
                Debug.Assert(packages.ContainsKey(zip) == false, "duplicate package added");
                packages.AddOrUpdate(zip, entry.Item2, (oldPkg, oldData) => oldData);
            });

            // Set additional attributes after visiting all packages
            foreach (var entry in absoluteLatest.Values)
            {
                entry.Item2.IsAbsoluteLatestVersion = true;
            }

            foreach (var entry in latest.Values)
            {
                entry.Item2.IsLatestVersion = true;
            }

            return(packages);
        }