Skip to content

Commit b40b72d

Browse files
authored
MMI-3212 Fix Scheduler Service Issue (bcgov#2426)
1 parent bb8f68d commit b40b72d

File tree

7 files changed

+92
-20
lines changed

7 files changed

+92
-20
lines changed

api/net/Areas/Services/Controllers/EventScheduleController.cs

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
using Swashbuckle.AspNetCore.Annotations;
77
using TNO.API.Areas.Services.Models.EventSchedule;
88
using TNO.API.Models;
9+
using TNO.API.Models.SignalR;
910
using TNO.Core.Exceptions;
1011
using TNO.DAL.Services;
12+
using TNO.Kafka;
13+
using TNO.Kafka.SignalR;
1114
using TNO.Keycloak;
1215

1316
namespace TNO.API.Areas.Services.Controllers;
@@ -28,19 +31,31 @@ namespace TNO.API.Areas.Services.Controllers;
2831
public class EventScheduleController : ControllerBase
2932
{
3033
#region Variables
31-
private readonly IEventScheduleService _serviceEventSchedule;
34+
private readonly IKafkaMessenger _kafkaMessenger;
35+
private readonly KafkaHubConfig _kafkaHubOptions;
36+
private readonly IUserService _userService;
37+
private readonly IReportService _reportService;
38+
private readonly IEventScheduleService _eventScheduleService;
3239
private readonly JsonSerializerOptions _serializerOptions;
3340
#endregion
3441

3542
#region Constructors
3643
/// <summary>
3744
/// Creates a new instance of a EventScheduleController object, initializes with specified parameters.
3845
/// </summary>
39-
/// <param name="serviceEventSchedule"></param>
46+
/// <param name="kafkaMessenger"></param>
47+
/// <param name="kafkaConfig"></param>
48+
/// <param name="userService"></param>
49+
/// <param name="reportService"></param>
50+
/// <param name="eventScheduleService"></param>
4051
/// <param name="serializerOptions"></param>
41-
public EventScheduleController(IEventScheduleService serviceEventSchedule, IOptions<JsonSerializerOptions> serializerOptions)
52+
public EventScheduleController(IKafkaMessenger kafkaMessenger, IOptions<KafkaHubConfig> kafkaConfig, IUserService userService, IReportService reportService, IEventScheduleService eventScheduleService, IOptions<JsonSerializerOptions> serializerOptions)
4253
{
43-
_serviceEventSchedule = serviceEventSchedule;
54+
_kafkaMessenger = kafkaMessenger;
55+
_kafkaHubOptions = kafkaConfig.Value;
56+
_userService = userService;
57+
_reportService = reportService;
58+
_eventScheduleService = eventScheduleService;
4459
_serializerOptions = serializerOptions.Value;
4560
}
4661
#endregion
@@ -56,7 +71,7 @@ public EventScheduleController(IEventScheduleService serviceEventSchedule, IOpti
5671
[SwaggerOperation(Tags = new[] { "EventSchedule" })]
5772
public IActionResult GetEventSchedules()
5873
{
59-
var result = _serviceEventSchedule.FindAll();
74+
var result = _eventScheduleService.FindAll();
6075
return new JsonResult(result.Select(ds => new EventScheduleModel(ds, _serializerOptions)));
6176
}
6277

@@ -72,7 +87,7 @@ public IActionResult GetEventSchedules()
7287
[SwaggerOperation(Tags = new[] { "EventSchedule" })]
7388
public IActionResult FindById(int id)
7489
{
75-
var result = _serviceEventSchedule.FindById(id);
90+
var result = _eventScheduleService.FindById(id);
7691
if (result == null) return NoContent();
7792
return new JsonResult(new EventScheduleModel(result, _serializerOptions));
7893
}
@@ -88,11 +103,32 @@ public IActionResult FindById(int id)
88103
[ProducesResponseType(typeof(ErrorResponseModel), (int)HttpStatusCode.BadRequest)]
89104
[ProducesResponseType((int)HttpStatusCode.NoContent)]
90105
[SwaggerOperation(Tags = new[] { "EventSchedule" })]
91-
public IActionResult Update([FromBody] EventScheduleModel model)
106+
public async Task<IActionResult> UpdateAsync([FromBody] EventScheduleModel model)
92107
{
93-
_serviceEventSchedule.UpdateAndSave(model.ToEntity(_serializerOptions));
108+
_eventScheduleService.UpdateAndSave(model.ToEntity(_serializerOptions));
94109

95-
var result = _serviceEventSchedule.FindById(model.Id) ?? throw new NoContentException();
110+
var result = _eventScheduleService.FindById(model.Id) ?? throw new NoContentException();
111+
if (result.ReportId.HasValue)
112+
{
113+
var report = _reportService.FindById(result.ReportId.Value);
114+
if (report?.OwnerId.HasValue == true)
115+
{
116+
var instance = _reportService.GetCurrentReportInstance(report.Id, report.OwnerId);
117+
var user = _userService.FindById(report.OwnerId.Value) ?? throw new NotAuthorizedException();
118+
await _kafkaMessenger.SendMessageAsync(
119+
_kafkaHubOptions.HubTopic,
120+
new KafkaHubMessage(HubEvent.SendUser, user.Username, new KafkaInvocationMessage(MessageTarget.ReportStatus, new[] { new ReportMessageModel()
121+
{
122+
Id = instance?.Id ?? 0,
123+
ReportId = report.Id,
124+
Status = instance?.Status ?? Entities.ReportStatus.Pending,
125+
Subject = instance?.Subject ?? report.Name,
126+
OwnerId = user.Id,
127+
Message = "event",
128+
} }))
129+
);
130+
}
131+
}
96132
return new JsonResult(new EventScheduleModel(result, _serializerOptions));
97133
}
98134
#endregion

app/subscriber/src/components/layout/DefaultLayout.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,14 @@ export const DefaultLayout: React.FC<ILayoutProps> = ({ children, ...rest }) =>
6868
hub.useHubEffect(MessageTargetKey.ReportStatus, async (message: IReportMessageModel) => {
6969
// Report has been updated, go fetch latest.
7070
try {
71-
if (message.status === ReportStatusName.Accepted)
72-
toast.info(`Report "${message.subject}" has been generated and email requested.`);
73-
else if (message.status === ReportStatusName.Completed)
74-
toast.info(`Report "${message.subject}" has been sent out by email.`);
75-
else if (message.status === ReportStatusName.Failed)
76-
toast.error(`Report "${message.subject}" failed to be sent out by email.`);
71+
if (message.message === 'status') {
72+
if (message.status === ReportStatusName.Accepted)
73+
toast.info(`Report "${message.subject}" has been generated and email requested.`);
74+
else if (message.status === ReportStatusName.Completed)
75+
toast.info(`Report "${message.subject}" has been sent out by email.`);
76+
else if (message.status === ReportStatusName.Failed)
77+
toast.error(`Report "${message.subject}" failed to be sent out by email.`);
78+
}
7779
} catch {}
7880
});
7981

app/subscriber/src/features/my-reports/MyReports.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { ReportPreview } from './ReportPreview';
2222
import * as styled from './styled';
2323

2424
export const MyReports: React.FC = () => {
25-
const [{ myReports, reportsFilter }, { findMyReports, deleteReport }] = useReports();
25+
const [{ myReports, reportsFilter }, { findMyReports, deleteReport, getReport }] = useReports();
2626
const [{ getReportInstance }] = useReportInstances();
2727
const { toggle, isShowing } = useModal();
2828
const navigate = useNavigate();
@@ -53,6 +53,14 @@ export const MyReports: React.FC = () => {
5353
i.id === message.id ? { ...i, status: message.status, version: message.version } : i,
5454
),
5555
});
56+
} else if (message.message === 'event') {
57+
const updateReport = await getReport(report.id, false);
58+
if (updateReport) {
59+
setReport({
60+
...report,
61+
events: updateReport.events,
62+
});
63+
}
5664
} else {
5765
const instance = await getReportInstance(message.id, false);
5866
if (instance) {

app/subscriber/src/features/my-reports/edit/ReportEditPage.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@ export const ReportEditPage = () => {
168168
i.id === message.id ? { ...i, status: message.status, version: message.version } : i,
169169
),
170170
});
171+
} else if (message.message === 'event') {
172+
const updateReport = await getReport(report.id, false);
173+
if (updateReport) {
174+
setReport({
175+
...report,
176+
events: updateReport.events,
177+
});
178+
}
171179
} else {
172180
const instance = await getReportInstance(message.id, true);
173181
if (instance) {

app/subscriber/src/store/hooks/subscriber/useReportSync.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { useProfileStore } from 'store/slices';
33
import { IReportMessageModel, MessageTargetKey, useApiSubscriberReportInstances } from 'tno-core';
44

55
import { useApiHub } from '../signalr';
6+
import { useReports } from './useReports';
67

78
/**
89
* Hook provides a singleton way to ensure my reports are synced across tabs.
910
*/
1011
export const useReportSync = () => {
1112
const { getReportInstance } = useApiSubscriberReportInstances();
13+
const [, { getReport }] = useReports();
1214
const hub = useApiHub();
1315
const [{ myReports }, { storeMyReports }] = useProfileStore();
1416

@@ -38,6 +40,21 @@ export const useReportSync = () => {
3840
);
3941
return results;
4042
});
43+
} else if (message.message === 'event') {
44+
const updateReport = await getReport(report.id, false);
45+
if (updateReport) {
46+
storeMyReports((reports) => {
47+
const results = reports.map((r) =>
48+
r.id === report.id
49+
? {
50+
...report,
51+
events: updateReport.events,
52+
}
53+
: r,
54+
);
55+
return results;
56+
});
57+
}
4158
} else {
4259
const response = await getReportInstance(message.id, true);
4360
if (response.status === 200 && response.data) {
@@ -67,7 +84,7 @@ export const useReportSync = () => {
6784
}
6885
} catch {}
6986
},
70-
[getReportInstance, myReports, storeMyReports],
87+
[getReportInstance, myReports, storeMyReports, getReport],
7188
);
7289

7390
hub.useHubEffect(MessageTargetKey.ReportStatus, handleUpdateReportInstance);

libs/net/dal/Services/ContentService.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ public override Content AddAndSave(Content entity)
297297
private Dictionary<string, object> GetChangedProperties(Microsoft.EntityFrameworkCore.ChangeTracking.PropertyValues currentValues,
298298
Microsoft.EntityFrameworkCore.ChangeTracking.PropertyValues? databaseValues)
299299
{
300-
// Fields to ignore: system fields
300+
// Fields to ignore: system fields
301301
var ignoreFields = new HashSet<string> {
302302
nameof(Content.Versions),
303303
nameof(Content.UpdatedBy),
@@ -402,8 +402,8 @@ public override Content UpdateAndSave(Content entity)
402402
var contentConflictEx = new ContentConflictException($"FIELDS:{changedFields}");
403403
throw new DbUpdateConcurrencyException(contentConflictEx.Message, contentConflictEx);
404404
}
405-
406-
throw ex;
405+
406+
throw;
407407
}
408408
}
409409

libs/net/reports/TNO.Reports.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
<ItemGroup>
1717
<PackageReference Include="NPOI" Version="2.7.2" />
18+
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
1819
</ItemGroup>
1920

2021
</Project>

0 commit comments

Comments
 (0)