feat: integrate notifications with signals
Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
@@ -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,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user