feat: integrate notifications with signals

Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
Heikki Hellgren
2024-01-25 09:07:16 +02:00
parent 1a38100a8e
commit 6a79f9f1ee
17 changed files with 98 additions and 36 deletions
+3 -1
View File
@@ -4,7 +4,8 @@ Welcome to the notifications backend plugin!
## Getting started
First you have to install the `@backstage/plugin-notifications-node` package.
First you have to install `@backstage/plugin-notifications-node` and `@backstage/plugin-signals-node`
packages.
Then create a new file to `packages/backend/src/plugins/notifications.ts`:
@@ -22,6 +23,7 @@ export default async function createPlugin(
tokenManager: env.tokenManager,
database: env.database,
discovery: env.discovery,
signalService: env.signalService
});
}
```
+5 -2
View File
@@ -5,12 +5,13 @@
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
import { CatalogApi } from '@backstage/catalog-client';
import { DiscoveryApi } from '@backstage/core-plugin-api';
import { DiscoveryService } from '@backstage/backend-plugin-api';
import express from 'express';
import { IdentityApi } from '@backstage/plugin-auth-node';
import { LoggerService } from '@backstage/backend-plugin-api';
import { Notification as Notification_2 } from '@backstage/plugin-notifications-common';
import { PluginDatabaseManager } from '@backstage/backend-common';
import { SignalService } from '@backstage/plugin-signals-node';
import { TokenManager } from '@backstage/backend-common';
// @public (undocumented)
@@ -32,7 +33,7 @@ export interface RouterOptions {
// (undocumented)
database: PluginDatabaseManager;
// (undocumented)
discovery: DiscoveryApi;
discovery: DiscoveryService;
// (undocumented)
identity: IdentityApi;
// (undocumented)
@@ -40,6 +41,8 @@ export interface RouterOptions {
// (undocumented)
processors?: NotificationProcessor[];
// (undocumented)
signalService?: SignalService;
// (undocumented)
tokenManager: TokenManager;
}
+2 -1
View File
@@ -27,11 +27,12 @@
"@backstage/catalog-client": "workspace:^",
"@backstage/catalog-model": "workspace:^",
"@backstage/config": "workspace:^",
"@backstage/core-plugin-api": "workspace:^",
"@backstage/errors": "workspace:^",
"@backstage/plugin-auth-node": "workspace:^",
"@backstage/plugin-events-node": "workspace:^",
"@backstage/plugin-notifications-common": "workspace:^",
"@backstage/plugin-notifications-node": "workspace:^",
"@backstage/plugin-signals-node": "workspace:^",
"@types/express": "*",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
@@ -18,6 +18,7 @@ import {
createBackendPlugin,
} from '@backstage/backend-plugin-api';
import { createRouter } from './service/router';
import { signalService } from '@backstage/plugin-signals-node';
/**
* Notifications backend plugin
@@ -35,6 +36,7 @@ export const notificationsPlugin = createBackendPlugin({
database: coreServices.database,
tokenManager: coreServices.tokenManager,
discovery: coreServices.discovery,
signals: signalService,
},
async init({
httpRouter,
@@ -43,6 +45,7 @@ export const notificationsPlugin = createBackendPlugin({
database,
tokenManager,
discovery,
signals,
}) {
httpRouter.use(
await createRouter({
@@ -51,6 +54,7 @@ export const notificationsPlugin = createBackendPlugin({
database,
tokenManager,
discovery,
signalService: signals,
}),
);
},
@@ -26,6 +26,7 @@ import request from 'supertest';
import { createRouter } from './router';
import { IdentityApi } from '@backstage/plugin-auth-node';
import { ConfigReader } from '@backstage/config';
import { SignalService } from '@backstage/plugin-signals-node';
function createDatabase(): PluginDatabaseManager {
return DatabaseManager.fromConfig(
@@ -65,6 +66,10 @@ describe('createRouter', () => {
getExternalBaseUrl: jest.fn(),
};
const signalService: jest.Mocked<SignalService> = {
publish: jest.fn(),
};
beforeAll(async () => {
const router = await createRouter({
logger: getVoidLogger(),
@@ -72,6 +77,7 @@ describe('createRouter', () => {
database: createDatabase(),
tokenManager: mockedTokenManager,
discovery,
signalService,
});
app = express().use(router);
});
@@ -39,8 +39,8 @@ import {
} from '@backstage/catalog-model';
import { NotificationProcessor } from '../types';
import { AuthenticationError } from '@backstage/errors';
import { DiscoveryApi } from '@backstage/core-plugin-api';
import { LoggerService } from '@backstage/backend-plugin-api';
import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';
import { SignalService } from '@backstage/plugin-signals-node';
/** @public */
export interface RouterOptions {
@@ -48,7 +48,8 @@ export interface RouterOptions {
identity: IdentityApi;
database: PluginDatabaseManager;
tokenManager: TokenManager;
discovery: DiscoveryApi;
discovery: DiscoveryService;
signalService?: SignalService;
catalog?: CatalogApi;
processors?: NotificationProcessor[];
}
@@ -65,6 +66,7 @@ export async function createRouter(
catalog,
tokenManager,
processors,
signalService,
} = options;
const catalogClient =
@@ -248,7 +250,14 @@ export async function createRouter(
}
}
notifications.push(notification);
// TODO: Signal service
}
if (signalService) {
await signalService.publish({
recipients: users,
message: { action: 'refresh' },
channel: 'notifications',
});
}
res.send(notifications);
@@ -31,6 +31,12 @@ import {
CatalogRequestOptions,
GetEntitiesByRefsRequest,
} from '@backstage/catalog-client';
import { DefaultSignalService } from '@backstage/plugin-signals-node';
import {
EventBroker,
EventParams,
EventSubscriber,
} from '@backstage/plugin-events-node';
export interface ServerOptions {
port: number;
@@ -90,6 +96,20 @@ export async function startStandaloneServer(
},
};
const mockSubscribers: EventSubscriber[] = [];
const eventBroker: EventBroker = {
async publish(params: EventParams): Promise<void> {
mockSubscribers.forEach(sub => sub.onEvent(params));
},
subscribe(...subscribers: EventSubscriber[]) {
subscribers.flat().forEach(subscriber => {
mockSubscribers.push(subscriber);
});
},
};
const signalService = DefaultSignalService.create({ eventBroker });
const router = await createRouter({
logger,
identity: identityMock,
@@ -97,6 +117,7 @@ export async function startStandaloneServer(
catalog: catalogApi,
discovery,
tokenManager,
signalService,
});
let service = createServiceBuilder(module)