void WritesExpectedDefaults() => DefaultValidModelForTasks(s => s .Elasticsearch(es => es .EsConfigMachineVariable(LocationsModel.DefaultConfigDirectory) ) .FileSystem(fs => { fs.AddFile(Path.Combine(LocationsModel.DefaultConfigDirectory, "jvm.options"), new MockFileData("")); return(fs); }) ) .AssertTask( (m, s, fs) => new EditJvmOptionsTask(m, s, fs), (m, t) => { var dir = m.LocationsModel.ConfigDirectory; var jvmOptionsFile = Path.Combine(dir, "jvm.options"); var jvmOptionsFileContents = t.FileSystem.File.ReadAllText(jvmOptionsFile); jvmOptionsFileContents.Should() .NotBeEmpty() .And.Contain($"-Xmx{ConfigurationModel.DefaultHeapSize}m") .And.Contain($"-Xms{ConfigurationModel.DefaultHeapSize}m"); var jvmOptions = LocalJvmOptionsConfiguration.FromFolder(dir, t.FileSystem); jvmOptions.ConfiguredHeapSize.Should().Be(ConfigurationModel.DefaultHeapSize); } );
public InstallationModelTester( MockWixStateProvider wixState, MockJavaEnvironmentStateProvider javaState, MockElasticsearchEnvironmentStateProvider esState, NoopServiceStateProvider serviceState, NoopPluginStateProvider pluginState, MockFileSystem fileSystem, NoopSession session, string[] args) { if (wixState == null) { throw new ArgumentNullException(nameof(wixState)); } if (javaState == null) { throw new ArgumentNullException(nameof(javaState)); } if (esState == null) { throw new ArgumentNullException(nameof(esState)); } this.JavaState = javaState; this.EsState = esState; this.PluginState = pluginState; this.JavaConfig = new JavaConfiguration(javaState); this.EsConfig = ElasticsearchYamlConfiguration.FromFolder(esState.ConfigDirectory, fileSystem); this.JvmConfig = LocalJvmOptionsConfiguration.FromFolder(esState.ConfigDirectory, fileSystem); this.InstallationModel = new InstallationModel( wixState, JavaConfig, esState, serviceState, pluginState, EsConfig, JvmConfig, session, args); this.FileSystem = fileSystem; }
void PicksUpExistingConfiguration() => WithValidPreflightChecks(s => s .Elasticsearch(e => e .EsConfigMachineVariable(LocationsModel.DefaultConfigDirectory) ) .FileSystem(fs => { fs.AddFile(Path.Combine(LocationsModel.DefaultConfigDirectory, "jvm.options"), new MockFileData(@"-Xmx8000m -SomeOtherJvmOption")); return(fs); }) ) .AssertTask( (m, s, fs) => new EditJvmOptionsTask(m, s, fs), (m, t) => { var dir = m.LocationsModel.ConfigDirectory; var jvmOptionsFile = Path.Combine(dir, "jvm.options"); var jvmOptionsFileContents = t.FileSystem.File.ReadAllText(jvmOptionsFile); jvmOptionsFileContents.Should() .NotBeEmpty() .And.Contain("-Xmx8000m") .And.Contain("-SomeOtherJvmOption") ; var jvmOptions = LocalJvmOptionsConfiguration.FromFolder(dir, t.FileSystem); jvmOptions.ConfiguredHeapSize.Should().Be((ulong)8000); } );
void WritesConfiguredMemory() => WithValidPreflightChecks(s => s .Elasticsearch(es => es .EsConfigMachineVariable(LocationsModel.DefaultConfigDirectory) ) .FileSystem(fs => { fs.AddFile(Path.Combine(LocationsModel.DefaultConfigDirectory, "jvm.options"), new MockFileData("")); return(fs); }) ) .OnStep(m => m.ConfigurationModel, s => s.SelectedMemory = 1024) .AssertTask( (m, s, fs) => new EditJvmOptionsTask(m, s, fs), (m, t) => { var dir = m.LocationsModel.ConfigDirectory; var jvmOptionsFile = Path.Combine(dir, "jvm.options"); var jvmOptionsFileContents = t.FileSystem.File.ReadAllText(jvmOptionsFile); jvmOptionsFileContents.Should() .NotBeEmpty() .And.Contain($"-Xmx1024m") .And.Contain($"-Xms1024m"); var jvmOptions = LocalJvmOptionsConfiguration.FromFolder(dir, t.FileSystem); jvmOptions.ConfiguredHeapSize.Should().Be((ulong)1024); } );
public static InstallationModel Create(IWixStateProvider wixState, ISession session, params string[] args) { var javaConfig = JavaConfiguration.Default; var esState = ElasticsearchEnvironmentStateProvider.Default; var serviceState = ServiceStateProvider.FromSession(session); var pluginState = PluginStateProvider.Default; var esConfig = ElasticsearchYamlConfiguration.FromFolder(esState.ConfigDirectory); var jvmConfig = LocalJvmOptionsConfiguration.FromFolder(esState.ConfigDirectory); return(new InstallationModel(wixState, javaConfig, esState, serviceState, pluginState, esConfig, jvmConfig, session, args)); }
public ConfigurationModel(ElasticsearchYamlConfiguration yamlConfiguration, LocalJvmOptionsConfiguration localJvmOptions, IObservable <bool> upgradingFrom6OrNewInstallation) { this.Header = "Configuration"; this._localJvmOptions = localJvmOptions; this._yamlSettings = yamlConfiguration?.Settings; upgradingFrom6OrNewInstallation.Subscribe(b => this.UpgradingFrom6OrNewInstallation = b); this.Refresh(); this.AddSeedHost = ReactiveCommand.CreateAsyncTask(async _ => await this.AddSeedHostUserInterfaceTask()); this.WhenAnyObservable(vm => vm.AddSeedHost) .Subscribe(x => { if (string.IsNullOrWhiteSpace(x)) { return; } var nodes = x .Split(',') .Select(node => node.Trim()) .Where(n => !string.IsNullOrEmpty(n)) .Distinct(); foreach (var n in nodes) { this.SeedHosts.Add(n); } }); this.WhenAny( vm => vm.TotalPhysicalMemory, (maxMemory) => Math.Min(maxMemory.Value / 2, CompressedOrdinaryPointersThreshold) ) .ToProperty(this, vm => vm.MaxSelectedMemory, out maxSelectedMemory); var canRemoveNode = this.WhenAny(vm => vm.SelectedSeedHost, (selected) => !string.IsNullOrWhiteSpace(selected.GetValue())); this.RemoveSeedHost = ReactiveCommand.Create(canRemoveNode); this.RemoveSeedHost.Subscribe(x => { this.SeedHosts.Remove(this.SelectedSeedHost); }); this.WhenAnyValue(vm => vm.MasterNode).Subscribe(b => { // if we unset master node make sure InitialMaster is not set either. if (!b) { this.InitialMaster = false; } }); }
protected override bool ExecuteTask() { this.Session.SendActionStart(1000, ActionName, "Updating Elasticsearch JVM options", "Elasticsearch JVM options: [1]"); var selectedMemory = this.InstallationModel.ConfigurationModel.SelectedMemory; var heapSize = $"{selectedMemory}m"; var configDirectory = this.InstallationModel.LocationsModel.ConfigDirectory; var options = LocalJvmOptionsConfiguration.FromFolder(configDirectory, this.FileSystem); options.Xmx = heapSize; options.Xms = heapSize; options.Save(); this.Session.SendProgress(1000, "updated heap size to " + selectedMemory + "m"); return(true); }
public static ElasticsearchInstallationModel Create(IWixStateProvider wixState, ISession session, params string[] args) { var javaConfig = JavaConfiguration.Default; var esEnvironmentConfig = ElasticsearchEnvironmentConfiguration.Default; var serviceState = ServiceStateProvider.FromSession(session, "Elasticsearch"); var pluginState = PluginStateProviderBase.ElasticsearchDefault(session); var esConfig = ElasticsearchYamlConfiguration.FromFolder(esEnvironmentConfig.ConfigDirectory); var jvmConfig = LocalJvmOptionsConfiguration.FromFolder(esEnvironmentConfig.ConfigDirectory); var tempDirConfig = new TempDirectoryConfiguration(session, ElasticsearchEnvironmentStateProvider.Default, null); return(new ElasticsearchInstallationModel(wixState, javaConfig, esEnvironmentConfig, serviceState, pluginState, esConfig, jvmConfig, tempDirConfig, session, args)); }
[Fact] void WritesExpectedDefauls() => WithValidPreflightChecks() .AssertTask( (m, s, fs) => new EditJvmOptionsTask(m, s, fs), (m, t) => { var dir = m.LocationsModel.ConfigDirectory; var jvmOptionsFile = Path.Combine(dir, "jvm.options"); var jvmOptionsFileContents = t.FileSystem.File.ReadAllText(jvmOptionsFile); jvmOptionsFileContents.Should().NotBeEmpty() .And.Contain($"-Xmx{ConfigurationModel.DefaultHeapSize}m") .And.Contain($"-Xms{ConfigurationModel.DefaultHeapSize}m"); var jvmOptions = LocalJvmOptionsConfiguration.FromFolder(dir, t.FileSystem); jvmOptions.ConfiguredHeapSize.Should().Be(ConfigurationModel.DefaultHeapSize); } );
[Fact] void WritesConfiguredMemory() => WithValidPreflightChecks() .OnStep(m => m.ConfigurationModel, s => s.SelectedMemory = 1024) .AssertTask( (m, s, fs) => new EditJvmOptionsTask(m, s, fs), (m, t) => { var dir = m.LocationsModel.ConfigDirectory; var jvmOptionsFile = Path.Combine(dir, "jvm.options"); var jvmOptionsFileContents = t.FileSystem.File.ReadAllText(jvmOptionsFile); jvmOptionsFileContents.Should().NotBeEmpty() .And.Contain($"-Xmx1024m") .And.Contain($"-Xms1024m"); var jvmOptions = LocalJvmOptionsConfiguration.FromFolder(dir, t.FileSystem); jvmOptions.ConfiguredHeapSize.Should().Be((ulong)1024); } );
[Fact] void SettingMemoryToNull() { var jvmOpts = $@"-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:+HeapDumpOnOutOfMemoryError -Xmx8146m -Xms1024m "; var path = "C:\\Java\\jvm.options"; var fs = new MockFileSystem(new Dictionary <string, MockFileData> { { path, new MockFileData(jvmOpts) } }); var optsFile = new LocalJvmOptionsConfiguration(path, fs); optsFile.Xms.Should().Be("1024m"); optsFile.Xmx.Should().Be("8146m"); optsFile.Xms = null; optsFile.Xmx = null; optsFile.Save(); var fileContentsAfterSave = fs.File.ReadAllText(path); var jvmOptsAfterSave = $@"-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:+HeapDumpOnOutOfMemoryError "; fileContentsAfterSave.Replace("\r", "").Should().Be(jvmOptsAfterSave.Replace("\r", "")); }
public ConfigurationModel(ElasticsearchYamlConfiguration yamlConfiguration, LocalJvmOptionsConfiguration localJvmOptions) { this.Header = "Configuration"; this._localJvmOptions = localJvmOptions; this._yamlSettings = yamlConfiguration?.Settings; this.Refresh(); this.AddUnicastNode = ReactiveCommand.CreateAsyncTask(async _ => await this.AddUnicastNodeUITask()); this.WhenAnyObservable(vm => vm.AddUnicastNode) .Subscribe(x => { if (string.IsNullOrWhiteSpace(x)) { return; } var nodes = x .Split(',') .Select(node => node.Trim()) .Where(n => !string.IsNullOrEmpty(n)) .Distinct(); foreach (var n in nodes) { this.UnicastNodes.Add(n); } }); this.WhenAny( vm => vm.TotalPhysicalMemory, (maxMemory) => Math.Min(maxMemory.Value / 2, CompressedOrdinaryPointersThreshold) ) .ToProperty(this, vm => vm.MaxSelectedMemory, out maxSelectedMemory); var canRemoveNode = this.WhenAny(vm => vm.SelectedUnicastNode, (selected) => !string.IsNullOrWhiteSpace(selected.GetValue())); this.RemoveUnicastNode = ReactiveCommand.Create(canRemoveNode); this.RemoveUnicastNode.Subscribe(x => { this.UnicastNodes.Remove(this.SelectedUnicastNode); }); }
protected sealed override IEnumerable <string> CreateObservableProcessArguments(IEnumerable <string> args) { var libFolder = Path.Combine(this.HomeDirectory, "lib"); if (!FileSystem.Directory.Exists(libFolder)) { throw new StartupException($"Expected a 'lib' directory inside: {this.HomeDirectory}"); } var jars = new HashSet <string>(FileSystem.Directory.GetFiles(libFolder)); var elasticsearchJar = jars.FirstOrDefault(f => Path.GetFileName(f).StartsWith("elasticsearch-")); if (elasticsearchJar == null) { throw new StartupException($"No elasticsearch jar found in: {libFolder}"); } jars.ExceptWith(new [] { elasticsearchJar }); var libs = jars.ToArray(); var javaOpts = new LocalJvmOptionsConfiguration(Path.Combine(this.ConfigDirectory, "jvm.options")); var classPath = $"{elasticsearchJar};{string.Join(";", libs)}"; var arguments = javaOpts.Options .Concat(new [] { $"-Delasticsearch", $"-Des.path.home=\"{this.HomeDirectory}\"", $"-Des.path.conf=\"{this.ConfigDirectory}\"", $"-cp \"{classPath}\" org.elasticsearch.bootstrap.Elasticsearch" }) .Concat(args) .ToList(); return(arguments); }
[Fact] public void CommentsBlankLinesAndJDKDependantOptionsArePreserved() { var jvmOpts = $@"-XX:+UseParNewGC -XX:+UseConcMarkSweepGC ## COMMENT -XX:+UseCMSInitiatingOccupancyOnly 9-:-Djava.locale.providers=COMPAT "; var path = "C:\\Java\\jvm.options"; var fs = new MockFileSystem(new Dictionary <string, MockFileData> { { path, new MockFileData(jvmOpts) } }); var optsFile = new LocalJvmOptionsConfiguration(path, fs); optsFile.Save(); var fileContentsAfterSave = fs.File.ReadAllText(path); fileContentsAfterSave.Replace("\r", "").Should().Be(jvmOpts.Replace("\r", "")); }
public InstallationModel( IWixStateProvider wixStateProvider, JavaConfiguration javaConfiguration, IElasticsearchEnvironmentStateProvider environmentStateProvider, IServiceStateProvider serviceStateProvider, IPluginStateProvider pluginStateProvider, ElasticsearchYamlConfiguration yamlConfiguration, LocalJvmOptionsConfiguration localJvmOptions, ISession session, string[] args ) { this.Session = session; if (wixStateProvider == null) { throw new ArgumentNullException(nameof(wixStateProvider)); } if (javaConfiguration == null) { throw new ArgumentNullException(nameof(javaConfiguration)); } this._wixStateProvider = wixStateProvider; this.JavaConfiguration = javaConfiguration; this.ElasticsearchEnvironmentState = environmentStateProvider; this._yamlConfiguration = yamlConfiguration; var versionConfig = new VersionConfiguration(wixStateProvider); this.SameVersionAlreadyInstalled = versionConfig.SameVersionAlreadyInstalled; this.HigherVersionAlreadyInstalled = versionConfig.HigherVersionAlreadyInstalled; this.LocationsModel = new LocationsModel(environmentStateProvider, yamlConfiguration, versionConfig); this.NoticeModel = new NoticeModel(versionConfig, serviceStateProvider, this.LocationsModel); this.ServiceModel = new ServiceModel(serviceStateProvider, versionConfig); this.ConfigurationModel = new ConfigurationModel(yamlConfiguration, localJvmOptions); var pluginDependencies = this.WhenAnyValue( vm => vm.ConfigurationModel.IngestNode, vm => vm.NoticeModel.AlreadyInstalled, vm => vm.LocationsModel.InstallDir, vm => vm.LocationsModel.ConfigDirectory ); this.PluginsModel = new PluginsModel(pluginStateProvider, pluginDependencies); var observeHost = this.WhenAnyValue(vm => vm.ConfigurationModel.NetworkHost, vm => vm.ConfigurationModel.HttpPort, (h, p) => $"http://{(string.IsNullOrWhiteSpace(h) ? "localhost" : h)}:{p}"); var observeLog = this.WhenAnyValue(vm => vm.MsiLogFileLocation); var observeElasticsearchLog = this.WhenAnyValue(vm => vm.LocationsModel.ElasticsearchLog); var isUpgrade = versionConfig.InstallationDirection == InstallationDirection.Up; this.ClosingModel = new ClosingModel(wixStateProvider.CurrentVersion, isUpgrade, observeHost, observeLog, observeElasticsearchLog, serviceStateProvider); this.AllSteps = new ReactiveList <IStep> { this.NoticeModel, this.LocationsModel, this.ServiceModel, this.ConfigurationModel, this.PluginsModel, this.ClosingModel }; this.Steps = this.AllSteps.CreateDerivedCollection(x => x, x => x.IsRelevant); this.NextButtonText = TextResources.SetupView_NextText; var canMoveForwards = this.WhenAny(vm => vm.TabSelectedIndex, vm => vm.TabSelectionMax, (i, max) => i.GetValue() < max.GetValue()); this.Next = ReactiveCommand.Create(canMoveForwards); this.Next.Subscribe(i => { this.TabSelectedIndex = Math.Min(this.Steps.Count - 1, this.TabSelectedIndex + 1); }); var canMoveBackwards = this.WhenAny(vm => vm.TabSelectedIndex, (i) => i.GetValue() > 0); this.Back = ReactiveCommand.Create(canMoveBackwards); this.Back.Subscribe(i => { this.TabSelectedIndex = Math.Max(0, this.TabSelectedIndex - 1); }); this.Help = ReactiveCommand.Create(); this.ShowLicenseBlurb = ReactiveCommand.Create(); this.ShowCurrentStepErrors = ReactiveCommand.Create(); this.RefreshCurrentStep = ReactiveCommand.Create(); this.RefreshCurrentStep.Subscribe(x => { this.Steps[this.TabSelectedIndex].Refresh(); }); this.Exit = ReactiveCommand.Create(); var observeValidationChanges = this.WhenAny( vm => vm.NoticeModel.ValidationFailures, vm => vm.LocationsModel.ValidationFailures, vm => vm.ConfigurationModel.ValidationFailures, vm => vm.PluginsModel.ValidationFailures, vm => vm.ServiceModel.ValidationFailures, vm => vm.ClosingModel.ValidationFailures, vm => vm.TabSelectedIndex, (welcome, locations, configuration, plugins, service, install, index) => { var firstInvalidScreen = this.Steps.FirstOrDefault(s => !s.IsValid) ?? this.ClosingModel; return(firstInvalidScreen); }); var canInstall = observeValidationChanges.Select(s => s.IsValid); this.Install = ReactiveCommand.CreateAsyncTask(canInstall, _ => { this.TabSelectedIndex += 1; return(this.InstallUITask()); }); this.Install.Subscribe(installationObservable => { installationObservable.Subscribe(installed => { this.ClosingModel.Installed = installed; }); }); this.WhenAny(vm => vm.TabSelectedIndex, v => v.GetValue()) .Subscribe(i => { var c = this.Steps.Count; if (i == (c - 1)) { this.NextButtonText = TextResources.SetupView_ExitText; } else if (i == (c - 2)) { this.NextButtonText = TextResources.SetupView_InstallText; } else { this.NextButtonText = TextResources.SetupView_NextText; } }); observeValidationChanges .Subscribe(selected => { var step = this.Steps[this.TabSelectedIndex]; var failures = step.ValidationFailures; this.CurrentStepValidationFailures = selected.ValidationFailures; }); this.WhenAny( vm => vm.NoticeModel.IsValid, vm => vm.LocationsModel.IsValid, vm => vm.ConfigurationModel.IsValid, vm => vm.PluginsModel.IsValid, vm => vm.ServiceModel.IsValid, vm => vm.ClosingModel.IsValid, (welcome, locations, configuration, plugins, service, install) => { var firstInvalidScreen = this.Steps.Select((s, i) => new { s, i }).FirstOrDefault(s => !s.s.IsValid); return(firstInvalidScreen?.i ?? (this.Steps.Count - 1)); }) .Subscribe(selected => { this.TabSelectionMax = selected; //if one of the steps prior to the current selection is invalid jump back if (this.TabSelectedIndex > this.TabSelectionMax) { this.TabSelectedIndex = this.TabSelectionMax; } this.CurrentStepValidationFailures = this.ActiveStep.ValidationFailures; }); this.WhenAnyValue(view => view.ValidationFailures) .Subscribe(failures => { this.PrequisiteFailures = (failures ?? Enumerable.Empty <ValidationFailure>()) .Where(v => _prerequisiteProperties.Contains(v.PropertyName)) .ToList(); }); this.Refresh(); //validate the first stab explicitly on constructing this //main viewmodel. WPF triggers a validation already this.ParsedArguments = new InstallationModelArgumentParser(this.AllSteps.Cast <IValidatableReactiveObject>().Concat(new[] { this }).ToList(), args); this.ActiveStep.Validate(); }
public ElasticsearchInstallationModel( IWixStateProvider wixStateProvider, JavaConfiguration javaConfiguration, ElasticsearchEnvironmentConfiguration elasticsearchEnvironmentConfiguration, IServiceStateProvider serviceStateProvider, IPluginStateProvider pluginStateProvider, ElasticsearchYamlConfiguration yamlConfiguration, LocalJvmOptionsConfiguration localJvmOptions, ISession session, string[] args ) : base(wixStateProvider, session, args) { this.JavaConfiguration = javaConfiguration ?? throw new ArgumentNullException(nameof(javaConfiguration)); this.ElasticsearchEnvironmentConfiguration = elasticsearchEnvironmentConfiguration; this._yamlConfiguration = yamlConfiguration; var versionConfig = new VersionConfiguration(wixStateProvider); this.SameVersionAlreadyInstalled = versionConfig.SameVersionAlreadyInstalled; this.HigherVersionAlreadyInstalled = versionConfig.HigherVersionAlreadyInstalled; this.LocationsModel = new LocationsModel(elasticsearchEnvironmentConfiguration, yamlConfiguration, versionConfig); this.NoticeModel = new NoticeModel(versionConfig, serviceStateProvider, this.LocationsModel); this.ServiceModel = new ServiceModel(serviceStateProvider, versionConfig); this.ConfigurationModel = new ConfigurationModel(yamlConfiguration, localJvmOptions); var pluginDependencies = this.WhenAnyValue( vm => vm.ConfigurationModel.IngestNode, vm => vm.NoticeModel.AlreadyInstalled, vm => vm.LocationsModel.InstallDir, vm => vm.LocationsModel.ConfigDirectory ); this.PluginsModel = new PluginsModel(pluginStateProvider, pluginDependencies); var isUpgrade = versionConfig.InstallationDirection == InstallationDirection.Up; var observeHost = this.WhenAnyValue(vm => vm.ConfigurationModel.NetworkHost, vm => vm.ConfigurationModel.HttpPort, (h, p) => $"http://{(string.IsNullOrWhiteSpace(h) ? "localhost" : h)}:{p}"); var observeInstallationLog = this.WhenAnyValue(vm => vm.MsiLogFileLocation); var observeElasticsearchLog = this.WhenAnyValue(vm => vm.LocationsModel.ElasticsearchLog); var observeInstallXPack = this.PluginsModel.AvailablePlugins.ItemChanged .Where(x => x.PropertyName == nameof(Plugin.Selected) && x.Sender.PluginType == PluginType.XPack) .Select(x => x.Sender.Selected); this.ClosingModel = new ClosingModel(wixStateProvider.CurrentVersion, isUpgrade, observeHost, observeInstallationLog, observeElasticsearchLog, observeInstallXPack, serviceStateProvider); this.AllSteps = new ReactiveList <IStep> { this.NoticeModel, this.LocationsModel, this.ServiceModel, this.ConfigurationModel, this.PluginsModel, this.ClosingModel }; this.Steps = this.AllSteps.CreateDerivedCollection(x => x, x => x.IsRelevant); var observeValidationChanges = this.WhenAny( vm => vm.NoticeModel.ValidationFailures, vm => vm.LocationsModel.ValidationFailures, vm => vm.ConfigurationModel.ValidationFailures, vm => vm.PluginsModel.ValidationFailures, vm => vm.ServiceModel.ValidationFailures, vm => vm.ClosingModel.ValidationFailures, vm => vm.TabSelectedIndex, (welcome, locations, configuration, plugins, service, install, index) => { var firstInvalidScreen = this.Steps.FirstOrDefault(s => !s.IsValid) ?? this.ClosingModel; return(firstInvalidScreen); }); observeValidationChanges .Subscribe(selected => { var step = this.Steps[this.TabSelectedIndex]; var failures = step.ValidationFailures; this.CurrentStepValidationFailures = selected.ValidationFailures; }); this.WhenAny( vm => vm.NoticeModel.IsValid, vm => vm.LocationsModel.IsValid, vm => vm.ConfigurationModel.IsValid, vm => vm.PluginsModel.IsValid, vm => vm.ServiceModel.IsValid, vm => vm.ClosingModel.IsValid, (welcome, locations, configuration, plugins, service, install) => { var firstInvalidScreen = this.Steps.Select((s, i) => new { s, i }).FirstOrDefault(s => !s.s.IsValid); return(firstInvalidScreen?.i ?? (this.Steps.Count - 1)); }) .Subscribe(selected => { this.TabSelectionMax = selected; //if one of the steps prior to the current selection is invalid jump back if (this.TabSelectedIndex > this.TabSelectionMax) { this.TabSelectedIndex = this.TabSelectionMax; } this.CurrentStepValidationFailures = this.ActiveStep.ValidationFailures; }); this.Install = ReactiveCommand.CreateAsyncTask(observeValidationChanges.Select(s => s.IsValid), _ => { this.TabSelectedIndex += 1; return(this.InstallUITask()); }); this.Install.Subscribe(installationObservable => { installationObservable.Subscribe(installed => this.ClosingModel.Installed = installed); }); this.Refresh(); //validate the first stab explicitly on constructing this //main viewmodel. WPF triggers a validation already this.ParsedArguments = new ElasticsearchArgumentParser( this.AllSteps.Cast <IValidatableReactiveObject>().Concat(new[] { this }).ToList(), args); this.ActiveStep.Validate(); }
public ElasticsearchInstallationModel( IWixStateProvider wixStateProvider, JavaConfiguration javaConfiguration, ElasticsearchEnvironmentConfiguration elasticsearchEnvironmentConfiguration, IServiceStateProvider serviceStateProvider, IPluginStateProvider pluginStateProvider, ElasticsearchYamlConfiguration yamlConfiguration, LocalJvmOptionsConfiguration localJvmOptions, TempDirectoryConfiguration tempDirectoryConfiguration, IFileSystem fileSystem, ISession session, string[] args) : base(wixStateProvider, session, args) { this.JavaConfiguration = javaConfiguration ?? throw new ArgumentNullException(nameof(javaConfiguration)); this.ElasticsearchEnvironmentConfiguration = elasticsearchEnvironmentConfiguration; this.TempDirectoryConfiguration = tempDirectoryConfiguration; this._yamlConfiguration = yamlConfiguration; var versionConfig = new VersionConfiguration(wixStateProvider, this.Session.IsInstalled); this.SameVersionAlreadyInstalled = versionConfig.SameVersionAlreadyInstalled; this.UnInstalling = this.Session.IsUninstalling; this.InstallationInProgress = this._wixStateProvider.InstallationInProgress; this.Installing = this.Session.IsInstalling; this.Installed = this.Session.IsInstalled; this.Upgrading = this.Session.IsUpgrading; this.HigherVersionAlreadyInstalled = versionConfig.HigherVersionAlreadyInstalled; this.LocationsModel = new LocationsModel(elasticsearchEnvironmentConfiguration, yamlConfiguration, versionConfig, fileSystem); this.ServiceModel = new ServiceModel(serviceStateProvider, versionConfig); this.NoticeModel = new NoticeModel(versionConfig, serviceStateProvider, this.LocationsModel, this.ServiceModel); this.ConfigurationModel = new ConfigurationModel(yamlConfiguration, localJvmOptions); var pluginDependencies = this.WhenAnyValue( vm => vm.NoticeModel.ExistingVersionInstalled, vm => vm.LocationsModel.PreviousInstallationDirectory, vm => vm.LocationsModel.ConfigDirectory ); this.PluginsModel = new PluginsModel(pluginStateProvider, versionConfig.CurrentVersion, pluginDependencies); var upgradeFromXPackPlugin = this.WhenAnyValue(vm => vm.PluginsModel.PreviousInstallationHasXPack); var canAutomaticallySetup = this.WhenAnyValue(vm => vm.ServiceModel.StartAfterInstall, vm => vm.ServiceModel.InstallAsService) .Select(t => t.Item1 && t.Item2); this.XPackModel = new XPackModel(versionConfig, canAutomaticallySetup, upgradeFromXPackPlugin); var isUpgrade = versionConfig.InstallationDirection == InstallationDirection.Up; var observeHost = this.WhenAnyValue(vm => vm.ConfigurationModel.NetworkHost, vm => vm.ConfigurationModel.HttpPort, (h, p) => $"http://{(string.IsNullOrWhiteSpace(h) ? "localhost" : h)}:{p}"); var observeInstallationLog = this.WhenAnyValue(vm => vm.MsiLogFileLocation); var observeElasticsearchLog = this.WhenAnyValue(vm => vm.LocationsModel.ElasticsearchLog); this.ClosingModel = new ClosingModel(wixStateProvider.CurrentVersion, isUpgrade, observeHost, observeInstallationLog, observeElasticsearchLog, serviceStateProvider); this.AllSteps.AddRange(new List <IStep> { this.NoticeModel, this.LocationsModel, this.ServiceModel, this.ConfigurationModel, this.PluginsModel, this.XPackModel, this.ClosingModel }); this.AllSteps.ChangeTrackingEnabled = true; var observeValidationChanges = this.WhenAny( vm => vm.NoticeModel.ValidationFailures, vm => vm.LocationsModel.ValidationFailures, vm => vm.ConfigurationModel.ValidationFailures, vm => vm.PluginsModel.ValidationFailures, vm => vm.XPackModel.ValidationFailures, vm => vm.ServiceModel.ValidationFailures, vm => vm.ClosingModel.ValidationFailures, vm => vm.TabSelectedIndex, (welcome, locations, configuration, plugins, xpack, service, install, index) => { var firstInvalidScreen = this.Steps.FirstOrDefault(s => !s.IsValid) ?? this.ClosingModel; return(firstInvalidScreen); }); observeValidationChanges .Subscribe(firstInvalidStep => { this.TabFirstInvalidIndex = this.Steps .Select((s, i) => new { s, i = (int?)i }) .Where(t => !t.s.IsValid) .Select(t => t.i) .FirstOrDefault(); this.FirstInvalidStepValidationFailures = firstInvalidStep.ValidationFailures; }); this.WhenAny( vm => vm.NoticeModel.IsValid, vm => vm.LocationsModel.IsValid, vm => vm.ConfigurationModel.IsValid, vm => vm.PluginsModel.IsValid, vm => vm.XPackModel.IsValid, vm => vm.ServiceModel.IsValid, vm => vm.ClosingModel.IsValid, (welcome, locations, configuration, plugins, xpack, service, install) => { var firstInvalidScreen = this.Steps.Select((s, i) => new { s, i }).FirstOrDefault(s => !s.s.IsValid); return(firstInvalidScreen?.i ?? (this.Steps.Count - 1)); }) .Subscribe(selected => { this.TabSelectionMax = selected; //if one of the steps prior to the current selection is invalid jump back if (this.TabSelectedIndex > this.TabSelectionMax) { this.TabSelectedIndex = this.TabSelectionMax; } this.FirstInvalidStepValidationFailures = this.ActiveStep.ValidationFailures; }); this.Steps.Changed.Subscribe(e => { var firstInvalidScreen = this.Steps.Select((s, i) => new { s, i }).FirstOrDefault(s => !s.s.IsValid); var selectedTabIndex = firstInvalidScreen?.i ?? (this.Steps.Count - 1); this.TabSelectionMax = selectedTabIndex; //if one of the steps prior to the current selection is invalid jump back if (this.TabSelectedIndex > this.TabSelectionMax) { this.TabSelectedIndex = this.TabSelectionMax; } this.FirstInvalidStepValidationFailures = this.ActiveStep.ValidationFailures; }); this.Install = ReactiveCommand.CreateAsyncTask(observeValidationChanges.Select(s => s.IsValid), _ => { this.TabSelectedIndex += 1; return(this.InstallUITask()); }); this.Install.Subscribe(installationObservable => { installationObservable.Subscribe(installed => this.ClosingModel.Installed = installed); }); this.Refresh(); //validate the first stab explicitly on constructing this //main viewmodel. WPF triggers a validation already this.ParsedArguments = new ElasticsearchArgumentParser( this.AllSteps.Cast <IValidatableReactiveObject>().Concat(new[] { this }).ToList(), args); this.ActiveStep.Validate(); }