Skip to content

Commit

Permalink
Add readonly capability to missionruns
Browse files Browse the repository at this point in the history
  • Loading branch information
andchiind committed Aug 2, 2024
1 parent 75e49ae commit 7822f8c
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 74 deletions.
2 changes: 1 addition & 1 deletion backend/api/Controllers/MissionDefinitionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public async Task<ActionResult<MissionRun>> GetNextMissionRun([FromRoute] string
{
return NotFound($"Could not find mission definition with id {id}");
}
var nextRun = await missionRunService.ReadNextScheduledRunByMissionId(id);
var nextRun = await missionRunService.ReadNextScheduledRunByMissionId(id, readOnly: true);
return Ok(nextRun);
}

Expand Down
4 changes: 2 additions & 2 deletions backend/api/Controllers/MissionRunController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ [FromQuery] MissionRunQueryStringParameters parameters
PagedList<MissionRun> missionRuns;
try
{
missionRuns = await missionRunService.ReadAll(parameters);
missionRuns = await missionRunService.ReadAll(parameters, readOnly: true);
}
catch (InvalidDataException e)
{
Expand Down Expand Up @@ -83,7 +83,7 @@ [FromQuery] MissionRunQueryStringParameters parameters
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<MissionRunResponse>> GetMissionRunById([FromRoute] string id)
{
var missionRun = await missionRunService.ReadById(id);
var missionRun = await missionRunService.ReadById(id, readOnly: true);
if (missionRun == null)
{
return NotFound($"Could not find mission run with id {id}");
Expand Down
2 changes: 1 addition & 1 deletion backend/api/Controllers/MissionSchedulingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ [FromBody] ScheduleMissionQuery scheduledMissionQuery
catch (Exception e) when (e is RobotNotFoundException) { return NotFound(e.Message); }
catch (Exception e) when (e is RobotPreCheckFailedException) { return BadRequest(e.Message); }

var missionRun = await missionRunService.ReadByIdAsReadOnly(missionRunId);
var missionRun = await missionRunService.ReadById(missionRunId, readOnly: true);
if (missionRun == null) return NotFound("Mission run not found");

var missionTasks = missionRun.Tasks.Where((t) => t.Status != Database.Models.TaskStatus.Successful && t.Status != Database.Models.TaskStatus.PartiallySuccessful).Select((t) => new MissionTask(t, Database.Models.TaskStatus.NotStarted)).ToList();
Expand Down
4 changes: 2 additions & 2 deletions backend/api/EventHandlers/MissionEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private async void OnLocalizationMissionSuccessful(object? sender, LocalizationM
return;
}

var lastMissionRun = await MissionService.ReadLastExecutedMissionRunByRobotWithoutTracking(robot.Id);
var lastMissionRun = await MissionService.ReadLastExecutedMissionRunByRobot(robot.Id, readOnly: true);
if (lastMissionRun != null)
{
if (lastMissionRun.MissionRunType == MissionRunType.Emergency & lastMissionRun.Status == MissionStatus.Successful)
Expand Down Expand Up @@ -287,7 +287,7 @@ private async void OnReleaseRobotFromSafezoneTriggered(object? sender, RobotEmer
RobotId = robot.Id,
OrderBy = "DesiredStartTime",
PageSize = 100
});
}, readOnly: true);

var localizationMission = missionRuns.Find(missionRun => missionRun.IsLocalizationMission());

Expand Down
6 changes: 3 additions & 3 deletions backend/api/EventHandlers/MqttEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ private async void OnIsarMissionUpdate(object? sender, MqttReceivedArgs mqttArgs
return;
}

var flotillaMissionRun = await MissionRunService.ReadByIsarMissionId(isarMission.MissionId);
var flotillaMissionRun = await MissionRunService.ReadByIsarMissionId(isarMission.MissionId, readOnly: true);
if (flotillaMissionRun is null)
{
string errorMessage = $"Mission with isar mission Id {isarMission.IsarId} was not found";
Expand Down Expand Up @@ -380,7 +380,7 @@ private async void OnIsarTaskUpdate(object? sender, MqttReceivedArgs mqttArgs)
try { await MissionTaskService.UpdateMissionTaskStatus(task.TaskId, status); }
catch (MissionTaskNotFoundException) { return; }

var missionRun = await MissionRunService.ReadByIsarMissionId(task.MissionId);
var missionRun = await MissionRunService.ReadByIsarMissionId(task.MissionId, readOnly: true);
if (missionRun is null)
{
_logger.LogWarning("Mission run with ID {Id} was not found", task.MissionId);
Expand Down Expand Up @@ -411,7 +411,7 @@ private async void OnIsarStepUpdate(object? sender, MqttReceivedArgs mqttArgs)
try { await InspectionService.UpdateInspectionStatus(step.StepId, status); }
catch (InspectionNotFoundException) { return; }

var missionRun = await MissionRunService.ReadByIsarMissionId(step.MissionId);
var missionRun = await MissionRunService.ReadByIsarMissionId(step.MissionId, readOnly: true);
if (missionRun is null) _logger.LogWarning("Mission run with ID {Id} was not found", step.MissionId);

_ = SignalRService.SendMessageAsync("Mission run updated", missionRun?.Area?.Installation, missionRun != null ? new MissionRunResponse(missionRun) : null);
Expand Down
4 changes: 2 additions & 2 deletions backend/api/Services/ActionServices/TaskDurationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public async Task UpdateAverageDurationPerTask(RobotType robotType)
MinDesiredStartTime = minEpochTime,
RobotModelType = robotType,
PageSize = QueryStringParameters.MaxPageSize
}
);
},
readOnly: true);

var model = await robotModelService.ReadByRobotType(robotType);
if (model is null)
Expand Down
2 changes: 1 addition & 1 deletion backend/api/Services/MissionDefinitionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public async Task<List<MissionDefinition>> ReadByDeckId(string deckId)

public async Task<MissionDefinition> UpdateLastSuccessfulMissionRun(string missionRunId, string missionDefinitionId)
{
var missionRun = await missionRunService.ReadById(missionRunId);
var missionRun = await missionRunService.ReadById(missionRunId, readOnly: true);
if (missionRun is null)
{
string errorMessage = $"Mission run {missionRunId} was not found";
Expand Down
97 changes: 41 additions & 56 deletions backend/api/Services/MissionRunService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,25 @@ public interface IMissionRunService
{
public Task<MissionRun> Create(MissionRun missionRun, bool triggerCreatedMissionRunEvent = true);

public Task<PagedList<MissionRun>> ReadAll(MissionRunQueryStringParameters parameters);
public Task<PagedList<MissionRun>> ReadAll(MissionRunQueryStringParameters parameters, bool readOnly = false);

public Task<MissionRun?> ReadById(string id);
public Task<MissionRun?> ReadById(string id, bool readOnly = false);

public Task<MissionRun?> ReadByIdAsReadOnly(string id);
public Task<MissionRun?> ReadByIsarMissionId(string isarMissionId, bool readOnly = false);

public Task<MissionRun?> ReadByIsarMissionId(string isarMissionId);
public Task<IList<MissionRun>> ReadMissionRunQueue(string robotId, bool readOnly = false);

public Task<IList<MissionRun>> ReadMissionRunQueue(string robotId);
public Task<MissionRun?> ReadNextScheduledRunByMissionId(string missionId, bool readOnly = false);

public Task<MissionRun?> ReadNextScheduledRunByMissionId(string missionId);
public Task<MissionRun?> ReadNextScheduledMissionRun(string robotId, bool readOnly = false);

public Task<MissionRun?> ReadNextScheduledMissionRun(string robotId);
public Task<MissionRun?> ReadNextScheduledEmergencyMissionRun(string robotId, bool readOnly = false);

public Task<MissionRun?> ReadNextScheduledEmergencyMissionRun(string robotId);
public Task<MissionRun?> ReadNextScheduledLocalizationMissionRun(string robotId, bool readOnly = false);

public Task<MissionRun?> ReadNextScheduledLocalizationMissionRun(string robotId);
public Task<IList<MissionRun>> ReadMissionRuns(string robotId, MissionRunType? missionRunType, IList<MissionStatus>? filterStatuses = null, bool readOnly = false);

public Task<IList<MissionRun>> ReadMissionRuns(string robotId, MissionRunType? missionRunType, IList<MissionStatus>? filterStatuses = null);

public Task<MissionRun?> ReadLastExecutedMissionRunByRobotWithoutTracking(string robotId);
public Task<MissionRun?> ReadLastExecutedMissionRunByRobot(string robotId, bool readOnly = false);

public Task<bool> PendingLocalizationMissionRunExists(string robotId);

Expand Down Expand Up @@ -109,9 +107,9 @@ public async Task<MissionRun> Create(MissionRun missionRun, bool triggerCreatedM
return missionRun;
}

public async Task<PagedList<MissionRun>> ReadAll(MissionRunQueryStringParameters parameters)
public async Task<PagedList<MissionRun>> ReadAll(MissionRunQueryStringParameters parameters, bool readOnly = false)
{
var query = GetMissionRunsWithSubModels();
var query = GetMissionRunsWithSubModels(readOnly: readOnly);
var filter = ConstructFilter(parameters);

query = query.Where(filter);
Expand All @@ -129,51 +127,43 @@ public async Task<PagedList<MissionRun>> ReadAll(MissionRunQueryStringParameters
);
}

public async Task<MissionRun?> ReadById(string id)
{
return await GetMissionRunsWithSubModels()
.FirstOrDefaultAsync(missionRun => missionRun.Id.Equals(id));
}

public async Task<MissionRun?> ReadByIdAsReadOnly(string id)
public async Task<MissionRun?> ReadById(string id, bool readOnly = false)
{
return await GetMissionRunsWithSubModels().AsNoTracking()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.FirstOrDefaultAsync(missionRun => missionRun.Id.Equals(id));
}

public async Task<IList<MissionRun>> ReadMissionRunQueue(string robotId)
public async Task<IList<MissionRun>> ReadMissionRunQueue(string robotId, bool readOnly = false)
{
return await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.Where(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Pending)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.ToListAsync();
}

public async Task<MissionRun?> ReadNextScheduledMissionRun(string robotId)
public async Task<MissionRun?> ReadNextScheduledMissionRun(string robotId, bool readOnly = false)
{
return await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.FirstOrDefaultAsync(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Pending);
}

public async Task<MissionRun?> ReadNextScheduledEmergencyMissionRun(string robotId)
public async Task<MissionRun?> ReadNextScheduledEmergencyMissionRun(string robotId, bool readOnly = false)
{
return await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.FirstOrDefaultAsync(missionRun =>
missionRun.Robot.Id == robotId && missionRun.MissionRunType == MissionRunType.Emergency && missionRun.Status == MissionStatus.Pending);
}

public async Task<MissionRun?> ReadNextScheduledLocalizationMissionRun(string robotId)
public async Task<MissionRun?> ReadNextScheduledLocalizationMissionRun(string robotId, bool readOnly = false)
{
var nextScheduledMissionRun = await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.FirstOrDefaultAsync(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Pending && missionRun.MissionRunType == MissionRunType.Localization);

return nextScheduledMissionRun;
}

public async Task<IList<MissionRun>> ReadMissionRuns(string robotId, MissionRunType? missionRunType, IList<MissionStatus>? filterStatuses = null)
public async Task<IList<MissionRun>> ReadMissionRuns(string robotId, MissionRunType? missionRunType, IList<MissionStatus>? filterStatuses = null, bool readOnly = false)
{
var missionFilter = ConstructFilter(new MissionRunQueryStringParameters
{
Expand All @@ -183,25 +173,23 @@ public async Task<IList<MissionRun>> ReadMissionRuns(string robotId, MissionRunT
PageSize = 100
});

var missionRuns = await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.Where(missionFilter)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.ToListAsync();

return missionRuns;
}

public async Task<MissionRun?> ReadNextScheduledRunByMissionId(string missionId)
public async Task<MissionRun?> ReadNextScheduledRunByMissionId(string missionId, bool readOnly = false)
{
return await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.Where(m => m.MissionId == missionId && m.EndTime == null)
.OrderBy(m => m.DesiredStartTime)
.FirstOrDefaultAsync();
}

public async Task<MissionRun?> ReadLastExecutedMissionRunByRobotWithoutTracking(string robotId)
public async Task<MissionRun?> ReadLastExecutedMissionRunByRobot(string robotId, bool readOnly = false)
{
return await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.Where(m => m.Robot.Id == robotId)
.Where(m => m.EndTime != null)
.OrderByDescending(m => m.EndTime)
Expand All @@ -211,17 +199,13 @@ public async Task<IList<MissionRun>> ReadMissionRuns(string robotId, MissionRunT

public async Task<bool> PendingLocalizationMissionRunExists(string robotId)
{
var pendingMissionRuns = await ReadMissionRunQueue(robotId);
foreach (var pendingMissionRun in pendingMissionRuns)
{
if (pendingMissionRun.IsLocalizationMission()) { return true; }
}
return false;
var pendingMissionRuns = await ReadMissionRunQueue(robotId, readOnly: true);
return pendingMissionRuns.Any((m) => m.IsLocalizationMission());
}

public async Task<bool> OngoingLocalizationMissionRunExists(string robotId)
{
var ongoingMissionRuns = await GetMissionRunsWithSubModels()
var ongoingMissionRuns = await GetMissionRunsWithSubModels(readOnly: true)
.Where(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Ongoing)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.ToListAsync();
Expand All @@ -234,12 +218,12 @@ public async Task<bool> OngoingLocalizationMissionRunExists(string robotId)

public async Task<bool> PendingOrOngoingLocalizationMissionRunExists(string robotId)
{
var pendingMissionRuns = await ReadMissionRunQueue(robotId);
var pendingMissionRuns = await ReadMissionRunQueue(robotId, readOnly: true);
foreach (var pendingMissionRun in pendingMissionRuns)
{
if (pendingMissionRun.IsLocalizationMission()) { return true; }
}
var ongoingMissionRuns = await GetMissionRunsWithSubModels()
var ongoingMissionRuns = await GetMissionRunsWithSubModels(readOnly: true)
.Where(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Ongoing)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.ToListAsync();
Expand All @@ -252,12 +236,12 @@ public async Task<bool> PendingOrOngoingLocalizationMissionRunExists(string robo

public async Task<bool> PendingOrOngoingReturnToHomeMissionRunExists(string robotId)
{
var pendingMissionRuns = await ReadMissionRunQueue(robotId);
var pendingMissionRuns = await ReadMissionRunQueue(robotId, readOnly: true);
foreach (var pendingMissionRun in pendingMissionRuns)
{
if (pendingMissionRun.IsReturnHomeMission()) { return true; }
}
var ongoingMissionRuns = await GetMissionRunsWithSubModels()
var ongoingMissionRuns = await GetMissionRunsWithSubModels(readOnly: true)
.Where(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Ongoing)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.ToListAsync();
Expand Down Expand Up @@ -320,10 +304,10 @@ public async Task<bool> OngoingMission(string robotId)
return ongoingMissions.Any();
}

private IQueryable<MissionRun> GetMissionRunsWithSubModels()
private IQueryable<MissionRun> GetMissionRunsWithSubModels(bool readOnly = false)
{
var accessibleInstallationCodes = accessRoleService.GetAllowedInstallationCodes();
return context.MissionRuns
var query = context.MissionRuns
.Include(missionRun => missionRun.Area)
.ThenInclude(area => area != null ? area.Deck : null)
.ThenInclude(deck => deck != null ? deck.Plant : null)
Expand All @@ -345,7 +329,8 @@ private IQueryable<MissionRun> GetMissionRunsWithSubModels()
.ThenInclude(task => task.Inspections)
.ThenInclude(inspections => inspections.InspectionFindings)
.Where((m) => m.Area == null || accessibleInstallationCodes.Result.Contains(m.Area.Installation.InstallationCode.ToUpper()))
.Where((m) => m.IsDeprecated == false); ;
.Where((m) => m.IsDeprecated == false);
return readOnly ? query.AsNoTracking() : query;
}

protected virtual void OnMissionRunCreated(MissionRunCreatedEventArgs e)
Expand Down Expand Up @@ -547,9 +532,9 @@ MissionRunQueryStringParameters parameters

#region ISAR Specific methods

public async Task<MissionRun?> ReadByIsarMissionId(string isarMissionId)
public async Task<MissionRun?> ReadByIsarMissionId(string isarMissionId, bool readOnly = false)
{
return await GetMissionRunsWithSubModels()
return await GetMissionRunsWithSubModels(readOnly: readOnly)
.FirstOrDefaultAsync(
missionRun =>
missionRun.IsarMissionId != null && missionRun.IsarMissionId.Equals(isarMissionId)
Expand Down
Loading

0 comments on commit 7822f8c

Please sign in to comment.