Skip to content

Commit 838259e

Browse files
committed
Merge branch 'main' into fix/#3881-validate-user-account
2 parents 62bb0ef + 6002f6e commit 838259e

File tree

14 files changed

+329
-89
lines changed

14 files changed

+329
-89
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Inject, LoggerService, Module, OnModuleInit } from "@nestjs/common";
2+
import { ModuleRef } from "@nestjs/core";
3+
import { BULL_BOARD_INSTANCE, BullBoardInstance } from "@bull-board/nestjs";
4+
import { QueueService } from "@sims/services/queue/queue.service";
5+
import { InjectLogger } from "@sims/utilities/logger";
6+
import { getQueueToken } from "@nestjs/bull";
7+
import { Queue } from "bull";
8+
import { BullAdapter } from "@bull-board/api/bullAdapter";
9+
10+
@Module({})
11+
export class BullBoardQueuesRegistrationModule implements OnModuleInit {
12+
constructor(
13+
private readonly moduleRef: ModuleRef,
14+
private readonly queueService: QueueService,
15+
@Inject(BULL_BOARD_INSTANCE)
16+
private readonly board: BullBoardInstance,
17+
) {}
18+
19+
/**
20+
* Adds all queues to the bull board during application initialization
21+
* checking if the queue is active and if it is a scheduler.
22+
*/
23+
async onModuleInit(): Promise<void> {
24+
const queues = await this.queueService.queueConfigurationModel();
25+
queues.forEach((queue) => {
26+
if (!queue.isActive && queue.isScheduler) {
27+
this.logger.log(`Queue service '${queue.name}' is inactive.`);
28+
return;
29+
}
30+
const queueProvider = this.moduleRef.get<Queue>(
31+
getQueueToken(queue.name),
32+
{
33+
strict: false,
34+
},
35+
);
36+
const queueAdapter = new BullAdapter(queueProvider, {
37+
readOnlyMode: queue.dashboardReadonly,
38+
});
39+
this.board.addQueue(queueAdapter);
40+
});
41+
}
42+
43+
@InjectLogger()
44+
logger: LoggerService;
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Module } from "@nestjs/common";
2+
import { BullBoardModule, BullBoardModuleOptions } from "@bull-board/nestjs";
3+
import { ConfigModule, ConfigService } from "@sims/utilities/config";
4+
import * as basicAuth from "express-basic-auth";
5+
import { ExpressAdapter } from "@bull-board/express";
6+
import { BULL_BOARD_ROUTE } from "../constants";
7+
import { BullBoardQueuesRegistrationModule } from "./bull-board-queues-registration.module";
8+
9+
/**
10+
* Bull board related modules to allow the dashboard to be registered.
11+
*/
12+
@Module({
13+
imports: [
14+
BullBoardModule.forRootAsync({
15+
imports: [ConfigModule],
16+
useFactory: bullBoardModuleFactory,
17+
inject: [ConfigService],
18+
}),
19+
BullBoardQueuesRegistrationModule,
20+
],
21+
exports: [BullBoardModule, BullBoardQueuesRegistrationModule],
22+
})
23+
export class BullBoardQueuesModule {}
24+
25+
/**
26+
* Builds the Bull Board module options to register the dashboard in a dynamic way.
27+
* @param configService service with the configuration of the application.
28+
* @returns Bull Board module options with the dashboard route,
29+
* authentication middleware and the board options.
30+
*/
31+
async function bullBoardModuleFactory(
32+
configService: ConfigService,
33+
): Promise<BullBoardModuleOptions> {
34+
const queueDashboardUsers = {};
35+
queueDashboardUsers[configService.queueDashboardCredential.userName] =
36+
configService.queueDashboardCredential.password;
37+
const authMiddleware = basicAuth({
38+
users: queueDashboardUsers,
39+
challenge: true,
40+
});
41+
return {
42+
route: BULL_BOARD_ROUTE,
43+
adapter: ExpressAdapter,
44+
middleware: authMiddleware,
45+
boardOptions: {
46+
uiConfig: {
47+
boardTitle: "SIMS-Queues",
48+
boardLogo: {
49+
path: "https://sims.studentaidbc.ca/favicon-32x32.png",
50+
},
51+
favIcon: {
52+
default: "https://sims.studentaidbc.ca/favicon-16x16.png",
53+
alternative: "https://sims.studentaidbc.ca/favicon-32x32.png",
54+
},
55+
},
56+
},
57+
};
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./error-code.constants";
2+
export * from "./system-configurations.constants";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/**
2+
* Bull Dashboard route.
3+
*/
4+
export const BULL_BOARD_ROUTE = "admin/queues";
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import "../../../env-setup";
2-
import { QueueService } from "@sims/services/queue";
32
import { ConfigService } from "@sims/utilities/config";
4-
import { createBullBoard } from "@bull-board/api";
5-
import { BullAdapter } from "@bull-board/api/bullAdapter";
6-
import { ExpressAdapter } from "@bull-board/express";
73
import { NestFactory } from "@nestjs/core";
8-
import { Queue } from "bull";
94
import { QueueConsumersModule } from "./queue-consumers.module";
10-
import * as basicAuth from "express-basic-auth";
115
import { LoggerService } from "@sims/utilities/logger";
126
import { SystemUsersService } from "@sims/services";
137

@@ -23,40 +17,5 @@ import { SystemUsersService } from "@sims/services";
2317
const systemUsersService = app.get(SystemUsersService);
2418
await systemUsersService.loadSystemUser();
2519

26-
// Queue service.
27-
const queueService = app.get<QueueService>(QueueService);
28-
const queues = await queueService.queueConfigurationModel();
29-
// Create bull board UI dashboard for queue management.
30-
const serverAdapter = new ExpressAdapter();
31-
serverAdapter.setBasePath("/admin/queues");
32-
const bullBoardQueues: BullAdapter[] = [];
33-
queues.forEach((queue) => {
34-
if (!queue.isActive && queue.isScheduler) {
35-
logger.log(`Queue service "${queue.name}" is inactive.`);
36-
} else {
37-
bullBoardQueues.push(
38-
new BullAdapter(app.get<Queue>(`BullQueue_${queue.name}`), {
39-
readOnlyMode: queue.dashboardReadonly,
40-
}),
41-
);
42-
}
43-
});
44-
createBullBoard({
45-
queues: bullBoardQueues,
46-
serverAdapter,
47-
});
48-
// Bull board user for basic authentication.
49-
const queueDashboardUsers = {};
50-
queueDashboardUsers[config.queueDashboardCredential.userName] =
51-
config.queueDashboardCredential.password;
52-
app.use(
53-
"/admin/queues",
54-
basicAuth({
55-
users: queueDashboardUsers,
56-
challenge: true,
57-
}),
58-
serverAdapter.getRouter(),
59-
);
60-
6120
await app.listen(config.queueConsumersPort);
6221
})();

sources/packages/backend/apps/queue-consumers/src/queue-consumers.module.ts

+2
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,15 @@ import { CASSupplierIntegrationService } from "./services/cas-supplier/cas-suppl
7878
import { VirusScanProcessor } from "./processors/virus-scan/virus-scan.processor";
7979
import { CASService } from "@sims/integrations/cas/cas.service";
8080
import { ObjectStorageService } from "@sims/integrations/object-storage";
81+
import { BullBoardQueuesModule } from "./bull-board/bull-board-queues.module";
8182

8283
// TODO: Removed ATBCResponseIntegrationScheduler in providers, the queuename from enum and the decorators of the processor as part of #2539.
8384
@Module({
8485
imports: [
8586
GlobalHttpModule,
8687
DatabaseModule,
8788
QueueModule,
89+
BullBoardQueuesModule,
8890
ZeebeModule.forRoot(),
8991
IER12IntegrationModule,
9092
ECEIntegrationModule,

sources/packages/backend/apps/queue-consumers/test/helpers/testing-modules/testing-modules-helper.ts

+6
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { INestApplication } from "@nestjs/common";
22
import { Test, TestingModule } from "@nestjs/testing";
33
import { DataSource } from "typeorm";
44
import { QueueConsumersModule } from "../../../src/queue-consumers.module";
5+
import { BullBoardQueuesModule } from "../../../src/bull-board/bull-board-queues.module";
56
import { SshService } from "@sims/integrations/services";
67
import { overrideImportsMetadata } from "@sims/test-utils";
78
import {
89
QueueModuleMock,
910
createObjectStorageServiceMock,
1011
createSSHServiceMock,
1112
createZeebeModuleMock,
13+
BullBoardQueuesModuleMock,
1214
} from "@sims/test-utils/mocks";
1315
import * as Client from "ssh2-sftp-client";
1416
import { DeepMocked, createMock } from "@golevelup/ts-jest";
@@ -45,6 +47,10 @@ export async function createTestingAppModule(): Promise<CreateTestingModuleResul
4547
replace: QueueModule,
4648
by: QueueModuleMock,
4749
},
50+
{
51+
replace: BullBoardQueuesModule,
52+
by: BullBoardQueuesModuleMock,
53+
},
4854
{
4955
replace: ZeebeModule,
5056
by: createZeebeModuleMock(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Global, Module } from "@nestjs/common";
2+
3+
/**
4+
* Mock to entirely replace the Bull Board queues module
5+
* that are not part of the E2E tests.
6+
*/
7+
@Global()
8+
@Module({})
9+
export class BullBoardQueuesModuleMock {}

sources/packages/backend/libs/test-utils/src/mocks/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from "./ssh-service-mock";
22
export * from "./queue-module-mock";
33
export * from "./zeebe-client-mock";
44
export * from "./object-storage-service-mock";
5+
export * from "./bull-board-queues-module-mock";

sources/packages/backend/package-lock.json

+111-18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sources/packages/backend/package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@
4343
},
4444
"dependencies": {
4545
"@aws-sdk/client-s3": "^3.663.0",
46-
"@bull-board/api": "^5.15.1",
47-
"@bull-board/express": "^5.15.1",
48-
"@bull-board/ui": "^5.15.1",
46+
"@bull-board/api": "^6.5.2",
47+
"@bull-board/express": "^6.5.2",
48+
"@bull-board/nestjs": "^6.5.2",
49+
"@bull-board/ui": "^6.5.2",
4950
"@camunda8/sdk": "^8.6.13",
5051
"@golevelup/nestjs-discovery": "^4.0.0",
5152
"@nestjs/axios": "^3.0.2",

0 commit comments

Comments
 (0)