示例#1
0
 public Task <VersionDescriptor> UpdatePackageAsync(string packageName, NewNapackVersion newNapackVersion, UserSecret userSecret)
 {
     return(this.PatchAsync <VersionDescriptor, NewNapackVersion>("/napacks/" + packageName, newNapackVersion, userSecret,
                                                                  new Dictionary <HttpStatusCode, Exception>
     {
         [HttpStatusCode.BadRequest] = new InvalidNapackException("The napack contents were invalid!")
     }));
 }
示例#2
0
        public static NapackVersion CreateFromNewNapack(NewNapackVersion newNapackVersion)
        {
            NapackVersion version = new NapackVersion()
            {
                Authors      = newNapackVersion.Authors,
                Files        = newNapackVersion.Files,
                Dependencies = newNapackVersion.Dependencies ?? new List <NapackMajorVersion>()
            };

            return(version);
        }
示例#3
0
        public void AddVersion(NewNapackVersion newVersion)
        {
            foreach (string author in newVersion.Authors)
            {
                this.AllAuthors.Add(author);
            }

            const double charactersPerKiB = 124; // Assuming UTF8 and no special characters
            double       versionSizeInKiB = (double)newVersion.Files.Sum(file => file.Value.Contents.Length) / charactersPerKiB;

            this.AverageVersionSizeInkiB = (this.AverageVersionSizeInkiB * this.Versions + versionSizeInKiB) / (this.Versions + 1);

            TimeSpan updateFrequency = DateTime.UtcNow - this.LastUpdateTime;

            this.LastUpdateTime         = DateTime.UtcNow;
            this.AverageUpdateFrequency = TimeSpan.FromSeconds(
                ((this.AverageUpdateFrequency.TotalSeconds * this.Versions + updateFrequency.TotalSeconds) / (this.Versions + 1)));

            // This must go last to ensure proper average calculations.
            this.Versions++;
        }
        private void UpdatePackageMetadataStore(NapackMetadata package, NapackVersionIdentifier nextVersion, NapackAnalyst.UpversionType upversionType, NewNapackVersion newNapackVersion)
        {
            if (upversionType == NapackAnalyst.UpversionType.Major)
            {
                NapackMajorVersionMetadata newMajorVersionMetadata = new NapackMajorVersionMetadata()
                {
                    Recalled = false,
                    Versions = new Dictionary <int, List <int> >
                    {
                        [0] = new List <int> {
                            0
                        }
                    },
                    License = newNapackVersion.License
                };

                package.Versions.Add(nextVersion.Major, newMajorVersionMetadata);
            }
            else if (upversionType == NapackAnalyst.UpversionType.Minor)
            {
                package.Versions[nextVersion.Major].Versions.Add(nextVersion.Minor, new List <int> {
                    0
                });
            }
            else
            {
                package.Versions[nextVersion.Major].Versions[nextVersion.Minor].Add(nextVersion.Patch);
            }

            statsStore[nextVersion.NapackName].AddVersion(newNapackVersion);
            searchIndices[nextVersion.NapackName].LastUpdateTime  = statsStore[nextVersion.NapackName].LastUpdateTime;
            searchIndices[nextVersion.NapackName].LastUsedLicense = newNapackVersion.License;

            packageMetadataStore[nextVersion.NapackName] = package;
        }
        /// <summary>
        /// Saves a new napack version onto an existing napack.
        /// </summary>
        /// <param name="package">The package metadata.</param>
        /// <param name="currentVersion">The current version of the napack.</param>
        /// <param name="upversionType">The type of upversioning to perform.</param>
        /// <param name="newNapackVersion">The new napack version.</param>
        /// <param name="newVersionSpec">The napack specification.</param>
        public void SaveNewNapackVersion(NapackMetadata package, NapackVersionIdentifier currentVersion, NapackAnalyst.UpversionType upversionType, NewNapackVersion newNapackVersion, NapackSpec newVersionSpec)
        {
            NapackVersionIdentifier nextVersion    = new NapackVersionIdentifier(currentVersion.NapackName, currentVersion.Major, currentVersion.Minor, currentVersion.Patch);
            NapackVersion           packageVersion = NapackVersion.CreateFromNewNapack(newNapackVersion);

            foreach (string author in newNapackVersion.Authors)
            {
                AddAuthorConsumption(author, nextVersion);
            }

            // Changes in user authorization do not occur through napack version updates.

            foreach (NapackMajorVersion consumedPackage in newNapackVersion.Dependencies)
            {
                AddConsumingPackage(consumedPackage, nextVersion);
            }

            UpdatePackageMetadataStore(package, nextVersion, upversionType, newNapackVersion);
            packageStore.Add(nextVersion.GetFullName(), packageVersion);
            specStore.Add(nextVersion.GetFullName(), newVersionSpec);
        }
示例#6
0
        private void UpdatePackageMetadataStore(NapackMetadata package, NapackVersionIdentifier nextVersion, NapackAnalyst.UpversionType upversionType, NewNapackVersion newNapackVersion)
        {
            if (upversionType == NapackAnalyst.UpversionType.Major)
            {
                NapackMajorVersionMetadata newMajorVersionMetadata = new NapackMajorVersionMetadata()
                {
                    Recalled = false,
                    Versions = new Dictionary <int, List <int> >
                    {
                        [0] = new List <int> {
                            0
                        }
                    },
                    License = newNapackVersion.License
                };

                package.Versions.Add(nextVersion.Major, newMajorVersionMetadata);
            }
            else if (upversionType == NapackAnalyst.UpversionType.Minor)
            {
                package.Versions[nextVersion.Major].Versions.Add(nextVersion.Minor, new List <int> {
                    0
                });
            }
            else
            {
                package.Versions[nextVersion.Major].Versions[nextVersion.Minor].Add(nextVersion.Patch);
            }

            ExecuteTransactionCommand((command) =>
            {
                NapackStats stats = GetItem <NapackStats>(command, PackageStatsTable, "packageName", package.Name, "packageStat",
                                                          () => { throw new NapackStatsNotFoundException(package.Name); });
                stats.AddVersion(newNapackVersion);

                string statsEncoded = Serializer.Serialize(stats);
                command.Parameters.Add(statsEncoded);
                command.Parameters.Add(package.Name);
                command.CommandText = $"UPDATE {PackageStatsTable} SET packageStat = $1 WHERE packageName = $2";
                command.ExecuteNonQuery();
                command.Parameters.Clear();
            });

            UpdatePackageMetadata(package);
        }
示例#7
0
        public void SaveNewNapackVersion(NapackMetadata package, NapackVersionIdentifier currentVersion, NapackAnalyst.UpversionType upversionType, NewNapackVersion newNapackVersion, NapackSpec newVersionSpec)
        {
            NapackVersionIdentifier nextVersion    = new NapackVersionIdentifier(currentVersion.NapackName, currentVersion.Major, currentVersion.Minor, currentVersion.Patch);
            NapackVersion           packageVersion = NapackVersion.CreateFromNewNapack(newNapackVersion);

            foreach (string author in newNapackVersion.Authors)
            {
                AddItem(author.ToUpperInvariant(), nextVersion, AuthorPackageTable, "authorName", "packageVersionList", false);
            }

            //
            // // Changes in user authorization do not occur through napack version updates.
            //

            foreach (NapackMajorVersion consumedPackage in newNapackVersion.Dependencies)
            {
                AddItem(consumedPackage.ToString(), nextVersion, PackageConsumersTable, "packageMajorVersionId", "consumingPackages", false);
            }

            ExecuteTransactionCommand((command) =>
            {
                string napackSpecEncoded = Serializer.Serialize(newVersionSpec);
                command.Parameters.Add(nextVersion.GetFullName());
                command.Parameters.Add(napackSpecEncoded);
                command.CommandText = $"INSERT INTO {PackageSpecsTable} VALUES ($1, $2)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();

                string packageVersionEncoded = Serializer.Serialize(packageVersion);
                command.Parameters.Add(nextVersion.GetFullName());
                command.Parameters.Add(packageVersionEncoded);
                command.CommandText = $"INSERT INTO {PackageStoreTable} VALUES ($1, $2)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();
            });

            // Our lock is cleared at last here.
            UpdatePackageMetadataStore(package, nextVersion, upversionType, newNapackVersion);
        }
示例#8
0
        private static void ValidateDependentPackages(INapackStorageManager napackManager, NewNapackVersion newNapack)
        {
            // Validate dependent packages exist, aren't recalled, and have valid licenses.
            foreach (NapackMajorVersion napackVersion in newNapack.Dependencies)
            {
                NapackMetadata             package = napackManager.GetPackageMetadata(napackVersion.Name, false);
                NapackMajorVersionMetadata majorVersionMetadata = package.GetMajorVersion(napackVersion.Major);
                if (majorVersionMetadata.Recalled)
                {
                    // Users creating a new napack cannot use recalled packages as they have no reasonable chance of retrieving them.
                    throw new NapackRecalledException(napackVersion.Name, napackVersion.Major);
                }

                newNapack.License.VerifyCompatibility(napackVersion.Name, napackVersion.Major, majorVersionMetadata.License);
            }
        }
示例#9
0
        public NapackModule()
            : base("/napacks")
        {
            // Gets a Napack package or series of package versions.
            Get["/{packageName}/{version?}"] = parameters =>
            {
                string packageName = parameters.packageName;
                string version     = null;
                try
                {
                    version = parameters.version;
                }
                catch (RuntimeBinderException)
                {
                }

                if (version == null)
                {
                    // The user is asking for all major versions of the specified package.
                    NapackMetadata package = Global.NapackStorageManager.GetPackageMetadata(packageName, false);
                    return(this.Response.AsJson(package.AsSummaryJson()));
                }
                else
                {
                    // Attempt to parse our the version string.
                    List <int> components;
                    try
                    {
                        components = version.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Select(item => int.Parse(item)).ToList();
                    }
                    catch (Exception)
                    {
                        throw new InvalidNapackVersionException();
                    }

                    // Handle the resulting version components.
                    if (components.Count == 1 || components.Count == 2)
                    {
                        NapackMetadata             package      = Global.NapackStorageManager.GetPackageMetadata(packageName, false);
                        NapackMajorVersionMetadata majorVersion = package.GetMajorVersion(components[0]);

                        return(this.Response.AsJson(majorVersion.AsSummaryJson()));
                    }
                    else if (components.Count == 3)
                    {
                        NapackVersion specificVersion = Global.NapackStorageManager.GetPackageVersion(new NapackVersionIdentifier(packageName, components[0], components[1], components[2]));
                        Global.NapackStorageManager.IncrementPackageDownload(packageName);

                        return(this.Response.AsJson(specificVersion.AsSummaryJson()));
                    }
                    else
                    {
                        throw new InvalidNapackVersionException();
                    }
                }
            };

            // Creates a new Napack package.
            Post["/{packageName}"] = parameters =>
            {
                string packageName = parameters.packageName;
                if (Global.NapackStorageManager.ContainsNapack(packageName))
                {
                    throw new DuplicateNapackException();
                }

                // Validate user, name and API.
                NewNapack newNapack = SerializerExtensions.Deserialize <NewNapack>(this.Context);
                newNapack.Validate();

                UserIdentifier.VerifyAuthorization(this.Request.Headers.ToDictionary(hdr => hdr.Key, hdr => hdr.Value), Global.NapackStorageManager, newNapack.metadata.AuthorizedUserIds);
                NapackSpec generatedApiSpec = NapackAnalyst.CreateNapackSpec(packageName, newNapack.NewNapackVersion.Files);
                NapackModule.ValidateDependentPackages(Global.NapackStorageManager, newNapack.NewNapackVersion);

                newNapack.NewNapackVersion.UpdateNamespaceOfFiles(packageName, 1);
                Global.NapackStorageManager.SaveNewNapack(packageName, newNapack, generatedApiSpec);

                return(this.Response.AsJson(new
                {
                    Message = "Created package " + packageName
                }, HttpStatusCode.Created));
            };

            // Updates the definition (metadata) of a Napack package.
            Put["/{packageName"] = parameters =>
            {
                string         packageName = parameters.packageName;
                NapackMetadata package     = Global.NapackStorageManager.GetPackageMetadata(packageName, true);

                NewNapackMetadata metadata = SerializerExtensions.Deserialize <NewNapackMetadata>(this.Context);
                UserIdentifier.VerifyAuthorization(this.Request.Headers.ToDictionary(hdr => hdr.Key, hdr => hdr.Value), Global.NapackStorageManager, metadata.AuthorizedUserIds);

                if (metadata.AuthorizedUserIds.Count == 0)
                {
                    throw new InvalidNapackException("At least one authorized user ID must be provided.");
                }

                package.AuthorizedUserIds = metadata.AuthorizedUserIds;
                package.Description       = metadata.Description;
                package.MoreInformation   = metadata.MoreInformation;
                package.Tags = metadata.Tags;
                Global.NapackStorageManager.UpdatePackageMetadata(package);

                return(this.Response.AsJson(new
                {
                    Message = "Updated package metadata " + packageName
                }));
            };

            // Updates an existing Napack package.
            Patch["/{packageName}"] = parameters =>
            {
                NewNapackVersion newNapackVersion = SerializerExtensions.Deserialize <NewNapackVersion>(this.Context);
                newNapackVersion.Validate();

                string         packageName = parameters.packageName;
                NapackMetadata package     = Global.NapackStorageManager.GetPackageMetadata(packageName, true);
                UserIdentifier.VerifyAuthorization(this.Request.Headers.ToDictionary(hdr => hdr.Key, hdr => hdr.Value), Global.NapackStorageManager, package.AuthorizedUserIds);

                // Validate and create a spec for this new version.
                NapackSpec newVersionSpec = NapackAnalyst.CreateNapackSpec(packageName, newNapackVersion.Files);
                NapackModule.ValidateDependentPackages(Global.NapackStorageManager, newNapackVersion);

                // Determine what upversioning will be performed.
                int majorVersion = package.Versions.Max(version => version.Key);
                int minorVersion = package.Versions[majorVersion].Versions.Max(version => version.Key);
                int patchVersion = package.Versions[majorVersion].Versions[minorVersion].Max();

                NapackAnalyst.UpversionType upversionType = NapackAnalyst.UpversionType.Patch;
                if (newNapackVersion.ForceMajorUpversioning)
                {
                    // Skip analysis as we know we must go to a new major version.
                    upversionType = NapackAnalyst.UpversionType.Major;
                }
                else
                {
                    // Perform specification and license analysis.
                    NapackVersionIdentifier oldVersionId          = new NapackVersionIdentifier(packageName, majorVersion, minorVersion, patchVersion);
                    NapackSpec oldVersionSpec                     = Global.NapackStorageManager.GetPackageSpecification(oldVersionId);
                    NapackAnalyst.UpversionType specUpversionType = NapackAnalyst.DeterminedRequiredUpversioning(oldVersionSpec, newVersionSpec);
                    if (specUpversionType == NapackAnalyst.UpversionType.Major || newNapackVersion.License.NeedsMajorUpversioning(package.GetMajorVersion(majorVersion).License))
                    {
                        upversionType = NapackAnalyst.UpversionType.Major;
                    }
                }

                if (upversionType == NapackAnalyst.UpversionType.Patch && newNapackVersion.ForceMinorUpversioning)
                {
                    upversionType = NapackAnalyst.UpversionType.Minor;
                }

                newNapackVersion.UpdateNamespaceOfFiles(packageName, upversionType != NapackAnalyst.UpversionType.Major ? majorVersion : majorVersion + 1);
                Global.NapackStorageManager.SaveNewNapackVersion(package, new NapackVersionIdentifier(packageName, majorVersion, minorVersion, patchVersion), upversionType, newNapackVersion, newVersionSpec);

                return(this.Response.AsJson(new
                {
                    Message = "Updated package " + packageName,
                    Major = majorVersion,
                    Minor = minorVersion,
                    Patch = patchVersion
                }));
            };
        }