/// <summary>
        /// Gets a new system list.
        /// </summary>
        public static void RefreshSystemList()
        {
            // Do not perform schema validation since we don't want to be forced into redeploying Program Runner after every schema change. We also don't have access
            // to the schema on non-development machines.
            var cacheFilePath = EwlStatics.CombinePaths(ConfigurationStatics.EwlFolderPath, "System List.xml");
            var cacheUsed     = false;

            try {
                ConfigurationLogic.ExecuteWithSystemManagerClient(
                    client => {
                    Task.Run(
                        async() => {
                        using (var response = await client.GetAsync("system-list", HttpCompletionOption.ResponseHeadersRead)) {
                            response.EnsureSuccessStatusCode();
                            using (var stream = await response.Content.ReadAsStreamAsync())
                                RsisSystemList = XmlOps.DeserializeFromStream <SystemList>(stream, false);
                        }
                    })
                    .Wait();
                });
            }
            catch (Exception e) {
                // Use the cached version of the system list if it is available.
                if (File.Exists(cacheFilePath))
                {
                    RsisSystemList = XmlOps.DeserializeFromFile <SystemList>(cacheFilePath, false);
                    cacheUsed      = true;
                }
                else
                {
                    throw new UserCorrectableException("Failed to download the system list and a cached version is not available.", e);
                }
            }

            StatusStatics.SetStatus(
                cacheUsed ? "Failed to download the system list; loaded a cached version from \"{0}\".".FormatWith(cacheFilePath) : "Downloaded the system list.");

            // Cache the system list so something is available in the future if the machine is offline.
            try {
                XmlOps.SerializeIntoFile(RsisSystemList, cacheFilePath);
            }
            catch (Exception e) {
                const string generalMessage = "Failed to cache the system list on disk.";
                if (e is UnauthorizedAccessException)
                {
                    throw new UserCorrectableException(generalMessage + " If the program is running as a non built in administrator, you may need to disable UAC.", e);
                }

                // An IOException probably means the file is locked. In this case we want to ignore the problem and move on.
                if (!(e is IOException))
                {
                    throw new UserCorrectableException(generalMessage, e);
                }
            }
        }
 private static void executeWebMethod <ContractType>(Action <ContractType> method, ChannelFactory <ContractType> factory, string action)
 {
     StatusStatics.SetStatus("Performing " + action + ".");
     try {
         using (var channel = (IDisposable)factory.CreateChannel())
             method((ContractType)channel);
     }
     catch (Exception e) {
         throw createWebServiceException(action, e);
     }
     StatusStatics.SetStatus("Performed " + action + ".");
 }
        private static ResultType executeWebMethodWithResult <ContractType, ResultType>(
            Func <ContractType, ResultType> method, ChannelFactory <ContractType> factory, string action)
        {
            StatusStatics.SetStatus("Performing " + action + ".");
            ResultType ret;

            try {
                using (var channel = (IDisposable)factory.CreateChannel())
                    ret = method((ContractType)channel);
            }
            catch (Exception e) {
                throw createWebServiceException(action, e);
            }
            StatusStatics.SetStatus("Performed " + action + ".");
            return(ret);
        }
        public static Action DownloadDataPackageAndGetDataUpdateMethod(
            ExistingInstallation installation, bool installationIsStandbyDb, RsisInstallation source, bool forceNewPackageDownload,
            OperationResult operationResult)
        {
            var recognizedInstallation = installation as RecognizedInstallation;
            var packageZipFilePath     = recognizedInstallation != null?source.GetDataPackage(forceNewPackageDownload, operationResult) : "";

            return(() => {
                IoMethods.ExecuteWithTempFolder(
                    tempFolderPath => {
                    var packageFolderPath = EwlStatics.CombinePaths(tempFolderPath, "Package");
                    if (packageZipFilePath.Any())
                    {
                        ZipOps.UnZipFileAsFolder(packageZipFilePath, packageFolderPath);
                    }

                    // Delete and re-create databases.
                    DatabaseOps.DeleteAndReCreateDatabaseFromFile(
                        installation.ExistingInstallationLogic.Database,
                        databaseHasMinimumDataRevision(installation.ExistingInstallationLogic.RuntimeConfiguration.PrimaryDatabaseSystemConfiguration),
                        packageFolderPath);
                    if (recognizedInstallation != null)
                    {
                        foreach (var secondaryDatabase in recognizedInstallation.RecognizedInstallationLogic.SecondaryDatabasesIncludedInDataPackages)
                        {
                            DatabaseOps.DeleteAndReCreateDatabaseFromFile(
                                secondaryDatabase,
                                databaseHasMinimumDataRevision(
                                    installation.ExistingInstallationLogic.RuntimeConfiguration.GetSecondaryDatabaseSystemConfiguration(
                                        secondaryDatabase.SecondaryDatabaseName)),
                                packageFolderPath);
                        }
                    }
                });

                DatabaseOps.WaitForDatabaseRecovery(installation.ExistingInstallationLogic.Database);
                if (recognizedInstallation != null)
                {
                    recompileProceduresInSecondaryOracleDatabases(recognizedInstallation);
                }

                if (!installationIsStandbyDb)
                {
                    // Bring database logic up to date with the rest of the logic in this installation. In other words, reapply changes lost when we deleted the database.
                    StatusStatics.SetStatus("Updating database logic...");
                    DatabaseOps.UpdateDatabaseLogicIfUpdateFileExists(
                        installation.ExistingInstallationLogic.Database,
                        installation.ExistingInstallationLogic.DatabaseUpdateFilePath,
                        installation.ExistingInstallationLogic.RuntimeConfiguration.InstallationType == InstallationType.Development);
                }

                // If we're an intermediate installation and we are getting data from a live installation, sanitize the data and do other conversion commands.
                if (installation is RecognizedInstalledInstallation recognizedInstalledInstallation &&
                    recognizedInstalledInstallation.KnownInstallationLogic.RsisInstallation.InstallationTypeElements is IntermediateInstallationElements &&
                    source.InstallationTypeElements is LiveInstallationElements)
                {
                    StatusStatics.SetStatus("Executing live -> intermediate conversion commands...");
                    doDatabaseLiveToIntermediateConversionIfCommandsExist(
                        installation.ExistingInstallationLogic.Database,
                        installation.ExistingInstallationLogic.RuntimeConfiguration.PrimaryDatabaseSystemConfiguration);
                    foreach (var secondaryDatabase in recognizedInstallation.RecognizedInstallationLogic.SecondaryDatabasesIncludedInDataPackages)
                    {
                        doDatabaseLiveToIntermediateConversionIfCommandsExist(
                            secondaryDatabase,
                            installation.ExistingInstallationLogic.RuntimeConfiguration.GetSecondaryDatabaseSystemConfiguration(secondaryDatabase.SecondaryDatabaseName));
                    }
                }
            });
        }