private void CheckPrerequisits(bool log) { if (log) { Logger.LogMessage("Name: " + this.Name); Logger.LogMessage("Edition: " + this.Edition); Logger.LogMessage("Type: " + this.Type); Logger.LogMessage("Level: " + this.Level); if (this.Level != PackageLevel.Tool) { Logger.LogMessage("Package version: " + this.VersionControl.Target); } if (this.Type == PackageType.Application) { Logger.LogMessage("AppId: {0}", this.AppId); } } if (Level == PackageLevel.Install) { // Workaround for creating an in-memory version info in case the // database does not exist yet (or will be overwritten anyway). if (Type == PackageType.Product) { RepositoryVersionInfo.SetInitialVersion(new ApplicationInfo { Name = this.Name, Edition = this.Edition, Version = this.VersionControl.Target, Description = this.Description }); } CheckInstall(RepositoryVersionInfo.Instance, log); } else { CheckUpdate(RepositoryVersionInfo.Instance, log); } }
public void Patching_System_InstalledComponents_Descriptions() { var installer = new ComponentInstaller { ComponentId = "C1", Version = new Version(1, 0), Description = "C1 component", ReleaseDate = new DateTime(2020, 07, 30), Dependencies = null }; var patch = new SnPatch { ComponentId = "C1", Version = new Version(2, 0), Description = "C1 patch", ReleaseDate = new DateTime(2020, 07, 31), Boundary = new VersionBoundary { MinVersion = new Version(1, 0) }, Dependencies = new[] { Dep("C2", "1.0 <= v <= 1.0"), } }; PackageManager.SavePackage(Manifest.Create(installer), null, true, null); PackageManager.SavePackage(Manifest.Create(patch), null, true, null); var verInfo = RepositoryVersionInfo.Create(CancellationToken.None); var components = verInfo.Components.ToArray(); Assert.AreEqual(1, components.Length); Assert.AreEqual("C1", components[0].ComponentId); Assert.AreEqual("2.0", components[0].Version.ToString()); Assert.AreEqual("C1 component", components[0].Description); Assert.AreEqual(1, components[0].Dependencies.Length); Assert.AreEqual("C2: 1.0 <= v <= 1.0", components[0].Dependencies[0].ToString()); }
protected virtual void Application_Start(object sender, EventArgs e, HttpApplication application) { using (var op = SnTrace.Repository.StartOperation("Application_Start. Process: {0}, AppDomain: {1}, ", System.Diagnostics.Process.GetCurrentProcess().Id, AppDomain.CurrentDomain.Id)) { var runOnceMarkerPath = application.Server.MapPath("/" + RunOnceGuid); var firstRun = File.Exists(runOnceMarkerPath); var startConfig = new RepositoryStartSettings { StartIndexingEngine = !firstRun, IsWebContext = true }; Repository.Start(startConfig); RepositoryVersionInfo.CheckComponentVersions(); StorageContext.L2Cache = new L2CacheImpl(); RegisterRoutes(RouteTable.Routes, application); RepositoryPathProvider.Register(); op.Successful = true; } }
private static void SavePackage(Manifest manifest, ExecutionContext executionContext, bool successful, Exception execError) { var executionResult = successful ? ExecutionResult.Successful : ExecutionResult.Faulty; var isAppPack = manifest.Type == PackageType.Application; RepositoryVersionInfo.Reset(); Package[] oldPacks = null; if (manifest.Level == PackageLevel.Tool) { oldPacks = RepositoryVersionInfo.Instance.InstalledPackages .Where(p => p.AppId == manifest.AppId && p.PackageLevel == PackageLevel.Tool && p.ExecutionResult == ExecutionResult.Unfinished) .OrderBy(p => p.ExecutionDate).ToArray(); } else { oldPacks = isAppPack ? RepositoryVersionInfo.Instance.InstalledPackages .Where(p => p.AppId == manifest.AppId && p.ApplicationVersion == manifest.VersionControl.Target) .OrderBy(p => p.ExecutionDate).ToArray() : RepositoryVersionInfo.Instance.InstalledPackages .Where(p => p.AppId == manifest.AppId && p.SenseNetVersion == manifest.VersionControl.Target) .OrderBy(p => p.ExecutionDate).ToArray(); } var oldPack = oldPacks.LastOrDefault(); if (oldPack == null) { var newPack = CreatePackage(manifest, executionResult, execError); DataProvider.Current.SavePackage(newPack); } else { UpdatePackage(oldPack, manifest, executionResult, execError); DataProvider.Current.UpdatePackage(oldPack); } }
private bool RunComponent(SnComponentInfo component) { try { RepositoryVersionInfo.CheckComponentVersions(new[] { component }, true); return(true); } catch (InvalidOperationException e) { if (e.Message.Contains("component is missing.")) { return(false); } throw; } catch (ApplicationException e) { if (e.Message.Contains("Component and assembly version mismatch.")) { return(false); } throw; } }
internal static void SavePackage(Manifest manifest, ExecutionResult executionResult, Exception execError, bool insertOnly = false) { // Ensure consistency of local version-info before determining the installed packages. RepositoryVersionInfo.Reset(true); var oldPacks = RepositoryVersionInfo.Instance.InstalledPackages; if (manifest.PackageType == PackageType.Tool) { oldPacks = oldPacks .Where(p => p.ComponentId == manifest.ComponentId && p.PackageType == PackageType.Tool && p.ExecutionResult == ExecutionResult.Unfinished); } else { oldPacks = oldPacks .Where(p => p.ComponentId == manifest.ComponentId && p.ComponentVersion == manifest.Version); } oldPacks = oldPacks.OrderBy(p => p.ExecutionDate).ToArray(); var oldPack = oldPacks.LastOrDefault(); if (oldPack == null || insertOnly) { var newPack = CreatePackage(manifest, executionResult, execError); Storage.SavePackageAsync(newPack, CancellationToken.None).GetAwaiter().GetResult(); } else { UpdatePackage(oldPack, manifest, executionResult, execError); Storage.UpdatePackageAsync(oldPack, CancellationToken.None).GetAwaiter().GetResult(); } // Ensure consistency of local version-info after persisting every executed package. RepositoryVersionInfo.Reset(true); }
protected virtual void Application_Start(object sender, EventArgs e, HttpApplication application) { using (var op = SnTrace.Repository.StartOperation("Application_Start. Process: {0}, AppDomain: {1}, ", System.Diagnostics.Process.GetCurrentProcess().Id, AppDomain.CurrentDomain.Id)) { var repositoryBuilder = new RepositoryBuilder { IsWebContext = true }; BuildRepository(repositoryBuilder); Repository.Start(repositoryBuilder); RepositoryVersionInfo.CheckComponentVersions(); StorageContext.L2Cache = new L2CacheImpl(); RegisterRoutes(RouteTable.Routes, application); RepositoryPathProvider.Register(); op.Successful = true; } }
private static void PatchAndCheck(string componentId, Version[] packageVersions, Version[] successfulPatchVersions, Version[] failedPatchVersions, Version expectedVersion) { Version initialVersion = null; // install mock packages if (packageVersions?.Any() ?? false) { // the first should be an install package, Patch packages will follow var install = true; foreach (var packageVersion in packageVersions) { PackageManager.Storage.SavePackage(new Package { ComponentId = componentId, ComponentVersion = packageVersion, ExecutionResult = ExecutionResult.Successful, PackageType = install ? PackageType.Install : PackageType.Patch }); install = false; } RepositoryVersionInfo.Reset(); initialVersion = packageVersions.Last(); } var installedComponent = RepositoryVersionInfo.Instance.Components.Single(c => c.ComponentId == componentId); if (installedComponent != null) { Assert.AreEqual(initialVersion, installedComponent.Version); } var assemblyComponent = RepositoryVersionInfo.GetAssemblyComponents() .Single(c => c.ComponentId == componentId); // ACTION var results = PackageManager.ExecuteAssemblyPatches(assemblyComponent); // reload version info installedComponent = RepositoryVersionInfo.Instance.Components.Single(c => c.ComponentId == componentId); if (successfulPatchVersions?.Any() ?? false) { // the component was successfully upgraded foreach (var patchVersion in successfulPatchVersions) { Assert.IsTrue(results[patchVersion].Successful); } } if (failedPatchVersions?.Any() ?? false) { // there should be failed patch results foreach (var patchVersion in failedPatchVersions) { Assert.IsFalse(results[patchVersion].Successful); } } if (!(successfulPatchVersions?.Any() ?? false) && !(failedPatchVersions?.Any() ?? false)) { // no patch is expected Assert.IsFalse(results?.Keys.Any() ?? false); } if (installedComponent != null) { Assert.AreEqual(expectedVersion, installedComponent.Version); } }
internal static PackagingResult ExecuteCurrentPhase(Manifest manifest, ExecutionContext executionContext) { var sysInstall = manifest.SystemInstall; var currentPhase = executionContext.CurrentPhase; if (0 == currentPhase - (sysInstall ? 1 : 0)) { SaveInitialPackage(manifest); } var stepElements = manifest.GetPhase(executionContext.CurrentPhase); var stopper = Stopwatch.StartNew(); Logger.LogMessage("Executing steps"); Exception phaseException = null; var successful = false; try { var maxStepId = stepElements.Count; for (int i = 0; i < maxStepId; i++) { var stepElement = stepElements[i]; var step = Step.Parse(stepElement, i, executionContext); var stepStopper = Stopwatch.StartNew(); Logger.LogStep(step, maxStepId); step.Execute(executionContext); stepStopper.Stop(); Logger.LogMessage("-------------------------------------------------------------"); Logger.LogMessage("Time: " + stepStopper.Elapsed); if (executionContext.Terminated) { LogTermination(executionContext); break; } } stopper.Stop(); Logger.LogMessage("============================================================="); Logger.LogMessage("All steps were executed."); Logger.LogMessage("Aggregated time: " + stopper.Elapsed); Logger.LogMessage("Errors: " + Logger.Errors); successful = true; } catch (Exception e) { phaseException = e; } var finished = executionContext.Terminated || (executionContext.CurrentPhase == manifest.CountOfPhases - 1); if (successful && !finished) { return new PackagingResult { NeedRestart = true, Successful = true, Errors = Logger.Errors } } ; if (executionContext.Terminated && executionContext.TerminationReason == TerminationReason.Warning) { successful = false; phaseException = new PackageTerminatedException(executionContext.TerminationMessage); } try { SavePackage(manifest, executionContext, successful, phaseException); } catch (Exception e) { if (phaseException != null) { Logger.LogException(phaseException); } throw new PackagingException("Cannot save the package.", e); } finally { RepositoryVersionInfo.Reset(); // we need to shut down messaging, because the line above uses it if (!executionContext.Test) { DistributedApplication.ClusterChannel.ShutDown(); } else { Diagnostics.SnTrace.Test.Write("DistributedApplication.ClusterChannel.ShutDown SKIPPED because it is a test context."); } } if (!successful && !executionContext.Terminated) { throw new ApplicationException(String.Format(SR.Errors.PhaseFinishedWithError_1, phaseException.Message), phaseException); } return(new PackagingResult { NeedRestart = false, Successful = successful, Terminated = executionContext.Terminated && !successful, Errors = Logger.Errors }); }
private void CheckUpdate(RepositoryVersionInfo versionInfo, bool log) { Version current = null; Version min = null; Version max = null; switch (this.Type) { case PackageType.Product: if (null != this.AppId) { throw new InvalidPackageException(SR.Errors.Manifest.UnexpectedAppId); } CheckEdition(versionInfo.OfficialVersion); current = versionInfo.OfficialVersion.AcceptableVersion; min = VersionControl.ExpectedProductMinimum; max = VersionControl.ExpectedProductMaximum; break; case PackageType.Application: var existingApplication = versionInfo.Applications.FirstOrDefault(a => a.AppId == this.AppId); if (existingApplication == null) { throw new PackagePreconditionException(SR.Errors.Precondition.AppIdDoesNotMatch); } CheckEdition(existingApplication); current = existingApplication.AcceptableVersion; min = VersionControl.ExpectedApplicationMinimum; max = VersionControl.ExpectedApplicationMaximum; break; default: throw new NotImplementedException("Unknown PackageType: " + this.Type); } if (log) { Logger.LogMessage("Current version: {0}", current); if (min != null && min == max) { Logger.LogMessage("Expected version: {0}", min); } else { if (min != null) { Logger.LogMessage("Expected minimum version: {0}", min); } if (max != null) { Logger.LogMessage("Expected maximum version: {0}", max); } } } if (min != null && min > current) { throw new PackagePreconditionException(String.Format(SR.Errors.Precondition.MinimumVersion_1, this.Type.ToString().ToLower())); } if (max != null && max < current) { throw new PackagePreconditionException(String.Format(SR.Errors.Precondition.MaximumVersion_1, this.Type.ToString().ToLower())); } if (Level != PackageLevel.Tool) { if (current >= VersionControl.Target) { throw new PackagePreconditionException(String.Format(SR.Errors.Precondition.TargetVersionTooSmall_3, this.Type.ToString().ToLower(), VersionControl.Target, current)); } } }
private static PackagingResult ExecuteCurrentPhase(Manifest manifest, ExecutionContext executionContext) { if (manifest.Type == PackageType.Product && manifest.Level == PackageLevel.Install) { // In case of product install create initial entry at the beginning of the // second phase, after the new db was created in the first phase. if (executionContext.CurrentPhase == 1) { SaveInitialPackage(manifest); } } else { if (executionContext.CurrentPhase == 0) { SaveInitialPackage(manifest); } } var stepElements = manifest.GetPhase(executionContext.CurrentPhase); var stopper = Stopwatch.StartNew(); Logger.LogMessage("Executing steps"); Exception phaseException = null; var successful = false; try { var maxStepId = stepElements.Count(); for (int i = 0; i < maxStepId; i++) { var stepElement = stepElements[i]; var step = Step.Parse(stepElement, i); executionContext.SubstituteParameters(step); var stepStopper = Stopwatch.StartNew(); Logger.LogStep(step, maxStepId); step.Execute(executionContext); stepStopper.Stop(); Logger.LogMessage("-------------------------------------------------------------"); Logger.LogMessage("Time: " + stepStopper.Elapsed); if (executionContext.Terminated) { LogTermination(executionContext); break; } } stopper.Stop(); Logger.LogMessage("============================================================="); Logger.LogMessage("All steps were executed."); Logger.LogMessage("Aggregated time: " + stopper.Elapsed); Logger.LogMessage("Errors: " + Logger.Errors); successful = true; } catch (Exception e) { phaseException = e; } var finished = executionContext.Terminated || (executionContext.CurrentPhase == manifest.CountOfPhases - 1); if (successful && !finished) { return new PackagingResult { NeedRestart = true, Successful = true, Errors = Logger.Errors } } ; if (executionContext.Terminated && executionContext.TerminationReason == TerminationReason.Warning) { successful = false; phaseException = new PackageTerminatedException(executionContext.TerminationMessage); } try { SavePackage(manifest, executionContext, successful, phaseException); } finally { RepositoryVersionInfo.Reset(); //we need to shut down messaging, because the line above uses it DistributedApplication.ClusterChannel.ShutDown(); } if (!successful && !executionContext.Terminated) { throw new ApplicationException(String.Format(SR.Errors.PhaseFinishedWithError_1, phaseException.Message), phaseException); } return(new PackagingResult { NeedRestart = false, Successful = successful, Terminated = executionContext.Terminated && !successful, Errors = Logger.Errors }); }
private void CheckPrerequisits(PackageParameter[] packageParameters, bool forcedReinstall, bool log, bool editConnectionString) { if (log) { Logger.LogMessage("ComponentId: {0}", this.ComponentId); Logger.LogMessage("PackageType: " + this.PackageType); Logger.LogMessage("Package version: " + this.Version); if (SystemInstall) { Logger.LogMessage(forcedReinstall ? "FORCED REINSTALL" : "SYSTEM INSTALL"); } } if (SystemInstall && editConnectionString) { //UNDONE:CNSTR: Get ConnectionStringOptions from ServiceProvider or another general location. var connectionStrings = new ConnectionStringOptions(); throw new SnNotSupportedException(); EditConnectionString(connectionStrings, this.Parameters, packageParameters); RepositoryVersionInfo.Reset(); } var versionInfo = RepositoryVersionInfo.Instance; var existingComponentInfo = versionInfo.Components.FirstOrDefault(a => a.ComponentId == ComponentId); if (PackageType == PackageType.Install) { if (!(forcedReinstall && SystemInstall) && existingComponentInfo != null) { // Install packages can be executed multiple times only if it is // allowed in the package AND the version in the manifest is the // same as in the db. if (!this.MultipleExecutionAllowed || existingComponentInfo.Version != this.Version) { throw new PackagePreconditionException( string.Format(SR.Errors.Precondition.CannotInstallExistingComponent1, this.ComponentId), PackagingExceptionType.CannotInstallExistingComponent); } } } else if (PackageType != PackageType.Tool) { if (existingComponentInfo == null) { throw new PackagePreconditionException(string.Format(SR.Errors.Precondition.CannotUpdateMissingComponent1, this.ComponentId), PackagingExceptionType.CannotUpdateMissingComponent); } if (existingComponentInfo.Version >= this.Version) { throw new PackagePreconditionException(string.Format(SR.Errors.Precondition.TargetVersionTooSmall2, this.Version, existingComponentInfo.Version), PackagingExceptionType.TargetVersionTooSmall); } } if (log && this.Dependencies.Any()) { Logger.LogMessage("Dependencies:"); } foreach (var dependency in this.Dependencies) { CheckDependency(dependency, versionInfo, log); } }
private static PackagingResult ExecuteCurrentPhase(Manifest manifest, ExecutionContext executionContext) { if (executionContext.CurrentPhase == 0) { SaveInitialPackage(manifest); } var steps = manifest.GetPhase(executionContext.CurrentPhase); var stopper = Stopwatch.StartNew(); Logger.LogMessage("Executing steps"); Exception phaseException = null; var successful = false; try { var maxStepId = steps.Count(); foreach (var step in steps) { var stepStopper = Stopwatch.StartNew(); Logger.LogStep(step, maxStepId); step.Execute(executionContext); stepStopper.Stop(); Logger.LogMessage("-------------------------------------------------------------"); Logger.LogMessage("Time: " + stepStopper.Elapsed); } stopper.Stop(); Logger.LogMessage("============================================================="); Logger.LogMessage("All steps were executed."); Logger.LogMessage("Aggregated time: " + stopper.Elapsed); Logger.LogMessage("Errors: " + Logger.Errors); successful = true; } catch (Exception e) { phaseException = e; } if (successful && (executionContext.CurrentPhase < manifest.CountOfPhases - 1)) { return new PackagingResult { NeedRestart = true, Successful = true, Errors = Logger.Errors } } ; try { if (Logger.Level <= LogLevel.Default) { SavePackage(manifest, executionContext, successful, phaseException); } } finally { RepositoryVersionInfo.Reset(); //we need to shut down messaging, because the line above uses it DistributedApplication.ClusterChannel.ShutDown(); } if (!successful) { throw new ApplicationException(String.Format(SR.Errors.PhaseFinishedWithError_1, phaseException.Message), phaseException); } return(new PackagingResult { NeedRestart = false, Successful = true, Errors = Logger.Errors }); }