/// <summary> /// Builds (and validates) a <see cref="DeploymentManager"/> asynchronously. /// </summary> public async Task <IUpdateManager> BuildAsync() { XDeployAPI api = new XDeployAPI(_config); await ValidateAPIAsync(api); var apps = await GetApplicationDetailsAsync(api, _config.Apps); ISyncSignalNotifier notifier; IEnumerable <IApplicationSynchronizer> synchronizers; switch (_config.Mode) { case ApplicationMode.Deployer: notifier = new SyncSignalServer(_config.SyncServerPort); synchronizers = apps.Select(x => new ApplicationDeployer(api, x)); break; case ApplicationMode.Updater: if (_config.Proxy != null) { notifier = new WebSocketsSignalNotifier(apps, _config.Endpoint, _config.Email, _config.APIKey, _config.Proxy); } else { notifier = new WebSocketsSignalNotifier(apps, _config.Endpoint, _config.Email, _config.APIKey); } synchronizers = apps.Select(x => new ApplicationUpdater(api, x)); break; default: throw new NotImplementedException($"Mode {_config.Mode} is not supported."); } return(new UpdateManager <IApplicationSynchronizer>(api, notifier, synchronizers)); }
/// <summary> /// Initializes a new instance of the <see cref="UpdateManagerBase"/> class. /// </summary> /// <param name="api">The API.</param> /// <exception cref="ArgumentNullException">api</exception> public UpdateManager(XDeployAPI api, ISyncSignalNotifier signalNotifier, IEnumerable <T> applicationSynchronizers) { if (api is null) { throw new ArgumentNullException(nameof(api)); } if (signalNotifier is null) { throw new ArgumentNullException(nameof(signalNotifier)); } if (applicationSynchronizers is null) { throw new ArgumentNullException(nameof(applicationSynchronizers)); } _api = api; _notifier = signalNotifier; _applicationSynchronizers = applicationSynchronizers; _notifier.SyncSignalReceived += async(_, id) => { Func <T, bool> idSelector = x => x.ApplicationID == id; if (_applicationSynchronizers.Any(idSelector)) { _ = await _applicationSynchronizers.First(idSelector).SynchronizeAsync(); } }; }
private static async Task ValidateAPIAsync(XDeployAPI api) { try { _ = await api.ValidateCredentialsAsync(); } catch (Exception e) { throw new StartupException($"Invalid API credentials provided.", e); } }
/// <summary> /// Initializes a new instance of the <see cref="ApplicationSynchronizerBase"/> class. /// </summary> /// <param name="api">The API.</param> /// <param name="app">The application.</param> /// <exception cref="ArgumentNullException"> /// api /// or /// app /// </exception> protected ApplicationSynchronizerBase(XDeployAPI api, ApplicationInfo app) { if (api is null) { throw new ArgumentNullException(nameof(api)); } if (app is null) { throw new ArgumentNullException(nameof(app)); } _api = api; _app = app; ; _fileManager = new DiskFileManager(app.Location); }
private static async Task <IEnumerable <ApplicationInfo> > GetApplicationDetailsAsync(XDeployAPI api, IEnumerable <ApplicationInfo> apps) { foreach (var app in apps) { try { var anon = new { encrypted = false, preDeployment = string.Empty, postDeployment = string.Empty }; var details = JsonConvert.DeserializeAnonymousType(await api.GetAppDetailsAsync(app.ID), anon); app.Encrypted = details.encrypted; app.PredeployActions = details.preDeployment?.ToString().Replace("\r", string.Empty).Split('\n').ToList(); app.PostdeployActions = details.postDeployment?.ToString().Replace("\r", string.Empty).Split('\n').ToList(); } catch (Exception e) { throw new StartupException($"Invalid app ID \"{app.ID}\" or unauthorized IP.", e); } if (!Directory.Exists(app.Location)) { throw new StartupException($"Invalid application path: {app.Location}", new DirectoryNotFoundException(app.Location)); } } return(apps); }
/// <summary> /// Initializes a new instance of the <see cref="ApplicationDeployer"/> class. /// </summary> /// <param name="api">The API.</param> /// <param name="app">The application.</param> public ApplicationDeployer(XDeployAPI api, ApplicationInfo app) : base(api, app) { }