new services

master
Tudor Stanciu 2022-01-10 09:41:22 +02:00
parent 8f237cd2b7
commit e321769dd4
12 changed files with 183 additions and 56 deletions

View File

@ -1,6 +1,8 @@
using MediatR;
using AutoMapper;
using MediatR;
using Microsoft.Extensions.Logging;
using NetworkResurrector.Agent.Application.Services.Abstractions;
using NetworkResurrector.Agent.Domain.Models;
using NetworkResurrector.Agent.PublishedLanguage.Commands;
using NetworkResurrector.Agent.PublishedLanguage.Events;
using System.Diagnostics;
@ -12,14 +14,16 @@ namespace NetworkResurrector.Agent.Application.CommandHandlers
public class ShutdownHandler : IRequestHandler<Shutdown, ShutdownResult>
{
private readonly ILogger<ShutdownHandler> _logger;
private readonly IShutdownService _shutdownService;
private readonly IPowerService _powerService;
private readonly IValidationService _validationService;
private readonly IMapper _mapper;
public ShutdownHandler(ILogger<ShutdownHandler> logger, IShutdownService shutdownService, IValidationService validationService)
public ShutdownHandler(ILogger<ShutdownHandler> logger, IPowerService powerService, IValidationService validationService, IMapper mapper)
{
_logger=logger;
_shutdownService=shutdownService;
_powerService=powerService;
_validationService=validationService;
_mapper=mapper;
}
public async Task<ShutdownResult> Handle(Shutdown command, CancellationToken cancellationToken)
@ -36,7 +40,8 @@ namespace NetworkResurrector.Agent.Application.CommandHandlers
var stopWatch = new Stopwatch();
stopWatch.Start();
_shutdownService.Run();
var options = _mapper.Map<PowerOptions>(command.Options);
_powerService.Shutdown(options);
stopWatch.Stop();
_logger.LogDebug($"System shutdown finished - {stopWatch.ElapsedMilliseconds:N0} ms");

View File

@ -1,6 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using NetworkResurrector.Agent.Application.Services;
using NetworkResurrector.Agent.Application.Services.Abstractions;
using NetworkResurrector.Agent.Application.Services.Linux;
using NetworkResurrector.Agent.Application.Services.Windows;
using System;
using System.Runtime.InteropServices;
namespace NetworkResurrector.Agent.Application
{
@ -10,7 +14,18 @@ namespace NetworkResurrector.Agent.Application
{
services.AddSingleton<IParamProvider, ParamProvider>();
services.AddSingleton<IValidationService, ValidationService>();
services.AddSingleton<IShutdownService, ShutdownService>();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
services.AddSingleton<ICliService, CmdService>();
services.AddSingleton<IPowerService, WindowsPowerService>();
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
services.AddSingleton<ICliService, BashService>();
services.AddSingleton<IPowerService, LinuxPowerService>();
}
else throw new Exception("Cannot register IPowerService. Unknown operating system.");
}
}
}

View File

@ -1,4 +1,6 @@
using AutoMapper;
using NetworkResurrector.Agent.Domain.Models;
using NetworkResurrector.Agent.PublishedLanguage.Dto;
namespace NetworkResurrector.Agent.Application.Mappings
{
@ -6,7 +8,7 @@ namespace NetworkResurrector.Agent.Application.Mappings
{
public MappingProfile()
{
//CreateMap<Machine, GetMachines.Model>();
CreateMap<ActionOptions, PowerOptions>();
}
}
}

View File

@ -0,0 +1,7 @@
namespace NetworkResurrector.Agent.Application.Services.Abstractions
{
public interface ICliService
{
(bool success, string message) Execute(string command);
}
}

View File

@ -0,0 +1,10 @@
using NetworkResurrector.Agent.Domain.Models;
namespace NetworkResurrector.Agent.Application.Services.Abstractions
{
public interface IPowerService
{
void Shutdown(PowerOptions options);
void Lock();
}
}

View File

@ -1,7 +0,0 @@
namespace NetworkResurrector.Agent.Application.Services.Abstractions
{
public interface IShutdownService
{
void Run();
}
}

View File

@ -0,0 +1,13 @@
using NetworkResurrector.Agent.Application.Services.Abstractions;
using System;
namespace NetworkResurrector.Agent.Application.Services.Linux
{
internal class BashService : ICliService
{
public (bool success, string message) Execute(string command)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,19 @@
using NetworkResurrector.Agent.Application.Services.Abstractions;
using NetworkResurrector.Agent.Domain.Models;
using System;
namespace NetworkResurrector.Agent.Application.Services.Linux
{
internal class LinuxPowerService : IPowerService
{
public void Shutdown(PowerOptions options)
{
throw new NotImplementedException();
}
public void Lock()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,42 +0,0 @@
using Microsoft.Extensions.Logging;
using NetworkResurrector.Agent.Application.Services.Abstractions;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace NetworkResurrector.Agent.Application.Services
{
internal class ShutdownService : IShutdownService
{
private readonly ILogger<ShutdownService> _logger;
public ShutdownService(ILogger<ShutdownService> logger)
{
_logger=logger;
}
public void Run()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
ShutdownWindows();
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
// Do something
}
else throw new Exception("ShutdownService: Cannot shutdown host. Unknown operating system.");
}
private void ShutdownWindows()
{
var psi = new ProcessStartInfo("shutdown", "/s /t 0")
{
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(psi);
}
}
}

View File

@ -0,0 +1,66 @@
using Microsoft.Extensions.Logging;
using NetworkResurrector.Agent.Application.Services.Abstractions;
using System;
using System.Diagnostics;
using System.Text;
namespace NetworkResurrector.Agent.Application.Services.Windows
{
internal class CmdService : ICliService
{
private readonly ILogger<CmdService> _logger;
public CmdService(ILogger<CmdService> logger)
{
_logger=logger;
}
public (bool success, string message) Execute(string command)
{
var msg = new StringBuilder();
var commandOutput = new StringBuilder();
var commandError = new StringBuilder();
var process = new Process();
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "cmd.exe";
commandOutput.Clear();
commandError.Clear();
process.OutputDataReceived += new DataReceivedEventHandler(
(s, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
commandOutput.Append(e.Data + "\n");
});
process.ErrorDataReceived += new DataReceivedEventHandler(
(s, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
commandError.Append(e.Data + "\n");
});
msg.Append($"\nProcess started at: {DateTime.Now}\n");
process.Start();
process.StandardInput.WriteLine(command);
process.StandardInput.Flush();
process.StandardInput.Close();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
msg.Append($"Output:\n {commandOutput.ToString()}\n");
msg.Append($"Errors:\n {commandError.ToString()}\n");
msg.Append($"Process ended at: {DateTime.Now}");
_logger.LogDebug($"Command: {command} | ExecutionLog: {msg}");
return (commandError.Length > 0, msg.ToString());
}
}
}

View File

@ -0,0 +1,35 @@
using Microsoft.Extensions.Logging;
using NetworkResurrector.Agent.Application.Services.Abstractions;
using NetworkResurrector.Agent.Domain.Models;
using System.Diagnostics;
namespace NetworkResurrector.Agent.Application.Services.Windows
{
internal class WindowsPowerService : IPowerService
{
private readonly ILogger<WindowsPowerService> _logger;
private readonly ICliService _cliService;
public WindowsPowerService(ILogger<WindowsPowerService> logger)
{
_logger=logger;
}
public void Shutdown(PowerOptions options)
{
var psi = new ProcessStartInfo("shutdown", "/s /t 0")
{
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(psi);
}
public void Lock()
{
var (success, message) = _cliService.Execute("rundll32.exe user32.dll,LockWorkStation");
}
}
}

View File

@ -0,0 +1,4 @@
namespace NetworkResurrector.Agent.Domain.Models
{
public record PowerOptions(int Delay, bool Force);
}