feat(events)!: migrate EventRouter implementations from EventBroker to EventsService
Signed-off-by: Patrick Jungermann <Patrick.Jungermann@gmail.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
---
|
||||
'@backstage/plugin-events-backend-module-bitbucket-cloud': minor
|
||||
'@backstage/plugin-events-backend-module-gerrit': minor
|
||||
'@backstage/plugin-events-backend-module-github': minor
|
||||
'@backstage/plugin-events-backend-module-gitlab': minor
|
||||
'@backstage/plugin-events-backend-module-azure': minor
|
||||
'@backstage/plugin-events-node': minor
|
||||
---
|
||||
|
||||
BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`.
|
||||
|
||||
`EventRouter` uses the new `EventsService` instead of the `EventBroker` now,
|
||||
causing a breaking change to its signature.
|
||||
|
||||
All of its extensions and implementations got adjusted accordingly.
|
||||
(`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`,
|
||||
`GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`)
|
||||
|
||||
Required adjustments were made to all backend modules for the new backend system,
|
||||
now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`.
|
||||
|
||||
**Migration:**
|
||||
|
||||
Example for implementations of `SubTopicEventRouter`:
|
||||
|
||||
```diff
|
||||
import {
|
||||
EventParams,
|
||||
+ EventsService,
|
||||
SubTopicEventRouter,
|
||||
} from '@backstage/plugin-events-node';
|
||||
|
||||
export class GithubEventRouter extends SubTopicEventRouter {
|
||||
- constructor() {
|
||||
- super('github');
|
||||
+ constructor(options: { events: EventsService }) {
|
||||
+ super({
|
||||
+ events: options.events,
|
||||
+ topic: 'github',
|
||||
+ });
|
||||
}
|
||||
|
||||
+ protected getSubscriberId(): string {
|
||||
+ return 'GithubEventRouter';
|
||||
+ }
|
||||
+
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Example for a direct extension of `EventRouter`:
|
||||
|
||||
```diff
|
||||
class MyEventRouter extends EventRouter {
|
||||
- constructor(/* ... */) {
|
||||
+ constructor(options: {
|
||||
+ events: EventsService;
|
||||
+ // ...
|
||||
+ }) {
|
||||
- super();
|
||||
// ...
|
||||
+ super({
|
||||
+ events: options.events,
|
||||
+ topics: topics,
|
||||
+ });
|
||||
}
|
||||
+
|
||||
+ protected getSubscriberId(): string {
|
||||
+ return 'MyEventRouter';
|
||||
+ }
|
||||
-
|
||||
- supportsEventTopics(): string[] {
|
||||
- return this.topics;
|
||||
- }
|
||||
}
|
||||
```
|
||||
@@ -4,12 +4,15 @@
|
||||
|
||||
```ts
|
||||
import { EventParams } from '@backstage/plugin-events-node';
|
||||
import { EventsService } from '@backstage/plugin-events-node';
|
||||
import { SubTopicEventRouter } from '@backstage/plugin-events-node';
|
||||
|
||||
// @public
|
||||
export class AzureDevOpsEventRouter extends SubTopicEventRouter {
|
||||
constructor();
|
||||
constructor(options: { events: EventsService });
|
||||
// (undocumented)
|
||||
protected determineSubTopic(params: EventParams): string | undefined;
|
||||
// (undocumented)
|
||||
protected getSubscriberId(): string;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/plugin-events-node": "workspace:^",
|
||||
"winston": "^3.2.1"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
|
||||
@@ -14,37 +14,44 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { AzureDevOpsEventRouter } from './AzureDevOpsEventRouter';
|
||||
|
||||
describe('AzureDevOpsEventRouter', () => {
|
||||
const eventRouter = new AzureDevOpsEventRouter();
|
||||
const events = new TestEventsService();
|
||||
const eventRouter = new AzureDevOpsEventRouter({ events: events });
|
||||
const topic = 'azureDevOps';
|
||||
const eventPayload = { eventType: 'test.type', test: 'payload' };
|
||||
const metadata = {};
|
||||
|
||||
it('no $.eventType', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
beforeEach(() => {
|
||||
events.reset();
|
||||
});
|
||||
|
||||
it('subscribed to topic', () => {
|
||||
eventRouter.subscribe();
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('AzureDevOpsEventRouter');
|
||||
expect(events.subscribed[0].topics).toEqual([topic]);
|
||||
});
|
||||
|
||||
it('no $.eventType', () => {
|
||||
eventRouter.onEvent({
|
||||
topic,
|
||||
eventPayload: { invalid: 'payload' },
|
||||
metadata,
|
||||
});
|
||||
|
||||
expect(eventBroker.published).toEqual([]);
|
||||
expect(events.published).toEqual([]);
|
||||
});
|
||||
|
||||
it('with $.eventType', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
eventRouter.onEvent({ topic, eventPayload, metadata });
|
||||
|
||||
expect(eventBroker.published.length).toBe(1);
|
||||
expect(eventBroker.published[0].topic).toEqual('azureDevOps.test.type');
|
||||
expect(eventBroker.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(eventBroker.published[0].metadata).toEqual(metadata);
|
||||
expect(events.published).toHaveLength(1);
|
||||
expect(events.published[0].topic).toEqual('azureDevOps.test.type');
|
||||
expect(events.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(events.published[0].metadata).toEqual(metadata);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import {
|
||||
EventParams,
|
||||
EventsService,
|
||||
SubTopicEventRouter,
|
||||
} from '@backstage/plugin-events-node';
|
||||
|
||||
@@ -27,8 +28,15 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export class AzureDevOpsEventRouter extends SubTopicEventRouter {
|
||||
constructor() {
|
||||
super('azureDevOps');
|
||||
constructor(options: { events: EventsService }) {
|
||||
super({
|
||||
events: options.events,
|
||||
topic: 'azureDevOps',
|
||||
});
|
||||
}
|
||||
|
||||
protected getSubscriberId(): string {
|
||||
return 'AzureDevOpsEventRouter';
|
||||
}
|
||||
|
||||
protected determineSubTopic(params: EventParams): string | undefined {
|
||||
|
||||
+15
-19
@@ -14,32 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { eventsModuleAzureDevOpsEventRouter } from './eventsModuleAzureDevOpsEventRouter';
|
||||
import { AzureDevOpsEventRouter } from '../router/AzureDevOpsEventRouter';
|
||||
|
||||
describe('eventsModuleAzureDevOpsEventRouter', () => {
|
||||
it('should be correctly wired and set up', async () => {
|
||||
let addedPublisher: AzureDevOpsEventRouter | undefined;
|
||||
let addedSubscriber: AzureDevOpsEventRouter | undefined;
|
||||
const extensionPoint = {
|
||||
addPublishers: (publisher: any) => {
|
||||
addedPublisher = publisher;
|
||||
const events = new TestEventsService();
|
||||
const eventsServiceFactory = createServiceFactory({
|
||||
service: eventsServiceRef,
|
||||
deps: {},
|
||||
async factory({}) {
|
||||
return events;
|
||||
},
|
||||
addSubscribers: (subscriber: any) => {
|
||||
addedSubscriber = subscriber;
|
||||
},
|
||||
};
|
||||
|
||||
await startTestBackend({
|
||||
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
|
||||
features: [eventsModuleAzureDevOpsEventRouter()],
|
||||
});
|
||||
|
||||
expect(addedPublisher).not.toBeUndefined();
|
||||
expect(addedPublisher).toBeInstanceOf(AzureDevOpsEventRouter);
|
||||
expect(addedSubscriber).not.toBeUndefined();
|
||||
expect(addedSubscriber).toBeInstanceOf(AzureDevOpsEventRouter);
|
||||
await startTestBackend({
|
||||
features: [eventsServiceFactory(), eventsModuleAzureDevOpsEventRouter()],
|
||||
});
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('AzureDevOpsEventRouter');
|
||||
});
|
||||
});
|
||||
|
||||
+6
-6
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { AzureDevOpsEventRouter } from '../router/AzureDevOpsEventRouter';
|
||||
|
||||
/**
|
||||
@@ -31,13 +31,13 @@ export const eventsModuleAzureDevOpsEventRouter = createBackendModule({
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
events: eventsExtensionPoint,
|
||||
events: eventsServiceRef,
|
||||
},
|
||||
async init({ events }) {
|
||||
const eventRouter = new AzureDevOpsEventRouter();
|
||||
|
||||
events.addPublishers(eventRouter);
|
||||
events.addSubscribers(eventRouter);
|
||||
const eventRouter = new AzureDevOpsEventRouter({
|
||||
events,
|
||||
});
|
||||
await eventRouter.subscribe();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
|
||||
```ts
|
||||
import { EventParams } from '@backstage/plugin-events-node';
|
||||
import { EventsService } from '@backstage/plugin-events-node';
|
||||
import { SubTopicEventRouter } from '@backstage/plugin-events-node';
|
||||
|
||||
// @public
|
||||
export class BitbucketCloudEventRouter extends SubTopicEventRouter {
|
||||
constructor();
|
||||
constructor(options: { events: EventsService });
|
||||
// (undocumented)
|
||||
protected determineSubTopic(params: EventParams): string | undefined;
|
||||
// (undocumented)
|
||||
protected getSubscriberId(): string;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/plugin-events-node": "workspace:^",
|
||||
"winston": "^3.2.1"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
|
||||
+20
-13
@@ -14,33 +14,40 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { BitbucketCloudEventRouter } from './BitbucketCloudEventRouter';
|
||||
|
||||
describe('BitbucketCloudEventRouter', () => {
|
||||
const eventRouter = new BitbucketCloudEventRouter();
|
||||
const events = new TestEventsService();
|
||||
const eventRouter = new BitbucketCloudEventRouter({ events });
|
||||
const topic = 'bitbucketCloud';
|
||||
const eventPayload = { test: 'payload' };
|
||||
const metadata = { 'x-event-key': 'test:type' };
|
||||
|
||||
it('no x-event-key', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
beforeEach(() => {
|
||||
events.reset();
|
||||
});
|
||||
|
||||
it('subscribed to topic', () => {
|
||||
eventRouter.subscribe();
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('BitbucketCloudEventRouter');
|
||||
expect(events.subscribed[0].topics).toEqual([topic]);
|
||||
});
|
||||
|
||||
it('no x-event-key', () => {
|
||||
eventRouter.onEvent({ topic, eventPayload });
|
||||
|
||||
expect(eventBroker.published).toEqual([]);
|
||||
expect(events.published).toEqual([]);
|
||||
});
|
||||
|
||||
it('with x-event-key', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
eventRouter.onEvent({ topic, eventPayload, metadata });
|
||||
|
||||
expect(eventBroker.published.length).toBe(1);
|
||||
expect(eventBroker.published[0].topic).toEqual('bitbucketCloud.test:type');
|
||||
expect(eventBroker.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(eventBroker.published[0].metadata).toEqual(metadata);
|
||||
expect(events.published.length).toBe(1);
|
||||
expect(events.published[0].topic).toEqual('bitbucketCloud.test:type');
|
||||
expect(events.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(events.published[0].metadata).toEqual(metadata);
|
||||
});
|
||||
});
|
||||
|
||||
+10
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
import {
|
||||
EventParams,
|
||||
EventsService,
|
||||
SubTopicEventRouter,
|
||||
} from '@backstage/plugin-events-node';
|
||||
|
||||
@@ -27,8 +28,15 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export class BitbucketCloudEventRouter extends SubTopicEventRouter {
|
||||
constructor() {
|
||||
super('bitbucketCloud');
|
||||
constructor(options: { events: EventsService }) {
|
||||
super({
|
||||
events: options.events,
|
||||
topic: 'bitbucketCloud',
|
||||
});
|
||||
}
|
||||
|
||||
protected getSubscriberId(): string {
|
||||
return 'BitbucketCloudEventRouter';
|
||||
}
|
||||
|
||||
protected determineSubTopic(params: EventParams): string | undefined {
|
||||
|
||||
+18
-19
@@ -14,32 +14,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { eventsModuleBitbucketCloudEventRouter } from './eventsModuleBitbucketCloudEventRouter';
|
||||
import { BitbucketCloudEventRouter } from '../router/BitbucketCloudEventRouter';
|
||||
|
||||
describe('eventsModuleBitbucketCloudEventRouter', () => {
|
||||
it('should be correctly wired and set up', async () => {
|
||||
let addedPublisher: BitbucketCloudEventRouter | undefined;
|
||||
let addedSubscriber: BitbucketCloudEventRouter | undefined;
|
||||
const extensionPoint = {
|
||||
addPublishers: (publisher: any) => {
|
||||
addedPublisher = publisher;
|
||||
const events = new TestEventsService();
|
||||
const eventsServiceFactory = createServiceFactory({
|
||||
service: eventsServiceRef,
|
||||
deps: {},
|
||||
async factory({}) {
|
||||
return events;
|
||||
},
|
||||
addSubscribers: (subscriber: any) => {
|
||||
addedSubscriber = subscriber;
|
||||
},
|
||||
};
|
||||
|
||||
await startTestBackend({
|
||||
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
|
||||
features: [eventsModuleBitbucketCloudEventRouter()],
|
||||
});
|
||||
|
||||
expect(addedPublisher).not.toBeUndefined();
|
||||
expect(addedPublisher).toBeInstanceOf(BitbucketCloudEventRouter);
|
||||
expect(addedSubscriber).not.toBeUndefined();
|
||||
expect(addedSubscriber).toBeInstanceOf(BitbucketCloudEventRouter);
|
||||
await startTestBackend({
|
||||
features: [
|
||||
eventsServiceFactory(),
|
||||
eventsModuleBitbucketCloudEventRouter(),
|
||||
],
|
||||
});
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('BitbucketCloudEventRouter');
|
||||
});
|
||||
});
|
||||
|
||||
+6
-6
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { BitbucketCloudEventRouter } from '../router/BitbucketCloudEventRouter';
|
||||
|
||||
/**
|
||||
@@ -31,13 +31,13 @@ export const eventsModuleBitbucketCloudEventRouter = createBackendModule({
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
events: eventsExtensionPoint,
|
||||
events: eventsServiceRef,
|
||||
},
|
||||
async init({ events }) {
|
||||
const eventRouter = new BitbucketCloudEventRouter();
|
||||
|
||||
events.addPublishers(eventRouter);
|
||||
events.addSubscribers(eventRouter);
|
||||
const eventRouter = new BitbucketCloudEventRouter({
|
||||
events,
|
||||
});
|
||||
await eventRouter.subscribe();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
|
||||
```ts
|
||||
import { EventParams } from '@backstage/plugin-events-node';
|
||||
import { EventsService } from '@backstage/plugin-events-node';
|
||||
import { SubTopicEventRouter } from '@backstage/plugin-events-node';
|
||||
|
||||
// @public
|
||||
export class GerritEventRouter extends SubTopicEventRouter {
|
||||
constructor();
|
||||
constructor(options: { events: EventsService });
|
||||
// (undocumented)
|
||||
protected determineSubTopic(params: EventParams): string | undefined;
|
||||
// (undocumented)
|
||||
protected getSubscriberId(): string;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/plugin-events-node": "workspace:^",
|
||||
"winston": "^3.2.1"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
|
||||
@@ -14,37 +14,44 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { GerritEventRouter } from './GerritEventRouter';
|
||||
|
||||
describe('GerritEventRouter', () => {
|
||||
const eventRouter = new GerritEventRouter();
|
||||
const events = new TestEventsService();
|
||||
const eventRouter = new GerritEventRouter({ events: events });
|
||||
const topic = 'gerrit';
|
||||
const eventPayload = { type: 'test-type', test: 'payload' };
|
||||
const metadata = {};
|
||||
|
||||
it('no $.type', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
beforeEach(() => {
|
||||
events.reset();
|
||||
});
|
||||
|
||||
it('subscribed to topic', () => {
|
||||
eventRouter.subscribe();
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('GerritEventRouter');
|
||||
expect(events.subscribed[0].topics).toEqual([topic]);
|
||||
});
|
||||
|
||||
it('no $.type', () => {
|
||||
eventRouter.onEvent({
|
||||
topic,
|
||||
eventPayload: { invalid: 'payload' },
|
||||
metadata,
|
||||
});
|
||||
|
||||
expect(eventBroker.published).toEqual([]);
|
||||
expect(events.published).toEqual([]);
|
||||
});
|
||||
|
||||
it('with $.type', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
eventRouter.onEvent({ topic, eventPayload, metadata });
|
||||
|
||||
expect(eventBroker.published.length).toBe(1);
|
||||
expect(eventBroker.published[0].topic).toEqual('gerrit.test-type');
|
||||
expect(eventBroker.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(eventBroker.published[0].metadata).toEqual(metadata);
|
||||
expect(events.published.length).toBe(1);
|
||||
expect(events.published[0].topic).toEqual('gerrit.test-type');
|
||||
expect(events.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(events.published[0].metadata).toEqual(metadata);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import {
|
||||
EventParams,
|
||||
EventsService,
|
||||
SubTopicEventRouter,
|
||||
} from '@backstage/plugin-events-node';
|
||||
|
||||
@@ -27,8 +28,15 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export class GerritEventRouter extends SubTopicEventRouter {
|
||||
constructor() {
|
||||
super('gerrit');
|
||||
constructor(options: { events: EventsService }) {
|
||||
super({
|
||||
events: options.events,
|
||||
topic: 'gerrit',
|
||||
});
|
||||
}
|
||||
|
||||
protected getSubscriberId(): string {
|
||||
return 'GerritEventRouter';
|
||||
}
|
||||
|
||||
protected determineSubTopic(params: EventParams): string | undefined {
|
||||
|
||||
+15
-19
@@ -14,32 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { eventsModuleGerritEventRouter } from './eventsModuleGerritEventRouter';
|
||||
import { GerritEventRouter } from '../router/GerritEventRouter';
|
||||
|
||||
describe('eventsModuleGerritEventRouter', () => {
|
||||
it('should be correctly wired and set up', async () => {
|
||||
let addedPublisher: GerritEventRouter | undefined;
|
||||
let addedSubscriber: GerritEventRouter | undefined;
|
||||
const extensionPoint = {
|
||||
addPublishers: (publisher: any) => {
|
||||
addedPublisher = publisher;
|
||||
const events = new TestEventsService();
|
||||
const eventsServiceFactory = createServiceFactory({
|
||||
service: eventsServiceRef,
|
||||
deps: {},
|
||||
async factory({}) {
|
||||
return events;
|
||||
},
|
||||
addSubscribers: (subscriber: any) => {
|
||||
addedSubscriber = subscriber;
|
||||
},
|
||||
};
|
||||
|
||||
await startTestBackend({
|
||||
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
|
||||
features: [eventsModuleGerritEventRouter()],
|
||||
});
|
||||
|
||||
expect(addedPublisher).not.toBeUndefined();
|
||||
expect(addedPublisher).toBeInstanceOf(GerritEventRouter);
|
||||
expect(addedSubscriber).not.toBeUndefined();
|
||||
expect(addedSubscriber).toBeInstanceOf(GerritEventRouter);
|
||||
await startTestBackend({
|
||||
features: [eventsServiceFactory(), eventsModuleGerritEventRouter()],
|
||||
});
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('GerritEventRouter');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { GerritEventRouter } from '../router/GerritEventRouter';
|
||||
|
||||
/**
|
||||
@@ -31,13 +31,11 @@ export const eventsModuleGerritEventRouter = createBackendModule({
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
events: eventsExtensionPoint,
|
||||
events: eventsServiceRef,
|
||||
},
|
||||
async init({ events }) {
|
||||
const eventRouter = new GerritEventRouter();
|
||||
|
||||
events.addPublishers(eventRouter);
|
||||
events.addSubscribers(eventRouter);
|
||||
const eventRouter = new GerritEventRouter({ events });
|
||||
await eventRouter.subscribe();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
```ts
|
||||
import { Config } from '@backstage/config';
|
||||
import { EventParams } from '@backstage/plugin-events-node';
|
||||
import { EventsService } from '@backstage/plugin-events-node';
|
||||
import { RequestValidator } from '@backstage/plugin-events-node';
|
||||
import { SubTopicEventRouter } from '@backstage/plugin-events-node';
|
||||
|
||||
@@ -15,8 +16,10 @@ export function createGithubSignatureValidator(
|
||||
|
||||
// @public
|
||||
export class GithubEventRouter extends SubTopicEventRouter {
|
||||
constructor();
|
||||
constructor(options: { events: EventsService });
|
||||
// (undocumented)
|
||||
protected determineSubTopic(params: EventParams): string | undefined;
|
||||
// (undocumented)
|
||||
protected getSubscriberId(): string;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/plugin-events-node": "workspace:^",
|
||||
"@octokit/webhooks-methods": "^3.0.0",
|
||||
"winston": "^3.2.1"
|
||||
"@octokit/webhooks-methods": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
|
||||
@@ -14,33 +14,40 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { GithubEventRouter } from './GithubEventRouter';
|
||||
|
||||
describe('GithubEventRouter', () => {
|
||||
const eventRouter = new GithubEventRouter();
|
||||
const events = new TestEventsService();
|
||||
const eventRouter = new GithubEventRouter({ events: events });
|
||||
const topic = 'github';
|
||||
const eventPayload = { test: 'payload' };
|
||||
const metadata = { 'x-github-event': 'test_type' };
|
||||
|
||||
it('no x-github-event', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
beforeEach(() => {
|
||||
events.reset();
|
||||
});
|
||||
|
||||
it('subscribed to topic', () => {
|
||||
eventRouter.subscribe();
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('GithubEventRouter');
|
||||
expect(events.subscribed[0].topics).toEqual([topic]);
|
||||
});
|
||||
|
||||
it('no x-github-event', () => {
|
||||
eventRouter.onEvent({ topic, eventPayload });
|
||||
|
||||
expect(eventBroker.published).toEqual([]);
|
||||
expect(events.published).toEqual([]);
|
||||
});
|
||||
|
||||
it('with x-github-event', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
eventRouter.onEvent({ topic, eventPayload, metadata });
|
||||
|
||||
expect(eventBroker.published.length).toBe(1);
|
||||
expect(eventBroker.published[0].topic).toEqual('github.test_type');
|
||||
expect(eventBroker.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(eventBroker.published[0].metadata).toEqual(metadata);
|
||||
expect(events.published.length).toBe(1);
|
||||
expect(events.published[0].topic).toEqual('github.test_type');
|
||||
expect(events.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(events.published[0].metadata).toEqual(metadata);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import {
|
||||
EventParams,
|
||||
EventsService,
|
||||
SubTopicEventRouter,
|
||||
} from '@backstage/plugin-events-node';
|
||||
|
||||
@@ -27,8 +28,15 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export class GithubEventRouter extends SubTopicEventRouter {
|
||||
constructor() {
|
||||
super('github');
|
||||
constructor(options: { events: EventsService }) {
|
||||
super({
|
||||
events: options.events,
|
||||
topic: 'github',
|
||||
});
|
||||
}
|
||||
|
||||
protected getSubscriberId(): string {
|
||||
return 'GithubEventRouter';
|
||||
}
|
||||
|
||||
protected determineSubTopic(params: EventParams): string | undefined {
|
||||
|
||||
+15
-19
@@ -14,32 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { eventsModuleGithubEventRouter } from './eventsModuleGithubEventRouter';
|
||||
import { GithubEventRouter } from '../router/GithubEventRouter';
|
||||
|
||||
describe('eventsModuleGithubEventRouter', () => {
|
||||
it('should be correctly wired and set up', async () => {
|
||||
let addedPublisher: GithubEventRouter | undefined;
|
||||
let addedSubscriber: GithubEventRouter | undefined;
|
||||
const extensionPoint = {
|
||||
addPublishers: (publisher: any) => {
|
||||
addedPublisher = publisher;
|
||||
const events = new TestEventsService();
|
||||
const eventsServiceFactory = createServiceFactory({
|
||||
service: eventsServiceRef,
|
||||
deps: {},
|
||||
async factory({}) {
|
||||
return events;
|
||||
},
|
||||
addSubscribers: (subscriber: any) => {
|
||||
addedSubscriber = subscriber;
|
||||
},
|
||||
};
|
||||
|
||||
await startTestBackend({
|
||||
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
|
||||
features: [eventsModuleGithubEventRouter()],
|
||||
});
|
||||
|
||||
expect(addedPublisher).not.toBeUndefined();
|
||||
expect(addedPublisher).toBeInstanceOf(GithubEventRouter);
|
||||
expect(addedSubscriber).not.toBeUndefined();
|
||||
expect(addedSubscriber).toBeInstanceOf(GithubEventRouter);
|
||||
await startTestBackend({
|
||||
features: [eventsServiceFactory(), eventsModuleGithubEventRouter()],
|
||||
});
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('GithubEventRouter');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { GithubEventRouter } from '../router/GithubEventRouter';
|
||||
|
||||
/**
|
||||
@@ -31,13 +31,11 @@ export const eventsModuleGithubEventRouter = createBackendModule({
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
events: eventsExtensionPoint,
|
||||
events: eventsServiceRef,
|
||||
},
|
||||
async init({ events }) {
|
||||
const eventRouter = new GithubEventRouter();
|
||||
|
||||
events.addPublishers(eventRouter);
|
||||
events.addSubscribers(eventRouter);
|
||||
const eventRouter = new GithubEventRouter({ events });
|
||||
await eventRouter.subscribe();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
```ts
|
||||
import { Config } from '@backstage/config';
|
||||
import { EventParams } from '@backstage/plugin-events-node';
|
||||
import { EventsService } from '@backstage/plugin-events-node';
|
||||
import { RequestValidator } from '@backstage/plugin-events-node';
|
||||
import { SubTopicEventRouter } from '@backstage/plugin-events-node';
|
||||
|
||||
@@ -13,8 +14,10 @@ export function createGitlabTokenValidator(config: Config): RequestValidator;
|
||||
|
||||
// @public
|
||||
export class GitlabEventRouter extends SubTopicEventRouter {
|
||||
constructor();
|
||||
constructor(options: { events: EventsService });
|
||||
// (undocumented)
|
||||
protected determineSubTopic(params: EventParams): string | undefined;
|
||||
// (undocumented)
|
||||
protected getSubscriberId(): string;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
"dependencies": {
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/plugin-events-node": "workspace:^",
|
||||
"winston": "^3.2.1"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
|
||||
@@ -14,37 +14,44 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { GitlabEventRouter } from './GitlabEventRouter';
|
||||
|
||||
describe('GitlabEventRouter', () => {
|
||||
const eventRouter = new GitlabEventRouter();
|
||||
const events = new TestEventsService();
|
||||
const eventRouter = new GitlabEventRouter({ events: events });
|
||||
const topic = 'gitlab';
|
||||
const eventPayload = { event_name: 'test_type', test: 'payload' };
|
||||
const metadata = {};
|
||||
|
||||
it('no $.event_name', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
beforeEach(() => {
|
||||
events.reset();
|
||||
});
|
||||
|
||||
it('subscribed to topic', () => {
|
||||
eventRouter.subscribe();
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('GitlabEventRouter');
|
||||
expect(events.subscribed[0].topics).toEqual([topic]);
|
||||
});
|
||||
|
||||
it('no $.event_name', () => {
|
||||
eventRouter.onEvent({
|
||||
topic,
|
||||
eventPayload: { invalid: 'payload' },
|
||||
metadata,
|
||||
});
|
||||
|
||||
expect(eventBroker.published).toEqual([]);
|
||||
expect(events.published).toEqual([]);
|
||||
});
|
||||
|
||||
it('with $.event_name', () => {
|
||||
const eventBroker = new TestEventBroker();
|
||||
eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
eventRouter.onEvent({ topic, eventPayload, metadata });
|
||||
|
||||
expect(eventBroker.published.length).toBe(1);
|
||||
expect(eventBroker.published[0].topic).toEqual('gitlab.test_type');
|
||||
expect(eventBroker.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(eventBroker.published[0].metadata).toEqual(metadata);
|
||||
expect(events.published.length).toBe(1);
|
||||
expect(events.published[0].topic).toEqual('gitlab.test_type');
|
||||
expect(events.published[0].eventPayload).toEqual(eventPayload);
|
||||
expect(events.published[0].metadata).toEqual(metadata);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import {
|
||||
EventParams,
|
||||
EventsService,
|
||||
SubTopicEventRouter,
|
||||
} from '@backstage/plugin-events-node';
|
||||
|
||||
@@ -27,8 +28,15 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export class GitlabEventRouter extends SubTopicEventRouter {
|
||||
constructor() {
|
||||
super('gitlab');
|
||||
constructor(options: { events: EventsService }) {
|
||||
super({
|
||||
events: options.events,
|
||||
topic: 'gitlab',
|
||||
});
|
||||
}
|
||||
|
||||
protected getSubscriberId(): string {
|
||||
return 'GitlabEventRouter';
|
||||
}
|
||||
|
||||
protected determineSubTopic(params: EventParams): string | undefined {
|
||||
|
||||
+15
-19
@@ -14,32 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { TestEventsService } from '@backstage/plugin-events-backend-test-utils';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { eventsModuleGitlabEventRouter } from './eventsModuleGitlabEventRouter';
|
||||
import { GitlabEventRouter } from '../router/GitlabEventRouter';
|
||||
|
||||
describe('eventsModuleGitlabEventRouter', () => {
|
||||
it('should be correctly wired and set up', async () => {
|
||||
let addedPublisher: GitlabEventRouter | undefined;
|
||||
let addedSubscriber: GitlabEventRouter | undefined;
|
||||
const extensionPoint = {
|
||||
addPublishers: (publisher: any) => {
|
||||
addedPublisher = publisher;
|
||||
const events = new TestEventsService();
|
||||
const eventsServiceFactory = createServiceFactory({
|
||||
service: eventsServiceRef,
|
||||
deps: {},
|
||||
async factory({}) {
|
||||
return events;
|
||||
},
|
||||
addSubscribers: (subscriber: any) => {
|
||||
addedSubscriber = subscriber;
|
||||
},
|
||||
};
|
||||
|
||||
await startTestBackend({
|
||||
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
|
||||
features: [eventsModuleGitlabEventRouter()],
|
||||
});
|
||||
|
||||
expect(addedPublisher).not.toBeUndefined();
|
||||
expect(addedPublisher).toBeInstanceOf(GitlabEventRouter);
|
||||
expect(addedSubscriber).not.toBeUndefined();
|
||||
expect(addedSubscriber).toBeInstanceOf(GitlabEventRouter);
|
||||
await startTestBackend({
|
||||
features: [eventsServiceFactory(), eventsModuleGitlabEventRouter()],
|
||||
});
|
||||
|
||||
expect(events.subscribed).toHaveLength(1);
|
||||
expect(events.subscribed[0].id).toEqual('GitlabEventRouter');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { GitlabEventRouter } from '../router/GitlabEventRouter';
|
||||
|
||||
/**
|
||||
@@ -31,13 +31,11 @@ export const eventsModuleGitlabEventRouter = createBackendModule({
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
events: eventsExtensionPoint,
|
||||
events: eventsServiceRef,
|
||||
},
|
||||
async init({ events }) {
|
||||
const eventRouter = new GitlabEventRouter();
|
||||
|
||||
events.addPublishers(eventRouter);
|
||||
events.addSubscribers(eventRouter);
|
||||
const eventRouter = new GitlabEventRouter({ events: events });
|
||||
await eventRouter.subscribe();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -39,17 +39,17 @@ export interface EventPublisher {
|
||||
}
|
||||
|
||||
// @public
|
||||
export abstract class EventRouter implements EventPublisher, EventSubscriber {
|
||||
export abstract class EventRouter {
|
||||
protected constructor(options: { events: EventsService; topics: string[] });
|
||||
// (undocumented)
|
||||
protected abstract determineDestinationTopic(
|
||||
params: EventParams,
|
||||
): string | undefined;
|
||||
// (undocumented)
|
||||
protected abstract getSubscriberId(): string;
|
||||
// (undocumented)
|
||||
onEvent(params: EventParams): Promise<void>;
|
||||
// (undocumented)
|
||||
setEventBroker(eventBroker: EventBroker): Promise<void>;
|
||||
// (undocumented)
|
||||
abstract supportsEventTopics(): string[];
|
||||
subscribe(): Promise<void>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -114,12 +114,10 @@ export type RequestValidator = (
|
||||
|
||||
// @public
|
||||
export abstract class SubTopicEventRouter extends EventRouter {
|
||||
protected constructor(topic: string);
|
||||
protected constructor(options: { events: EventsService; topic: string });
|
||||
// (undocumented)
|
||||
protected determineDestinationTopic(params: EventParams): string | undefined;
|
||||
// (undocumented)
|
||||
protected abstract determineSubTopic(params: EventParams): string | undefined;
|
||||
// (undocumented)
|
||||
supportsEventTopics(): string[];
|
||||
}
|
||||
```
|
||||
|
||||
@@ -14,11 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EventBroker } from './EventBroker';
|
||||
import { EventParams } from './EventParams';
|
||||
import { EventRouter } from './EventRouter';
|
||||
import { EventsService } from './EventsService';
|
||||
|
||||
class TestEventRouter extends EventRouter {
|
||||
constructor(events: EventsService) {
|
||||
super({ events, topics: ['my-topic'] });
|
||||
}
|
||||
|
||||
protected getSubscriberId(): string {
|
||||
return 'TestEventRouter';
|
||||
}
|
||||
|
||||
protected determineDestinationTopic(params: EventParams): string | undefined {
|
||||
const payload = params.eventPayload as { value?: number };
|
||||
if (payload.value === undefined) {
|
||||
@@ -27,26 +35,21 @@ class TestEventRouter extends EventRouter {
|
||||
|
||||
return payload.value % 2 === 0 ? 'even' : 'odd';
|
||||
}
|
||||
|
||||
supportsEventTopics(): string[] {
|
||||
return ['my-topic'];
|
||||
}
|
||||
}
|
||||
|
||||
describe('EventRouter', () => {
|
||||
const eventRouter = new TestEventRouter();
|
||||
const published: EventParams[] = [];
|
||||
const events: EventsService = {
|
||||
publish: async event => {
|
||||
published.push(event);
|
||||
},
|
||||
subscribe: async _subscription => {},
|
||||
};
|
||||
const eventRouter = new TestEventRouter(events);
|
||||
const topic = 'my-topic';
|
||||
const metadata = { random: 'metadata' };
|
||||
|
||||
it('no destination topic', async () => {
|
||||
const published: EventParams[] = [];
|
||||
const eventBroker = {
|
||||
publish: (params: EventParams) => {
|
||||
published.push(params);
|
||||
},
|
||||
} as EventBroker;
|
||||
await eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
await eventRouter.onEvent({
|
||||
topic,
|
||||
eventPayload: { discarded: 'event' },
|
||||
@@ -57,14 +60,6 @@ describe('EventRouter', () => {
|
||||
});
|
||||
|
||||
it('with destination topic', async () => {
|
||||
const published: EventParams[] = [];
|
||||
const eventBroker = {
|
||||
publish: (params: EventParams) => {
|
||||
published.push(params);
|
||||
},
|
||||
} as EventBroker;
|
||||
await eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
const payloadEven = { value: 2 };
|
||||
const payloadOdd = { value: 3 };
|
||||
await eventRouter.onEvent({ topic, eventPayload: payloadEven, metadata });
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EventBroker } from './EventBroker';
|
||||
import { EventParams } from './EventParams';
|
||||
import { EventPublisher } from './EventPublisher';
|
||||
import { EventSubscriber } from './EventSubscriber';
|
||||
import { EventsService } from './EventsService';
|
||||
|
||||
/**
|
||||
* Subscribes to a topic and - depending on a set of conditions -
|
||||
@@ -26,13 +24,41 @@ import { EventSubscriber } from './EventSubscriber';
|
||||
* @see {@link https://www.enterpriseintegrationpatterns.com/MessageRouter.html | Message Router pattern}.
|
||||
* @public
|
||||
*/
|
||||
export abstract class EventRouter implements EventPublisher, EventSubscriber {
|
||||
private eventBroker?: EventBroker;
|
||||
export abstract class EventRouter {
|
||||
private readonly events: EventsService;
|
||||
private readonly topics: string[];
|
||||
private subscribed: boolean = false;
|
||||
|
||||
protected constructor(options: { events: EventsService; topics: string[] }) {
|
||||
this.events = options.events;
|
||||
this.topics = options.topics;
|
||||
}
|
||||
|
||||
protected abstract getSubscriberId(): string;
|
||||
|
||||
protected abstract determineDestinationTopic(
|
||||
params: EventParams,
|
||||
): string | undefined;
|
||||
|
||||
/**
|
||||
* Subscribes itself to the topic(s),
|
||||
* after which events potentially can be received
|
||||
* and processed by {@link EventRouter.onEvent}.
|
||||
*/
|
||||
async subscribe(): Promise<void> {
|
||||
if (this.subscribed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.subscribed = true;
|
||||
|
||||
await this.events.subscribe({
|
||||
id: this.getSubscriberId(),
|
||||
topics: this.topics,
|
||||
onEvent: this.onEvent.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
async onEvent(params: EventParams): Promise<void> {
|
||||
const topic = this.determineDestinationTopic(params);
|
||||
|
||||
@@ -41,15 +67,9 @@ export abstract class EventRouter implements EventPublisher, EventSubscriber {
|
||||
}
|
||||
|
||||
// republish to different topic
|
||||
this.eventBroker?.publish({
|
||||
await this.events.publish({
|
||||
...params,
|
||||
topic,
|
||||
});
|
||||
}
|
||||
|
||||
async setEventBroker(eventBroker: EventBroker): Promise<void> {
|
||||
this.eventBroker = eventBroker;
|
||||
}
|
||||
|
||||
abstract supportsEventTopics(): string[];
|
||||
}
|
||||
|
||||
@@ -14,13 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EventBroker } from './EventBroker';
|
||||
import { EventParams } from './EventParams';
|
||||
import { EventsService } from './EventsService';
|
||||
import { SubTopicEventRouter } from './SubTopicEventRouter';
|
||||
|
||||
class TestSubTopicEventRouter extends SubTopicEventRouter {
|
||||
constructor() {
|
||||
super('my-topic');
|
||||
constructor(events: EventsService) {
|
||||
super({ events, topic: 'my-topic' });
|
||||
}
|
||||
|
||||
protected getSubscriberId(): string {
|
||||
return 'TestSubTopicEventRouter';
|
||||
}
|
||||
|
||||
protected determineSubTopic(params: EventParams): string | undefined {
|
||||
@@ -29,34 +33,25 @@ class TestSubTopicEventRouter extends SubTopicEventRouter {
|
||||
}
|
||||
|
||||
describe('SubTopicEventRouter', () => {
|
||||
const eventRouter = new TestSubTopicEventRouter();
|
||||
const published: EventParams[] = [];
|
||||
const events: EventsService = {
|
||||
publish: async event => {
|
||||
published.push(event);
|
||||
},
|
||||
subscribe: async _subscription => {},
|
||||
};
|
||||
const eventRouter = new TestSubTopicEventRouter(events);
|
||||
const topic = 'my-topic';
|
||||
const eventPayload = { test: 'payload' };
|
||||
const metadata = { 'x-my-event': 'test.type' };
|
||||
|
||||
it('no x-my-event', async () => {
|
||||
const published: EventParams[] = [];
|
||||
const eventBroker = {
|
||||
publish: (params: EventParams) => {
|
||||
published.push(params);
|
||||
},
|
||||
} as EventBroker;
|
||||
await eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
await eventRouter.onEvent({ topic, eventPayload });
|
||||
|
||||
expect(published).toEqual([]);
|
||||
});
|
||||
|
||||
it('with x-my-event', async () => {
|
||||
const published: EventParams[] = [];
|
||||
const eventBroker = {
|
||||
publish: (params: EventParams) => {
|
||||
published.push(params);
|
||||
},
|
||||
} as EventBroker;
|
||||
await eventRouter.setEventBroker(eventBroker);
|
||||
|
||||
await eventRouter.onEvent({ topic, eventPayload, metadata });
|
||||
|
||||
expect(published.length).toBe(1);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import { EventParams } from './EventParams';
|
||||
import { EventRouter } from './EventRouter';
|
||||
import { EventsService } from './EventsService';
|
||||
|
||||
/**
|
||||
* Subscribes to the provided (generic) topic
|
||||
@@ -27,8 +28,11 @@ import { EventRouter } from './EventRouter';
|
||||
* @public
|
||||
*/
|
||||
export abstract class SubTopicEventRouter extends EventRouter {
|
||||
protected constructor(private readonly topic: string) {
|
||||
super();
|
||||
protected constructor(options: { events: EventsService; topic: string }) {
|
||||
super({
|
||||
events: options.events,
|
||||
topics: [options.topic],
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract determineSubTopic(params: EventParams): string | undefined;
|
||||
@@ -37,8 +41,4 @@ export abstract class SubTopicEventRouter extends EventRouter {
|
||||
const subTopic = this.determineSubTopic(params);
|
||||
return subTopic ? `${params.topic}.${subTopic}` : undefined;
|
||||
}
|
||||
|
||||
supportsEventTopics(): string[] {
|
||||
return [this.topic];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6404,7 +6404,6 @@ __metadata:
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/plugin-events-backend-test-utils": "workspace:^"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
winston: ^3.2.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -6417,7 +6416,6 @@ __metadata:
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/plugin-events-backend-test-utils": "workspace:^"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
winston: ^3.2.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -6430,7 +6428,6 @@ __metadata:
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/plugin-events-backend-test-utils": "workspace:^"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
winston: ^3.2.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -6445,7 +6442,6 @@ __metadata:
|
||||
"@backstage/plugin-events-backend-test-utils": "workspace:^"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
"@octokit/webhooks-methods": ^3.0.0
|
||||
winston: ^3.2.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -6459,7 +6455,6 @@ __metadata:
|
||||
"@backstage/config": "workspace:^"
|
||||
"@backstage/plugin-events-backend-test-utils": "workspace:^"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
winston: ^3.2.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
|
||||
Reference in New Issue
Block a user