From 979a43f49737520a6e37d583abb82acce0612639 Mon Sep 17 00:00:00 2001 From: Afonso Luz Date: Fri, 22 Dec 2023 01:17:36 +0100 Subject: [PATCH] Move OnIsarUnavailable to RobotService and rename --- .../api.test/Database/DatabaseUtilities.cs | 2 +- .../EventHandlers/TestMissionEventHandler.cs | 2 +- backend/api.test/Services/RobotService.cs | 10 +++-- backend/api/Controllers/RobotController.cs | 32 +++------------- .../api/Services/MissionSchedulingService.cs | 34 +---------------- backend/api/Services/RobotService.cs | 37 ++++++++++++++++++- 6 files changed, 51 insertions(+), 66 deletions(-) diff --git a/backend/api.test/Database/DatabaseUtilities.cs b/backend/api.test/Database/DatabaseUtilities.cs index 87359b41b..6ec518696 100644 --- a/backend/api.test/Database/DatabaseUtilities.cs +++ b/backend/api.test/Database/DatabaseUtilities.cs @@ -32,7 +32,7 @@ public DatabaseUtilities(FlotillaDbContext context) _areaService = new AreaService(context, _installationService, _plantService, _deckService, defaultLocalizationPoseService, _accessRoleService); _missionRunService = new MissionRunService(context, new MockSignalRService(), new Mock>().Object, _accessRoleService); _robotModelService = new RobotModelService(context); - _robotService = new RobotService(context, new Mock>().Object, _robotModelService, new MockSignalRService(), _accessRoleService, _installationService, _areaService); + _robotService = new RobotService(context, new Mock>().Object, _robotModelService, new MockSignalRService(), _accessRoleService, _installationService, _areaService, _missionRunService); } public void Dispose() diff --git a/backend/api.test/EventHandlers/TestMissionEventHandler.cs b/backend/api.test/EventHandlers/TestMissionEventHandler.cs index ee8579a62..b88e9fbf3 100644 --- a/backend/api.test/EventHandlers/TestMissionEventHandler.cs +++ b/backend/api.test/EventHandlers/TestMissionEventHandler.cs @@ -73,7 +73,7 @@ public TestMissionEventHandler(DatabaseFixture fixture) _plantService = new PlantService(_context, _installationService, _accessRoleService); _deckService = new DeckService(_context, _defaultLocalisationPoseService, _installationService, _plantService, _accessRoleService); _areaService = new AreaService(_context, _installationService, _plantService, _deckService, _defaultLocalisationPoseService, _accessRoleService); - _robotService = new RobotService(_context, robotServiceLogger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService); + _robotService = new RobotService(_context, robotServiceLogger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService, _missionRunService); _missionSchedulingService = new MissionSchedulingService(missionSchedulingServiceLogger, _missionRunService, _robotService, _robotControllerMock.Mock.Object, _areaService, _isarServiceMock); _localizationService = new LocalizationService(localizationServiceLogger, _robotService, _missionRunService, _installationService, _areaService); diff --git a/backend/api.test/Services/RobotService.cs b/backend/api.test/Services/RobotService.cs index 05809ba0a..a944c98b3 100644 --- a/backend/api.test/Services/RobotService.cs +++ b/backend/api.test/Services/RobotService.cs @@ -25,6 +25,7 @@ public class RobotServiceTest : IDisposable private readonly IDefaultLocalizationPoseService _defaultLocalizationPoseService; private readonly IDeckService _deckService; private readonly IAreaService _areaService; + private readonly IMissionRunService _missionRunService; public RobotServiceTest(DatabaseFixture fixture) { @@ -38,6 +39,7 @@ public RobotServiceTest(DatabaseFixture fixture) _defaultLocalizationPoseService = new DefaultLocalizationPoseService(_context); _deckService = new DeckService(_context, _defaultLocalizationPoseService, _installationService, _plantService, _accessRoleService); _areaService = new AreaService(_context, _installationService, _plantService, _deckService, _defaultLocalizationPoseService, _accessRoleService); + _missionRunService = new MissionRunService(_context, _signalRService, new Mock>().Object, _accessRoleService); } public void Dispose() @@ -49,7 +51,7 @@ public void Dispose() [Fact] public async Task ReadAll() { - var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService); + var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService, _missionRunService); var robots = await robotService.ReadAll(); Assert.True(robots.Any()); @@ -58,7 +60,7 @@ public async Task ReadAll() [Fact] public async Task Read() { - var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService); + var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService, _missionRunService); var robots = await robotService.ReadAll(); var firstRobot = robots.First(); var robotById = await robotService.ReadById(firstRobot.Id); @@ -69,7 +71,7 @@ public async Task Read() [Fact] public async Task ReadIdDoesNotExist() { - var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService); + var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService, _missionRunService); var robot = await robotService.ReadById("some_id_that_does_not_exist"); Assert.Null(robot); } @@ -77,7 +79,7 @@ public async Task ReadIdDoesNotExist() [Fact] public async Task Create() { - var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService); + var robotService = new RobotService(_context, _logger, _robotModelService, _signalRService, _accessRoleService, _installationService, _areaService, _missionRunService); var installationService = new InstallationService(_context, _accessRoleService); var installation = await installationService.Create(new CreateInstallationQuery diff --git a/backend/api/Controllers/RobotController.cs b/backend/api/Controllers/RobotController.cs index b0cad8ab2..3c961a6f0 100644 --- a/backend/api/Controllers/RobotController.cs +++ b/backend/api/Controllers/RobotController.cs @@ -384,7 +384,7 @@ [FromRoute] string missionRunId { string errorMessage = $"Could not reach ISAR at {robot.IsarUri}"; logger.LogError(e, "{Message}", errorMessage); - await OnIsarUnavailable(robot); + await robotService.SetRobotOffline(robot.Id); return StatusCode(StatusCodes.Status502BadGateway, errorMessage); } catch (MissionException e) @@ -451,7 +451,7 @@ public async Task StopMission([FromRoute] string robotId) { const string Message = "Error connecting to ISAR while stopping mission"; logger.LogError(e, "{Message}", Message); - await OnIsarUnavailable(robot); + await robotService.SetRobotOffline(robot.Id); return StatusCode(StatusCodes.Status502BadGateway, Message); } catch (MissionException e) @@ -510,7 +510,7 @@ public async Task PauseMission([FromRoute] string robotId) { const string Message = "Error connecting to ISAR while pausing mission"; logger.LogError(e, "{Message}", Message); - await OnIsarUnavailable(robot); + await robotService.SetRobotOffline(robot.Id); return StatusCode(StatusCodes.Status502BadGateway, Message); } catch (MissionException e) @@ -560,7 +560,7 @@ public async Task ResumeMission([FromRoute] string robotId) { const string Message = "Error connecting to ISAR while resuming mission"; logger.LogError(e, "{Message}", Message); - await OnIsarUnavailable(robot); + await robotService.SetRobotOffline(robot.Id); return StatusCode(StatusCodes.Status502BadGateway, Message); } catch (MissionException e) @@ -618,7 +618,7 @@ [FromRoute] string armPosition { string errorMessage = $"Error connecting to ISAR at {robot.IsarUri}"; logger.LogError(e, "{Message}", errorMessage); - await OnIsarUnavailable(robot); + await robotService.SetRobotOffline(robot.Id); return StatusCode(StatusCodes.Status502BadGateway, errorMessage); } catch (MissionException e) @@ -703,7 +703,7 @@ [FromBody] ScheduleLocalizationMissionQuery scheduleLocalizationMissionQuery { string message = $"Could not reach ISAR at {robot.IsarUri}"; logger.LogError(e, "{Message}", message); - await OnIsarUnavailable(robot); + await robotService.SetRobotOffline(robot.Id); return StatusCode(StatusCodes.Status502BadGateway, message); } catch (MissionException e) @@ -734,25 +734,5 @@ [FromBody] ScheduleLocalizationMissionQuery scheduleLocalizationMissionQuery return Ok(missionRun); } - private async Task OnIsarUnavailable(Robot robot) - { - robot.Enabled = false; - robot.Status = RobotStatus.Offline; - if (robot.CurrentMissionId != null) - { - var missionRun = await missionRunService.ReadById(robot.CurrentMissionId); - if (missionRun != null) - { - missionRun.SetToFailed(); - await missionRunService.Update(missionRun); - logger.LogWarning( - "Mission '{Id}' failed because ISAR could not be reached", - missionRun.Id - ); - } - } - - await robotService.UpdateCurrentMissionId(robot.Id, null); - } } } diff --git a/backend/api/Services/MissionSchedulingService.cs b/backend/api/Services/MissionSchedulingService.cs index 9ec6ff33b..b7eab8c88 100644 --- a/backend/api/Services/MissionSchedulingService.cs +++ b/backend/api/Services/MissionSchedulingService.cs @@ -107,7 +107,7 @@ public async Task StopCurrentMissionRun(string robotId) { const string Message = "Error connecting to ISAR while stopping mission"; logger.LogError(e, "{Message}", Message); - await OnIsarUnavailable(robot.Id); + await robotService.SetRobotOffline(robot.Id); throw new MissionException(Message, (int)e.StatusCode!); } catch (MissionException e) @@ -257,38 +257,6 @@ private async Task StartMissionRun(MissionRun queuedMissionRun) logger.LogInformation("Started mission run '{Id}'", queuedMissionRun.Id); } - private async Task OnIsarUnavailable(string robotId) - { - var robot = await robotService.ReadById(robotId); - if (robot == null) - { - logger.LogError("Robot with ID: {RobotId} was not found in the database", robotId); - return; - } - - if (robot.CurrentMissionId != null) - { - var missionRun = await missionRunService.ReadById(robot.CurrentMissionId); - if (missionRun != null) - { - missionRun.SetToFailed(); - await missionRunService.Update(missionRun); - logger.LogWarning( - "Mission '{Id}' failed because ISAR could not be reached", - missionRun.Id - ); - } - } - - try - { - await robotService.UpdateRobotStatus(robot.Id, RobotStatus.Offline); - await robotService.UpdateCurrentMissionId(robot.Id, null); - await robotService.UpdateRobotEnabled(robot.Id, false); - } - catch (RobotNotFoundException) { } - } - private static Pose ClosestSafePosition(Pose robotPose, IList safePositions) { if (safePositions == null || !safePositions.Any()) diff --git a/backend/api/Services/RobotService.cs b/backend/api/Services/RobotService.cs index 3f6582e15..108761bfa 100644 --- a/backend/api/Services/RobotService.cs +++ b/backend/api/Services/RobotService.cs @@ -26,6 +26,7 @@ public interface IRobotService public Task UpdateCurrentArea(string robotId, Area? area); public Task UpdateMissionQueueFrozen(string robotId, bool missionQueueFrozen); public Task Delete(string id); + public Task SetRobotOffline(string robotId); } [SuppressMessage( @@ -39,7 +40,8 @@ public class RobotService(FlotillaDbContext context, ISignalRService signalRService, IAccessRoleService accessRoleService, IInstallationService installationService, - IAreaService areaService) : IRobotService, IDisposable + IAreaService areaService, + IMissionRunService missionRunService) : IRobotService, IDisposable { private readonly Semaphore _robotSemaphore = new(1, 1); @@ -163,6 +165,39 @@ public async Task> ReadLocalizedRobotsForInstallation(string instal .ToListAsync(); } + public async Task SetRobotOffline(string robotId) + { + var robot = await ReadById(robotId); + if (robot == null) + { + logger.LogError("Robot with ID: {RobotId} was not found in the database", robotId); + return; + } + + if (robot.CurrentMissionId != null) + { + var missionRun = await missionRunService.ReadById(robot.CurrentMissionId); + if (missionRun != null) + { + missionRun.SetToFailed(); + await missionRunService.Update(missionRun); + logger.LogWarning( + "Mission '{Id}' failed because ISAR could not be reached", + missionRun.Id + ); + } + } + + try + { + await UpdateRobotStatus(robot.Id, RobotStatus.Offline); + await UpdateCurrentMissionId(robot.Id, null); + await UpdateRobotEnabled(robot.Id, false); + await UpdateCurrentArea(robot.Id, null); + } + catch (RobotNotFoundException) { } + } + private async Task UpdateRobotProperty(string robotId, string propertyName, object? value) { _robotSemaphore.WaitOne();