public ApplicationsController(ISecurityService securityService, IApplicationService applicationService, IUserService userService, ISectorService sectorService, INationalComponentService nationalComponentsService, IAppRegistry appRegistry, IVendorService vendorService) : base(securityService) { _applicationService = applicationService; _userService = userService; _sectorService = sectorService; _nationalComponentsService = nationalComponentsService; _appRegistry = appRegistry; _vendorService = vendorService; }
public InstallManagerActor(IAppRegistry registry, IConfiguration configuration, IAppManager manager, IAutoUpdater autoUpdater) { SubscribeAbility ability = new SubscribeAbility(this); ability.MakeReceive(); Receive <InstallerationCompled>(ic => ability.Send(ic)); Receive <InstallRequest>(o => Context.ActorOf(Props.Create <ActualInstallerActor>(registry, configuration, autoUpdater)).Forward(o)); Receive <UninstallRequest>(o => Context.ActorOf(Props.Create <ActualUninstallationActor>(registry, manager)).Forward(o)); }
static IEnumerable <IPreparedFeature> _(IAppRegistry appRegistry, IInstaller installer, InstallChecker installChecker, IIpcConnection ipc) { yield return(SubscribeFeature.New()); yield return(Feature.Create(() => new AppManagerActor(), new AppManagerState(appRegistry, installer, installChecker, ipc))); }
public sealed record AppManagerState(IAppRegistry AppRegistry, IInstaller Installer, InstallChecker InstallChecker, IIpcConnection Ipc);
static IEnumerable <IPreparedFeature> _(IAppRegistry registry, AppNodeInfo configuration, IAppManager manager, IAutoUpdater updater) { yield return(SubscribeFeature.New()); yield return(Feature.Create(() => new InstallManagerActor(), new InstallManagerState(registry, configuration, manager, updater))); }
public sealed record InstallManagerState(IAppRegistry Registry, AppNodeInfo Configuration, IAppManager AppManager, IAutoUpdater AutoUpdater);
public ActualInstallerActor(IAppRegistry registry, IConfiguration configuration, IAutoUpdater autoUpdater) { string appBaseLocation = configuration["AppsLocation"]; StartMessage <FileInstallationRequest>(HandleFileInstall); WhenStep(StepId.Start, c => c.OnExecute(cc => Preperation)); WhenStep(Preperation, config => { config.OnExecute((context, step) => { Log.Info("Perpering Data for Installation: {Apps}", context.Name); return(context.SetSource(InstallationSourceSelector.Select, step.SetError) .When(i => i != EmptySource.Instnace, () => StepId.Waiting.DoAnd(_ => registry.Actor .Ask <InstalledAppRespond>(new InstalledAppQuery(context.Name), TimeSpan.FromSeconds(5)) .PipeTo(Self)) , StepId.Fail)); }); Signal <InstalledAppRespond>((context, respond) => { if (!respond.Fault) { return(Validation.DoAnd(_ => context.SetInstalledApp(respond.App))); } SetError(ErrorCodes.QueryAppInfo); return(StepId.Fail); }); }); WhenStep(Validation, confg => { confg.OnExecute((context, step) => { Log.Info("Validating Data for installation: {Apps}", context.Name); if (context.Source.ValidateInput(context) is Status.Failure failure) { Log.Warning(failure.Cause, "Source Validation Failed {Apps}", context.Name); step.ErrorMessage = failure.Cause.Message; return(StepId.Fail); } // ReSharper disable once InvertIf if (!context.InstalledApp.IsEmpty() && context.InstalledApp.Name == context.Name && !context.Override) { Log.Warning("Apps is Installed {Apps}", context.Name); step.ErrorMessage = ErrorCodes.ExistingApp; return(StepId.Fail); } return(PreCopy); }); }); WhenStep(PreCopy, config => { config.OnExecute((context, step) => { Log.Info("Prepare for Copy Data {Apps}", context.Name); string targetAppPath = Path.GetFullPath(Path.Combine(appBaseLocation, context.Name)); if (context.AppType != AppType.Host) { try { if (!Directory.Exists(targetAppPath)) { Directory.CreateDirectory(targetAppPath); } } catch (Exception e) { Log.Warning(e, "Installation Faild during Directory Creation {Apps}", context.Name); step.ErrorMessage = ErrorCodes.DirectoryCreation; return(StepId.Fail); } } context.InstallationPath = targetAppPath; context.Source.PreperforCopy(context) .PipeTo(Self, success: () => new PreCopyCompled()); if (context.AppType != AppType.Host) { if (context.Override) { context.Backup.Make(targetAppPath); context.Recovery.Add(context.Backup.Recover); } } return(StepId.Waiting); }); Signal <PreCopyCompled>((c, m) => Copy); }); WhenStep(Copy, config => { config.OnExecute((context, step) => { Log.Info("Copy Application Data {Apps}", context.Name); if (context.AppType == AppType.Host) { autoUpdater.Tell(new StartAutoUpdate(context.Source.ToZipFile(context))); return(StepId.Finish); } context.Recovery.Add(log => { log.Info("Clearing Installation Directory during Recover {Apps}", context.Name); context.InstallationPath.ClearDirectory(); }); try { context.Source.CopyTo(context, context.InstallationPath) .PipeTo(Self, success: () => new CopyCompled()); } catch (Exception e) { Log.Error(e, "Error on Extracting Files to Directory {Apps}", context.Name); step.ErrorMessage = e.Message; return(StepId.Fail); } context.Recovery.Add(log => { log.Info("Delete Insttalation Files during Recovery {Apps}", context.Name); context.InstallationPath.ClearDirectory(); }); return(StepId.Waiting); }); Signal <CopyCompled>((context, compled) => Registration); }); WhenStep(Registration, config => { config.OnExecute((context, step) => { Log.Info("Register Application for Host {Apps}", context.Name); if (context.InstalledApp.IsEmpty()) { registry.Actor .Ask <RegistrationResponse>( new NewRegistrationRequest(context.Name, context.InstallationPath, context.Source.Version, context.AppType, context.GetExe()), TimeSpan.FromSeconds(15)) .PipeTo(Self); } else { registry.Actor .Ask <RegistrationResponse>(new UpdateRegistrationRequest(context.Name), TimeSpan.FromSeconds(15)) .PipeTo(Self); } return(StepId.Waiting); }); Signal <RegistrationResponse>((context, response) => { if (response.Scceeded) { return(Finalization); } SetError(response.Error?.Message ?? ""); return(StepId.Fail); }); }); WhenStep(Finalization, config => { config.OnExecute(context => { Log.Info("Clean Up and Compleding {Apps}", context.Name); context.Backup.CleanUp(); try { context.Source.CleanUp(context); } catch (Exception e) { Log.Warning(e, "Error on Clean Up {Apps}", context.Name); } return(StepId.Finish); }); }); Signal <Failure>((ctx, f) => { SetError(f.Exception.Message); return(StepId.Fail); }); OnFinish(wr => { if (!wr.Succesfully) { Log.Warning("Installation Failed Recover {Apps}", wr.Context.Name); wr.Context.Recovery.Recover(Log); } var finish = new InstallerationCompled(wr.Succesfully, wr.Error, wr.Context.AppType, wr.Context.Name, InstallationAction.Install); if (!Sender.Equals(Context.System.DeadLetters)) { Sender.Tell(finish, ActorRefs.NoSender); } Context.Parent.Tell(finish); Context.Stop(Self); }); }
public ActualUninstallationActor(IAppRegistry registry, IAppManager manager) { WhenStep(StepId.Start, config => { config.OnExecute(context => { Log.Info("Start Unistall Apps {Name}", context.Name); registry.Ask <InstalledAppRespond>(new InstalledAppQuery(context.Name), TimeSpan.FromSeconds(15)) .PipeTo(Self); return(StepId.Waiting); }); Signal <InstalledAppRespond>((context, respond) => { if (respond.Fault || respond.App.IsEmpty()) { Log.Warning("Error on Query Application Info {Name}", context.Name); SetError(ErrorCodes.QueryAppInfo); return(StepId.Fail); } context.App = respond.App; return(Stopping); }); }); WhenStep(Stopping, config => { config.OnExecute(context => { Log.Info("Stoping Appliocation {Name}", context.Name); manager.Actor .Ask <StopResponse>(new StopApp(context.Name), TimeSpan.FromMinutes(1)) .PipeTo(Self); return(StepId.Waiting); }); Signal <StopResponse>((context, response) => Unistall); }); WhenStep(Unistall, config => { config.OnExecute((context, step) => { try { Log.Info("Backup Application {Name}", context.Name); context.Backup.Make(context.App.Path); } catch (Exception e) { Log.Error(e, "Error while making Backup"); step.ErrorMessage = e.Message; return(StepId.Fail); } context.Recovery.Add(context.Backup.Recover); try { Log.Info("Delete Application Directory {Name}", context.Name); Directory.Delete(context.App.Path, true); } catch (Exception e) { Log.Warning(e, "Error while Deleting Apps Directory"); } return(Finalization); }); }); Signal <Failure>((ctx, f) => { SetError(f.Exception.Message); return(StepId.Fail); }); OnFinish(wr => { if (!wr.Succesfully) { Log.Warning("Installation Failed Recover {Apps}", wr.Context.Name); wr.Context.Recovery.Recover(Log); } var finish = new InstallerationCompled(wr.Succesfully, wr.Error, wr.Context.App.AppType, wr.Context.Name, InstallationAction.Uninstall); if (!Sender.Equals(Context.System.DeadLetters)) { Sender.Tell(finish, ActorRefs.NoSender); } Context.Parent.Tell(finish); Context.Stop(Self); }); }
public AppRegistryController(IAppRegistry appRegistry, ISecurityService securityService) : base(securityService) { _appRegistry = appRegistry; }
public AppManagerActor(IAppRegistry appRegistry, IInstaller installer, InstallChecker checker) { _appRegistry = appRegistry; var ability = new SubscribeAbility(this); installer.Actor .Tell(new EventSubscribe(typeof(InstallerationCompled))); Receive <UpdateTitle>(_ => Console.Title = "Application Host"); Receive <InstallerationCompled>(ic => { if (checker.IsInstallationStart) { Context.System.Terminate(); } void PipeToSelf(string name) { appRegistry.Actor .Ask <InstalledAppRespond>(new InstalledAppQuery(name), TimeSpan.FromSeconds(10)) .PipeTo(Self, success: ar => new StartApp(ar.App)); } if (ic.InstallAction != InstallationAction.Install || !ic.Succesfull) { return; } // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (ic.Type) { case AppType.Cluster: Cluster.Get(Context.System).RegisterOnMemberUp(() => PipeToSelf(ic.Name)); break; case AppType.StartUp: PipeToSelf(ic.Name); break; } }); Flow <StopApps>(b => b.Action(() => Context.GetChildren().Foreach(r => r.Tell(new InternalStopApp())))); Flow <StopApp>(b => b.Action(s => { var child = Context.Child(s.Name); if (child.IsNobody()) { Sender.Tell(new StopResponse(s.Name, false)); } else { child.Forward(new InternalStopApp()); } })); Flow <StopResponse>(b => b.Action(r => ability.Send(r))); Flow <StartApps>(b => { b.Action(sa => appRegistry.Actor .Ask <AllAppsResponse>(new AllAppsQuery()) .PipeTo(Self, Sender, r => new InternalFilterApps(sa.AppType, r.Apps))) .Then <InternalFilterApps>(b1 => b1.Action(fa => fa.Names.Foreach(s => Self.Tell(new InternalFilterApp(fa.AppType, s))))) .Then <InternalFilterApp>( b1 => b1.Action(fa => appRegistry.Actor .Ask <InstalledAppRespond>(new InstalledAppQuery(fa.Name)) .ContinueWith(t => { if (!t.IsCompletedSuccessfully && t.Result.Fault && t.Result.App.IsEmpty()) { return; } var data = t.Result.App; if (data.AppType != fa.AppType) { return; } Self.Tell(new StartApp(data)); }))) .Then <StartApp>(b1 => b1.Action(sa => { if (sa.App.IsEmpty()) { return; } if (!Context.Child(sa.App.Name).IsNobody()) { return; } Context.ActorOf(Props.Create <AppProcessActor>(sa.App)).Tell(new InternalStartApp()); })); }); Receive <Status.Failure>(f => Log.Error(f.Cause, "Error while processing message")); #region SharedApi Receive <StopAllApps>(_ => { Task.WhenAll(Context.GetChildren() .Select(ar => ar.Ask <StopResponse>(new InternalStopApp(), TimeSpan.FromMinutes(0.7))).ToArray()) .ContinueWith(t => new OperationResponse(t.IsCompletedSuccessfully && t.Result.All(s => !s.Error))) .PipeTo(Sender, failure: e => { Log.Warning(e, "Error on Shared Api Stop All Apps"); return(new OperationResponse(false)); }); }); Flow <StartAllApps>(b => b.Func(_ => { Self.Tell(new StartApps(AppType.Cluster)); return(new OperationResponse(true)); }).ToSender()); Receive <QueryAppStaus>(s => { var childs = Context.GetChildren().ToArray(); Task.Run(async() => { List <AppProcessActor.GetNameResponse> names = new List <AppProcessActor.GetNameResponse>(); foreach (var actorRef in childs) { try { names.Add(await actorRef.Ask <AppProcessActor.GetNameResponse>(new AppProcessActor.GetName(), TimeSpan.FromSeconds(5))); } catch (Exception e) { Log.Error(e, "Error on Recive Prcess Apps Name"); } } return(names.ToArray()); }).PipeTo(Sender, success: arr => new AppStatusResponse(s.OperationId, arr.ToImmutableDictionary(g => g.Name, g => g.Running)), failure: e => { Log.Error(e, "Error getting Status"); return(new AppStatusResponse(s.OperationId)); }); }); Receive <StopHostApp>(sha => { var pm = Context.Child(sha.AppName); if (pm.IsNobody()) { Context.Sender.Tell(new OperationResponse(false)); } pm.Ask <StopResponse>(new InternalStopApp(), TimeSpan.FromMinutes(1)) .PipeTo(Sender, success: () => new OperationResponse(true), failure: e => { Log.Warning(e, "Error on Shared Api Stop"); return(new OperationResponse(false)); }); }); Receive <StartHostApp> (sha => { if (string.IsNullOrWhiteSpace(sha.AppName)) { Sender.Tell(new OperationResponse(false)); } var pm = Context.Child(sha.AppName); if (pm.IsNobody()) { var self = Self; appRegistry.Actor.Ask <InstalledAppRespond>(new InstalledAppQuery(sha.AppName), TimeSpan.FromMinutes(1)) .ContinueWith(t => { if (t.Result.Fault) { return(new OperationResponse(false)); } self.Tell(new StartApp(t.Result.App)); return(new OperationResponse(true)); }) .PipeTo(Sender, failure: e => { Log.Warning(e, "Error on Shared Api Stop"); return(new OperationResponse(false)); }); } else { pm.Tell(new InternalStartApp()); Sender.Tell(new OperationResponse(true)); } }); #endregion ability.MakeReceive(); }