Skip to content

Commit

Permalink
Avoid scheduling each mission twice
Browse files Browse the repository at this point in the history
  • Loading branch information
oysand committed Sep 29, 2022
1 parent e309bff commit 1341aa4
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 87 deletions.
4 changes: 2 additions & 2 deletions backend/api.test/Controllers/TestRobotController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public TestRobotController(DatabaseFixture fixture)
var missionService = new MissionService(context, missionServiceLogger.Object);
var isarService = new IsarService(
isarLogger.Object,
missionService,
isarDownstreamApi.Object
);
var echoService = new EchoService(config, echoDownstreamApi.Object);
Expand All @@ -41,7 +40,8 @@ public TestRobotController(DatabaseFixture fixture)
mockLoggerController.Object,
service,
isarService,
echoService
echoService,
missionService
);
}

Expand Down
58 changes: 0 additions & 58 deletions backend/api.test/EventHandlers/TestMissionScheduler.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Api.Controllers;
using Api.Controllers.Models;
using Api.Database.Context;
using Api.Database.Models;
using Api.EventHandlers;
Expand Down Expand Up @@ -44,35 +42,6 @@ public class TestMissionScheduler : IDisposable
MissionStatus = MissionStatus.Pending,
StartTime = DateTimeOffset.Now
};
private static EchoMission EchoMission =>
new()
{
Tags = new List<EchoTag>()
{
new EchoTag()
{
Id = 1,
Inspections = new List<EchoInspection>()
{
new EchoInspection(IsarStep.InspectionTypeEnum.Image, null)
},
TagId = "dummy-tag",
URL = new Uri("http://localhost:3000")
}
}
};
private static Mission TestOngoingMission =>
new()
{
Id = "id",
Robot = Robot,
IsarMissionId = "isarId",
EchoMissionId = 0,
MissionStatus = MissionStatus.Ongoing,
StartTime = DateTimeOffset.Now,
EndTime = DateTimeOffset.Now.AddMinutes(3),
Tasks = new List<IsarTask>()
};

public TestMissionScheduler(DatabaseFixture fixture)
{
Expand Down Expand Up @@ -159,33 +128,6 @@ MissionStatus postStatus
Assert.True(postMission!.MissionStatus == postStatus);
}

[Fact]
public void ScheduledMissionSetToOngoing()
{
// Mock happy path of 'RobotController.StartMission'

#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
_robotControllerMock.RobotServiceMock
.Setup(r => r.ReadById(Robot.Id))
.Returns(async () => Robot);
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
_robotControllerMock.IsarServiceMock
.Setup(
i =>
i.StartMission(
Robot,
It.IsAny<int>(),
It.IsAny<IsarMissionDefinition>()
).Result
)
.Returns(TestOngoingMission);
_robotControllerMock.EchoServiceMock
.Setup(i => i.GetMissionById(It.IsAny<int>()).Result)
.Returns(EchoMission);

AssertExpectedStatusChange(MissionStatus.Pending, MissionStatus.Ongoing);
}

[Fact]
public void ScheduledMissionSetTFailed()
{
Expand Down
3 changes: 2 additions & 1 deletion backend/api.test/Mocks/RobotControllerMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public RobotControllerMock()
mockLoggerController.Object,
RobotServiceMock.Object,
IsarServiceMock.Object,
EchoServiceMock.Object
EchoServiceMock.Object,
MissionServiceMock.Object
)
{
CallBase = true
Expand Down
35 changes: 27 additions & 8 deletions backend/api/Controllers/RobotController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Api.Controllers.Models;
using Api.Database.Models;
using Api.Services;
using Api.Services.Models;
using Api.Utilities;
using Microsoft.AspNetCore.Mvc;

Expand All @@ -15,18 +16,21 @@ public class RobotController : ControllerBase
private readonly IRobotService _robotService;
private readonly IIsarService _isarService;
private readonly IEchoService _echoService;
private readonly IMissionService _missionService;

public RobotController(
ILogger<RobotController> logger,
IRobotService robotService,
IIsarService isarService,
IEchoService echoService
IEchoService echoService,
IMissionService missionService
)
{
_logger = logger;
_robotService = robotService;
_isarService = isarService;
_echoService = echoService;
_missionService = missionService;
}

/// <summary>
Expand Down Expand Up @@ -175,7 +179,7 @@ [FromBody] Robot robot
/// <para> This query starts a mission for a given robot and creates a mission </para>
/// </remarks>
[HttpPost]
[Route("{robotId}/start/{echoMissionId}")]
[Route("{robotId}/start/{missionId}")]
[ProducesResponseType(typeof(Mission), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
Expand All @@ -184,7 +188,7 @@ [FromBody] Robot robot
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<Mission>> StartMission(
[FromRoute] string robotId,
[FromRoute] int echoMissionId
[FromRoute] string missionId
)
{
var robot = await _robotService.ReadById(robotId);
Expand All @@ -204,16 +208,24 @@ [FromRoute] int echoMissionId
return Conflict($"The Robot is not available ({robot.Status})");
}

var mission = await _missionService.ReadById(missionId);

if (mission == null)
{
_logger.LogWarning("Could not find mission with id={id}", missionId);
return NotFound("Mission not found");
}

EchoMission? echoMission;
try
{
echoMission = await _echoService.GetMissionById(echoMissionId);
echoMission = await _echoService.GetMissionById(mission.EchoMissionId);
}
catch (HttpRequestException e)
{
if (e.StatusCode.HasValue && (int)e.StatusCode.Value == 404)
{
_logger.LogWarning("Could not find echo mission with id={id}", echoMissionId);
_logger.LogWarning("Could not find echo mission with id={id}", mission.EchoMissionId);
return NotFound("Echo mission not found");
}

Expand All @@ -227,12 +239,12 @@ [FromRoute] int echoMissionId
return StatusCode(StatusCodes.Status500InternalServerError, message);
}

Mission mission;
IsarServiceStartMissionResponse isarServiceStartMissionResponse;
try
{
mission = await _isarService.StartMission(
isarServiceStartMissionResponse = await _isarService.StartMission(
robot,
echoMissionId,
mission.EchoMissionId,
new IsarMissionDefinition(echoMission)
);
}
Expand Down Expand Up @@ -264,6 +276,13 @@ [FromRoute] int echoMissionId
return StatusCode(StatusCodes.Status500InternalServerError, message);
}

mission.IsarMissionId = isarServiceStartMissionResponse.IsarMissionId;
mission.StartTime = isarServiceStartMissionResponse.StartTime;
mission.Tasks = isarServiceStartMissionResponse.Tasks;
mission.MissionStatus = MissionStatus.Ongoing;

await _missionService.Update(mission);

robot.Status = RobotStatus.Busy;
await _robotService.Update(robot);

Expand Down
4 changes: 1 addition & 3 deletions backend/api/EventHandlers/MissionScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private async Task<bool> StartMission(Mission scheduledMission)
{
var result = await RobotController.StartMission(
scheduledMission.Robot.Id,
scheduledMission.EchoMissionId
scheduledMission.Id
);
if (result.Result is not OkObjectResult)
{
Expand All @@ -80,8 +80,6 @@ private async Task<bool> StartMission(Mission scheduledMission)
_logger.LogError(e, "Failed to start mission '{id}'", scheduledMission.Id);
return false;
}
scheduledMission.MissionStatus = MissionStatus.Ongoing;
await MissionService.Update(scheduledMission);
return true;
}
}
Expand Down
24 changes: 9 additions & 15 deletions backend/api/Services/IsarService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
using System.Text.Json.Serialization;
using Api.Controllers.Models;
using Api.Database.Models;
using Api.Services.Models;
using Api.Utilities;
using Microsoft.Identity.Web;

namespace Api.Services
{
public interface IIsarService
{
public abstract Task<Mission> StartMission(
public abstract Task<IsarServiceStartMissionResponse> StartMission(
Robot robot,
int echoMissionId,
IsarMissionDefinition missionDefinition
Expand All @@ -28,16 +29,13 @@ public class IsarService : IIsarService
public const string ServiceName = "IsarApi";
private readonly IDownstreamWebApi _isarApi;
private readonly ILogger<IsarService> _logger;
private readonly IMissionService _missionService;

public IsarService(
ILogger<IsarService> logger,
IMissionService missionService,
IDownstreamWebApi downstreamWebApi
)
{
_logger = logger;
_missionService = missionService;
_isarApi = downstreamWebApi;
}

Expand Down Expand Up @@ -76,7 +74,7 @@ private async Task<HttpResponseMessage> CallApi(
);
}

public async Task<Mission> StartMission(
public async Task<IsarServiceStartMissionResponse> StartMission(
Robot robot,
int echoMissionId,
IsarMissionDefinition missionDefinition
Expand Down Expand Up @@ -111,22 +109,18 @@ IsarMissionDefinition missionDefinition

var tasks = ProcessIsarMissionResponse(isarMissionResponse);

var mission = new Mission
{
Robot = robot,
IsarMissionId = isarMissionResponse?.MissionId,
EchoMissionId = echoMissionId,
MissionStatus = MissionStatus.Pending,
StartTime = DateTimeOffset.UtcNow,
Tasks = tasks,
};
var isarServiceStartMissionResponse = new IsarServiceStartMissionResponse(
isarMissionId: isarMissionResponse.MissionId,
startTime: DateTimeOffset.UtcNow,
tasks: tasks
);

_logger.LogInformation(
"ISAR Mission '{missionId}' started on robot '{robotId}'",
isarMissionResponse?.MissionId,
robot.Id
);
return await _missionService.Create(mission);
return isarServiceStartMissionResponse;
}

public async Task<IsarStopMissionResponse> StopMission(Robot robot)
Expand Down
22 changes: 22 additions & 0 deletions backend/api/Services/Models/IsarServiceResponses.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using Api.Database.Models;
namespace Api.Services.Models
{
public class IsarServiceStartMissionResponse
{
[Required]
public string IsarMissionId { get; set; }

[Required]
public DateTimeOffset StartTime { get; set; }

[Required]
public IList<IsarTask> Tasks { get; set; }
public IsarServiceStartMissionResponse(string isarMissionId, DateTimeOffset startTime, IList<IsarTask> tasks)
{
IsarMissionId = isarMissionId;
StartTime = startTime;
Tasks = tasks;
}
}
}

0 comments on commit 1341aa4

Please sign in to comment.