protected void CheckForBadEnvironmentVariables(ElasticsearchEnvironmentConfiguration c) { var errors = new Dictionary <string, string>(); var classPathError = "Don't modify the classpath with ES_CLASSPATH, Best is to add "; classPathError += "additional elements via the plugin mechanism, or if code must really be "; classPathError += "added to the main classpath, add jars to lib, unsupported"; ErrorIfExists(c, errors, "ES_CLASSPATH", (k, v) => classPathError); const string t = "to %ES_JAVA_OPTS%"; const string i = "in jvm.options or add"; ErrorIfExists(c, errors, "ES_MIN_MEM", (k, v) => $"{k}={v}: set -Xms{v} {i} \"-Xms{v}\" {t}"); ErrorIfExists(c, errors, "ES_MAX_MEM", (k, v) => $"{k}={v}: set -Xmx{v} {i} \"-Xmx{v}\" {t}"); ErrorIfExists(c, errors, "ES_HEAP_SIZE", (k, v) => $"{k}={v}: set -Xms{v} and -Xmx{v} {i} \"-Xms{v} -Xmx{v}\" {t}"); ErrorIfExists(c, errors, "ES_HEAP_NEWSIZE", (k, v) => $"{k}={v}: set -Xmn{v} {i} \"-Xmn{v}\" {t}"); ErrorIfExists(c, errors, "ES_DIRECT_SIZE", (k, v) => $"{k}={v}: set -XX:MaxDirectMemorySize={v} {i} \"-XX:MaxDirectMemorySize={v}\" {t}"); ErrorIfExists(c, errors, "ES_USE_IPV4", (k, v) => $"{k}={v}: set -Djava.net.preferIPv4Stack=true {i} \"-Djava.net.preferIPv4Stack=true\" {t}"); ErrorIfExists(c, errors, "ES_GC_OPTS", (k, v) => $"{k}={v}: set %ES_GC_OPTS: = and % {i} \"{v}\" {t}"); ErrorIfExists(c, errors, "ES_GC_LOG_FILE", (k, v) => $"{k}={v}: set -Xloggc:{v} {i} \"-Xloggc:{v}\" {t}"); if (errors.Count == 0) { return; } var helpText = errors.Values.Aggregate(new StringBuilder(), (sb, v) => sb.AppendLine(v), sb => sb.ToString()); throw new StartupException("The following deprecated environment variables are set and preventing elasticsearch from starting", helpText); }
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); var elasticsearchConfiguration = new ElasticsearchEnvironmentConfiguration(esState); this.EsConfig = ElasticsearchYamlConfiguration.FromFolder(elasticsearchConfiguration.ConfigDirectory, fileSystem); this.JvmConfig = LocalJvmOptionsConfiguration.FromFolder(elasticsearchConfiguration.ConfigDirectory, fileSystem); this.InstallationModel = new ElasticsearchInstallationModel( wixState, JavaConfig, elasticsearchConfiguration, serviceState, pluginState, EsConfig, JvmConfig, session, args); this.FileSystem = fileSystem; }
public ElasticsearchProcessTesterStateProvider Elasticsearch( Func <MockElasticsearchEnvironmentStateProvider, MockElasticsearchEnvironmentStateProvider> setter) { this.ElasticsearchState = setter(new MockElasticsearchEnvironmentStateProvider()); this.ElasticsearchConfigState = new ElasticsearchEnvironmentConfiguration(this.ElasticsearchState); return(this); }
public TestableElasticsearchObservableProcess(ElasticsearchEnvironmentConfiguration env, ConsoleSession session, bool interactive = true) { _session = session; UserInteractive = interactive; this.ProcessVariables = new Dictionary <string, string>(); ElasticsearchObservableProcess.AlterProcessVariables(env, this.ProcessVariables, warn: false); }
public ElasticsearchProcessTesterStateProvider() { this.JavaState = new MockJavaEnvironmentStateProvider(); this.JavaConfigState = new JavaConfiguration(this.JavaState); this.ElasticsearchState = new MockElasticsearchEnvironmentStateProvider(); this.ElasticsearchConfigState = new ElasticsearchEnvironmentConfiguration(this.ElasticsearchState); }
public LocationsModel( ElasticsearchEnvironmentConfiguration elasticsearchEnvironmentConfiguration, ElasticsearchYamlConfiguration yamlConfiguration, VersionConfiguration versionConfig, IFileSystem fileSystem) { this.IsRelevant = !versionConfig.ExistingVersionInstalled; this.Header = "Locations"; this._elasticsearchEnvironmentConfiguration = elasticsearchEnvironmentConfiguration; this._yamlConfiguration = yamlConfiguration; this.CurrentVersion = versionConfig.CurrentVersion.ToString(); this.ExistingVersion = versionConfig.UpgradeFromVersion?.ToString(); this.FileSystem = fileSystem; this.Refresh(); this._refreshing = true; this.WhenAny( vm => vm.LogsDirectory, (c) => { var v = c.GetValue(); return(this.FileSystem.Path.IsPathRooted(v) ? this.FileSystem.Path.Combine(v, "elasticsearch.log") : null); }) .ToProperty(this, vm => vm.ElasticsearchLog, out elasticsearchLog); this.ThrownExceptions.Subscribe(e => { }); //If install, config, logs or data dir are set force ConfigureLocations to true this.WhenAny( vm => vm.InstallDir, vm => vm.ConfigDirectory, vm => vm.LogsDirectory, vm => vm.DataDirectory, (i, c, l, d) => !this._refreshing ) .Subscribe(x => { if (x) { this.ConfigureLocations = true; } }); this.WhenAny( vm => vm.ConfigureLocations, (c) => !this._refreshing && !c.Value ) .Subscribe(x => { if (x) { this.Refresh(); } }); this._refreshing = false; }
private static void ErrorIfExists(ElasticsearchEnvironmentConfiguration c, Dictionary <string, string> errors, string variable, Func <string, string, string> errorMessage) { var v = c.GetEnvironmentVariable(variable); if (string.IsNullOrWhiteSpace(v)) { return; } errors.Add(variable, errorMessage(variable, v)); }
public ElasticsearchProcess( IObservableProcess process, IConsoleOutHandler consoleOutHandler, IFileSystem fileSystem, ElasticsearchEnvironmentConfiguration env, JavaConfiguration java, IElasticsearchTool jvmOptionsParser, IElasticsearchTool javaVersionChecker, ManualResetEvent completedHandle, IEnumerable <string> args) : base( process ?? new ElasticsearchObservableProcess(env), consoleOutHandler ?? new ElasticsearchConsoleOutHandler(process?.UserInteractive ?? false), fileSystem, completedHandle) { CheckForBadEnvironmentVariables(env); var homeDirectory = env.HomeDirectory?.TrimEnd('\\') ?? throw new StartupException($"No {ElasticsearchEnvironmentStateProvider.EsHome} variable set and no home directory could be inferred from the executable location"); var configDirectory = env.ConfigDirectory?.TrimEnd('\\') ?? throw new StartupException($"{ElasticsearchEnvironmentStateProvider.ConfDir} was not explicitly set nor could it be determined from {ElasticsearchEnvironmentStateProvider.EsHome} or the current executable location"); this.HomeDirectory = homeDirectory; this.ConfigDirectory = configDirectory; this.PrivateTempDirectory = env.PrivateTempDirectory; this.GCLogsDirectory = Path.Combine(homeDirectory, "logs"); var parsedArguments = this.ParseArguments(args); var javaHome = java.JavaHomeCanonical; if (javaHome == null) { throw new StartupException("JAVA_HOME is not set and no Java installation could be found in the windows registry!"); } this.ProcessExe = java.JavaExecutable; if (!this.FileSystem.File.Exists(this.ProcessExe)) { throw new StartupException($"Java executable not found, this could be because of a faulty JAVA_HOME variable: {this.ProcessExe}"); } this.JvmOptionsParser = jvmOptionsParser; this.JavaVersionChecker = javaVersionChecker; this.Arguments = this.CreateObservableProcessArguments(parsedArguments); }
public ElasticsearchTool(string javaClass, JavaConfiguration java, ElasticsearchEnvironmentConfiguration env, IFileSystem fileSystem) { this.JavaClass = javaClass; var homeDirectory = env.HomeDirectory?.TrimEnd('\\') ?? throw new StartupException( $"No {ElasticsearchEnvironmentStateProvider.EsHome} variable set and no home directory could be inferred from the executable location"); this.WorkingDirectory = homeDirectory; var javaHome = java.JavaHomeCanonical; if (javaHome == null) { throw new StartupException("JAVA_HOME is not set and no Java installation could be found in the windows registry!"); } this.ProcessExe = java.JavaExecutable; if (!fileSystem.File.Exists(this.ProcessExe)) { throw new StartupException($"Java executable not found, this could be because of a faulty JAVA_HOME variable: {this.ProcessExe}"); } var libFolder = Path.Combine(homeDirectory, "lib"); if (!fileSystem.Directory.Exists(libFolder)) { throw new StartupException($"Expected a 'lib' directory inside: {homeDirectory}"); } var classPath = Path.Combine(libFolder, "*"); this.ProcessVariables = new Dictionary <string, string> { { "ES_TMPDIR", env.PrivateTempDirectory }, { "HOSTNAME", Environment.MachineName } }; this.FileSystem = fileSystem; this.Arguments = new[] { $"-cp \"{classPath}\" {javaClass}" }; }
public ElasticsearchProcess( IObservableProcess process, IConsoleOutHandler consoleOutHandler, IFileSystem fileSystem, ElasticsearchEnvironmentConfiguration env, JavaConfiguration java, IElasticsearchTool jvmOptionsParser, IElasticsearchTool javaVersionChecker, ManualResetEvent completedHandle, IEnumerable <string> args) : base( process ?? new ElasticsearchObservableProcess(env), consoleOutHandler ?? new ElasticsearchConsoleOutHandler(process?.UserInteractive ?? false), fileSystem, completedHandle) { CheckForBadEnvironmentVariables(env); var homeDirectory = env.HomeDirectory?.TrimEnd('\\') ?? throw new StartupException($"No {ElasticsearchEnvironmentStateProvider.EsHome} variable set and no home directory could be inferred from the executable location"); var configDirectory = env.ConfigDirectory?.TrimEnd('\\') ?? throw new StartupException($"{ElasticsearchEnvironmentStateProvider.ConfDir} was not explicitly set nor could it be determined from {ElasticsearchEnvironmentStateProvider.EsHome} or the current executable location"); this.HomeDirectory = homeDirectory; this.ConfigDirectory = configDirectory; this.PrivateTempDirectory = env.PrivateTempDirectory; var parsedArguments = this.ParseArguments(args); this.ProcessExe = java.JavaExecutable; if (!this.FileSystem.File.Exists(this.ProcessExe)) { throw new StartupException($"java.exe does not exist at {this.ProcessExe}"); } this.JvmOptionsParser = jvmOptionsParser; this.JavaVersionChecker = javaVersionChecker; this.Arguments = this.CreateObservableProcessArguments(parsedArguments); }
public LocationsModel( ElasticsearchEnvironmentConfiguration elasticsearchEnvironmentConfiguration, ElasticsearchYamlConfiguration yamlConfiguration, VersionConfiguration versionConfig) { this.IsRelevant = !versionConfig.ExistingVersionInstalled; this.Header = "Locations"; this._elasticsearchEnvironmentConfiguration = elasticsearchEnvironmentConfiguration; this._yamlConfiguration = yamlConfiguration; this.Refresh(); this._refreshing = true; //when configurelocations is checked and place paths in samefolder is not set, set configureall locations to true var prop = this.WhenAny( vm => vm.ConfigureLocations, vm => vm.PlaceWritableLocationsInSamePath, vm => vm.InstallDir, (configureLocations, samePath, i) => configureLocations.GetValue() && !samePath.GetValue() ) .ToProperty(this, vm => vm.ConfigureAllLocations, out configureAllLocations); this.WhenAny( vm => vm.LogsDirectory, (c) => { var v = c.GetValue(); return(Path.IsPathRooted(v) ? Path.Combine(v, "elasticsearch.log") : null); }) .ToProperty(this, vm => vm.ElasticsearchLog, out elasticsearchLog); this.ThrownExceptions.Subscribe(e => { }); //If install, config, logs or data dir are set force ConfigureLocations to true this.WhenAny( vm => vm.InstallDir, vm => vm.ConfigDirectory, vm => vm.LogsDirectory, vm => vm.DataDirectory, (i, c, l, d) => !this._refreshing ) .Subscribe(x => { if (x) { this.ConfigureLocations = true; } }); this.WhenAny( vm => vm.ConfigureLocations, (c) => !this._refreshing && !c.Value ) .Subscribe(x => { if (x) { this.Refresh(); } }); this._refreshing = false; }
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(); }
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 ElasticsearchObservableProcess(ElasticsearchEnvironmentConfiguration environmentConfiguration) => this._env = environmentConfiguration;