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);
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
 public ElasticsearchProcessTesterStateProvider Elasticsearch(
     Func <MockElasticsearchEnvironmentStateProvider, MockElasticsearchEnvironmentStateProvider> setter)
 {
     this.ElasticsearchState       = setter(new MockElasticsearchEnvironmentStateProvider());
     this.ElasticsearchConfigState = new ElasticsearchEnvironmentConfiguration(this.ElasticsearchState);
     return(this);
 }
Beispiel #4
0
 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);
 }
Beispiel #5
0
        public ElasticsearchProcessTesterStateProvider()
        {
            this.JavaState       = new MockJavaEnvironmentStateProvider();
            this.JavaConfigState = new JavaConfiguration(this.JavaState);

            this.ElasticsearchState       = new MockElasticsearchEnvironmentStateProvider();
            this.ElasticsearchConfigState = new ElasticsearchEnvironmentConfiguration(this.ElasticsearchState);
        }
Beispiel #6
0
        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));
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #11
0
        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();
        }
Beispiel #13
0
        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();
        }
Beispiel #14
0
 public ElasticsearchObservableProcess(ElasticsearchEnvironmentConfiguration environmentConfiguration) =>
 this._env = environmentConfiguration;