From 1ab76e523de915c497277ed8d7ebdf03aad09579 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Wed, 24 Jan 2024 03:06:54 +0100 Subject: [PATCH] docs(events): describe the new events setup, update README.md files Signed-off-by: Patrick Jungermann --- .../events-backend-module-aws-sqs/README.md | 48 ++- plugins/events-backend-module-azure/README.md | 32 +- .../README.md | 32 +- .../events-backend-module-gerrit/README.md | 28 +- .../events-backend-module-github/README.md | 52 ++-- .../events-backend-module-gitlab/README.md | 52 ++-- plugins/events-backend-test-utils/README.md | 7 +- plugins/events-backend/README.md | 277 +++++------------- plugins/events-node/README.md | 83 +++++- 9 files changed, 295 insertions(+), 316 deletions(-) diff --git a/plugins/events-backend-module-aws-sqs/README.md b/plugins/events-backend-module-aws-sqs/README.md index 7ca4bb280d..bd8e0c51d3 100644 --- a/plugins/events-backend-module-aws-sqs/README.md +++ b/plugins/events-backend-module-aws-sqs/README.md @@ -1,12 +1,12 @@ -# events-backend-module-aws-sqs +# `@backstage/plugins-events-backend-module-aws-sqs` -Welcome to the `events-backend-module-aws-sqs` backend plugin! +Welcome to the `events-backend-module-aws-sqs` backend module! -This plugin is a module for the `events-backend` backend plugin -and extends it with an `AwsSqsConsumingEventPublisher`. +This package is a module for the `events-backend` backend plugin +and extends the events system with an `AwsSqsConsumingEventPublisher`. -This event publisher will allow you to receive events from -an AWS SQS queue and will publish these to the used event broker. +This event publisher will allow you to receive events from an AWS SQS queue +and will publish these to the used `EventsService` implementation. ## Configuration @@ -32,15 +32,43 @@ events: ## Installation -1. Install the [`events-backend` plugin](../events-backend/README.md). -2. Install this module -3. Add your configuration. +1. Install this module +2. Add your configuration. ```bash # From your Backstage root directory yarn --cwd packages/backend add @backstage/plugin-events-backend-module-aws-sqs ``` -```ts title="packages/backend/src/index.ts" +```ts +// packages/backend/src/index.ts backend.add(import('@backstage/plugin-events-backend-module-aws-sqs/alpha')); ``` + +### Legacy Backend System + +```ts +// packages/backend/src/plugins/events.ts +// ... +import { AwsSqsConsumingEventPublisher } from '@backstage/plugin-events-backend-module-aws-sqs'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + const eventsRouter = Router(); + + // ... + + const sqs = AwsSqsConsumingEventPublisher.fromConfig({ + config: env.config, + events: env.events, + logger: env.logger, + scheduler: env.scheduler, + }); + await Promise.all(sqs.map(publisher => publisher.start())); + + return eventsRouter; +} +``` diff --git a/plugins/events-backend-module-azure/README.md b/plugins/events-backend-module-azure/README.md index 61b3b63175..7c3920d499 100644 --- a/plugins/events-backend-module-azure/README.md +++ b/plugins/events-backend-module-azure/README.md @@ -1,9 +1,9 @@ # events-backend-module-azure -Welcome to the `events-backend-module-azure` backend plugin! +Welcome to the `events-backend-module-azure` backend module! -This plugin is a module for the `events-backend` backend plugin -and extends it with an `AzureDevOpsEventRouter`. +This package is a module for the `events-backend` backend plugin +and extends the event system with an `AzureDevOpsEventRouter`. The event router will subscribe to the topic `azureDevOps` and route the events to more concrete topics based on the value @@ -22,30 +22,22 @@ and [webhooks](https://learn.microsoft.com/en-us/azure/devops/service-hooks/serv ## Installation -Install the [`events-backend` plugin](../events-backend/README.md). - -Install this module: - ```bash # From your Backstage root directory yarn --cwd packages/backend add @backstage/plugin-events-backend-module-azure ``` -### Add to backend - -```ts title="packages/backend/src/index.ts" +```ts +// packages/backend/src/index.ts backend.add(import('@backstage/plugin-events-backend-module-azure/alpha')); ``` -### Add to backend (old) +### Legacy Backend System -Add the event router to the `EventsBackend` instance in `packages/backend/src/plugins/events.ts`: - -```diff -+const azureEventRouter = new AzureDevOpsEventRouter(); - -new EventsBackend(env.logger) -+ .addPublishers(azureEventRouter) -+ .addSubscribers(azureEventRouter); -// [...] +```ts +// packages/backend/src/plugins/events.ts +const eventRouter = new AzureDevOpsEventRouter({ + events: env.events, +}); +await eventRouter.subscribe(); ``` diff --git a/plugins/events-backend-module-bitbucket-cloud/README.md b/plugins/events-backend-module-bitbucket-cloud/README.md index 0a40ab2eea..7ff743c06d 100644 --- a/plugins/events-backend-module-bitbucket-cloud/README.md +++ b/plugins/events-backend-module-bitbucket-cloud/README.md @@ -1,9 +1,9 @@ # events-backend-module-bitbucket-cloud -Welcome to the `events-backend-module-bitbucket-cloud` backend plugin! +Welcome to the `events-backend-module-bitbucket-cloud` backend module! -This plugin is a module for the `events-backend` backend plugin -and extends it with an `BitbucketCloudEventRouter`. +This package is a module for the `events-backend` backend plugin +and extends the event system with an `BitbucketCloudEventRouter`. The event router will subscribe to the topic `bitbucketCloud` and route the events to more concrete topics based on the value @@ -22,32 +22,24 @@ Please find all possible webhook event types at the ## Installation -Install the [`events-backend` plugin](../events-backend/README.md). - -Install this module: - ```bash # From your Backstage root directory yarn --cwd packages/backend add @backstage/plugin-events-backend-module-bitbucket-cloud ``` -### Add to backend - -```ts title="packages/backend/src/index.ts" +```ts +// packages/backend/src/index.ts backend.add( import('@backstage/plugin-events-backend-module-bitbucket-cloud/alpha'), ); ``` -### Add to backend (old) +### Legacy Backend System -Add the event router to the `EventsBackend` instance in `packages/backend/src/plugins/events.ts`: - -```diff -+const bitbucketCloudEventRouter = new BitbucketCloudEventRouter(); - -new EventsBackend(env.logger) -+ .addPublishers(bitbucketCloudEventRouter) -+ .addSubscribers(bitbucketCloudEventRouter); -// [...] +```ts +// packages/backend/src/plugins/events.ts +const eventRouter = new BitbucketCloudEventRouter({ + events: env.events, +}); +await eventRouter.subscribe(); ``` diff --git a/plugins/events-backend-module-gerrit/README.md b/plugins/events-backend-module-gerrit/README.md index b658fba366..d5b9f9683a 100644 --- a/plugins/events-backend-module-gerrit/README.md +++ b/plugins/events-backend-module-gerrit/README.md @@ -1,8 +1,8 @@ # events-backend-module-gerrit -Welcome to the `events-backend-module-gerrit` backend plugin! +Welcome to the `events-backend-module-gerrit` backend module! -This plugin is a module for the `events-backend` backend plugin +This package is a module for the `events-backend` backend plugin and extends it with an `GerritEventRouter`. The event router will subscribe to the topic `gerrit` @@ -21,30 +21,20 @@ Please find all possible webhook event types at the ## Installation -Install the [`events-backend` plugin](../events-backend/README.md). - -Install this module: - ```bash # From your Backstage root directory yarn --cwd packages/backend add @backstage/plugin-events-backend-module-gerrit ``` -### Add to backend - -```ts title="packages/backend/src/index.ts" +```ts +// packages/backend/src/index.ts backend.add(import('@backstage/plugin-events-backend-module-gerrit/alpha')); ``` -### Add to backend (old) +### Legacy Backend System -Add the event router to the `EventsBackend` instance in `packages/backend/src/plugins/events.ts`: - -```diff -+const gerritEventRouter = new GerritEventRouter(); - -new EventsBackend(env.logger) -+ .addPublishers(gerritEventRouter) -+ .addSubscribers(gerritEventRouter); -// [...] +```ts +// packages/backend/src/plugins/events.ts +const eventRouter = new GerritEventRouter({ events: env.events }); +await eventRouter.subscribe(); ``` diff --git a/plugins/events-backend-module-github/README.md b/plugins/events-backend-module-github/README.md index 072877ee86..fec27b62e3 100644 --- a/plugins/events-backend-module-github/README.md +++ b/plugins/events-backend-module-github/README.md @@ -1,9 +1,9 @@ # events-backend-module-github -Welcome to the `events-backend-module-github` backend plugin! +Welcome to the `events-backend-module-github` backend module! -This plugin is a module for the `events-backend` backend plugin -and extends it with an `GithubEventRouter`. +This package is a module for the `events-backend` backend plugin +and extends the event system with an `GithubEventRouter`. The event router will subscribe to the topic `github` and route the events to more concrete topics based on the value @@ -22,37 +22,49 @@ Please find all possible webhook event types at the ## Installation -Install the [`events-backend` plugin](../events-backend/README.md). - -Install this module: - ```bash # From your Backstage root directory yarn --cwd packages/backend add @backstage/plugin-events-backend-module-github ``` -Add the event router to the `EventsBackend` instance in `packages/backend/src/plugins/events.ts`: +### Event Router -```diff -+const githubEventRouter = new GithubEventRouter(); +```ts +// packages/backend/src/index.ts +import { eventsModuleGithubEventRouter } from '@backstage/plugin-events-backend-module-github/alpha'; +// ... +backend.add(eventsModuleGithubEventRouter()); +``` -new EventsBackend(env.logger) -+ .addPublishers(githubEventRouter) -+ .addSubscribers(githubEventRouter); -// [...] +#### Legacy Backend System + +```ts +// packages/backend/src/plugins/events.ts +const eventRouter = new GithubEventRouter({ events: env.events }); +await eventRouter.subscribe(); ``` ### Signature Validator +```ts +// packages/backend/src/index.ts +import { eventsModuleGithubWebhook } from '@backstage/plugin-events-backend-module-github/alpha'; +// ... +backend.add(eventsModuleGithubWebhook()); +``` + +#### Legacy Backend System + Add the signature validator for the topic `github`: ```diff -// at packages/backend/src/plugins/events.ts +// packages/backend/src/plugins/events.ts + import { createGithubSignatureValidator } from '@backstage/plugin-events-backend-module-github'; -// [...] - const http = HttpPostIngressEventPublisher.fromConfig({ - config: env.config, - ingresses: { + // [...] + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + events: env.events, + ingresses: { + github: { + validator: createGithubSignatureValidator(env.config), + }, @@ -61,7 +73,7 @@ Add the signature validator for the topic `github`: }); ``` -Additionally, you need to add the configuration: +## Configuration ```yaml events: diff --git a/plugins/events-backend-module-gitlab/README.md b/plugins/events-backend-module-gitlab/README.md index 3d4919302f..73d5bf2d87 100644 --- a/plugins/events-backend-module-gitlab/README.md +++ b/plugins/events-backend-module-gitlab/README.md @@ -1,9 +1,9 @@ # events-backend-module-gitlab -Welcome to the `events-backend-module-gitlab` backend plugin! +Welcome to the `events-backend-module-gitlab` backend module! -This plugin is a module for the `events-backend` backend plugin -and extends it with an `GitlabEventRouter`. +This package is a module for the `events-backend` backend plugin +and extends the event system with an `GitlabEventRouter`. The event router will subscribe to the topic `gitlab` and route the events to more concrete topics based on the value @@ -21,37 +21,49 @@ Please find all possible webhook event types at the ## Installation -Install the [`events-backend` plugin](../events-backend/README.md). - -Install this module: - ```bash # From your Backstage root directory yarn --cwd packages/backend add @backstage/plugin-events-backend-module-gitlab ``` -Add the event router to the `EventsBackend` instance in `packages/backend/src/plugins/events.ts`: +### Event Router -```diff -+const gitlabEventRouter = new GitlabEventRouter(); +```ts +// packages/backend/src/index.ts +import { eventsModuleGitlabEventRouter } from '@backstage/plugin-events-backend-module-gitlab/alpha'; +// ... +backend.add(eventsModuleGitlabEventRouter()); +``` -new EventsBackend(env.logger) -+ .addPublishers(gitlabEventRouter) -+ .addSubscribers(gitlabEventRouter); -// [...] +#### Legacy Backend System + +```ts +// packages/backend/src/plugins/events.ts +const eventRouter = new GitlabEventRouter({ events: env.events }); +await eventRouter.subscribe(); ``` ### Token Validator +```ts +// packages/backend/src/index.ts +import { eventsModuleGitlabWebhook } from '@backstage/plugin-events-backend-module-gitlab/alpha'; +// ... +backend.add(eventsModuleGitlabWebhook()); +``` + +#### Legacy Backend System + Add the token validator for the topic `gitlab`: ```diff -// at packages/backend/src/plugins/events.ts +// packages/backend/src/plugins/events.ts + import { createGitlabTokenValidator } from '@backstage/plugin-events-backend-module-gitlab'; -// [...] - const http = HttpPostIngressEventPublisher.fromConfig({ - config: env.config, - ingresses: { + // [...] + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + events: env.events, + ingresses: { + gitlab: { + validator: createGitlabTokenValidator(env.config), + }, @@ -60,7 +72,7 @@ Add the token validator for the topic `gitlab`: }); ``` -Additionally, you need to add the configuration: +## Configuration ```yaml events: diff --git a/plugins/events-backend-test-utils/README.md b/plugins/events-backend-test-utils/README.md index c8727b536b..84a1be754e 100644 --- a/plugins/events-backend-test-utils/README.md +++ b/plugins/events-backend-test-utils/README.md @@ -1,4 +1,5 @@ -# plugin-events-backend-test-utils +# `@backstage/plugin-events-backend-test-utils` -Houses implementations of plugin-events-node interfaces -which can be useful for test for events-backend and its modules. +This is a package that can be used as `devDependency` +and provides a test implementation for the `EventsService` +by [`events-node` package](../events-node/README.md): `TestEventsService`. diff --git a/plugins/events-backend/README.md b/plugins/events-backend/README.md index b8470101aa..2dba259986 100644 --- a/plugins/events-backend/README.md +++ b/plugins/events-backend/README.md @@ -1,166 +1,55 @@ -# events-backend +# `@backstage/plugin-events-backend` Welcome to the events-backend backend plugin! -This plugin provides the wiring of all extension points -for managing events as defined by [plugin-events-node](../events-node) -including backend plugin `EventsPlugin` and `EventsBackend`. - -Additionally, it uses a simple in-process implementation for -the `EventBroker` by default which you can replace with a more sophisticated -implementation of your choice as you need (e.g., via module). - -Some of these (non-exhaustive) may provide added persistence, -or use external systems like AWS EventBridge, AWS SNS, Kafka, etc. +This package is based on [events-node](../events-node) and its `eventsServiceRef` +that is at the core of the event support. +It provides an `eventsPlugin` (exported as `default`). By default, the plugin ships with support to receive events via HTTP endpoints -`POST /api/events/http/{topic}` and will publish these -to the used event broker. +`POST /api/events/http/{topic}` and will publish these to the `EventsService`. + +HTTP ingresses can be enabled by config, or using the extension point +of the `eventsPlugin`. +Additionally, the latter allows to add a request validator +(e.g., signature verification). ## Installation ```bash # From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-events-backend @backstage/plugin-events-node +yarn --cwd packages/backend add @backstage/plugin-events-backend ``` -### Add to backend - -```ts title="packages/backend/src/index.ts" +```ts +// packages/backend/src/index.ts backend.add(import('@backstage/plugin-events-backend/alpha')); ``` -### Add to backend (old) +### Legacy Backend System -#### Event Broker +```ts +// packages/backend/src/plugins/events.ts +import { HttpPostIngressEventPublisher } from '@backstage/plugin-events-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; -First you will need to add and implementation of the `EventBroker` interface to the backend plugin environment. -This will allow event broker instance any backend plugins to publish and subscribe to events in order to communicate -between them. - -Add the following to `makeCreateEnv` - -```diff -// packages/backend/src/index.ts -+ import { DefaultEventBroker } from '@backstage/plugin-events-backend'; -+ const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' })); -``` - -Then update plugin environment to include the event broker. - -```diff -// packages/backend/src/types.ts -+ import { EventBroker } from '@backstage/plugin-events-node'; -+ eventBroker: EventBroker; -``` - -#### Publishing and Subscribing to events with the broker - -Backend plugins are passed the event broker in the plugin environment at startup of the application. The plugin can -make use of this to communicate between parts of the application. - -Here is an example of a plugin publishing a payload to a topic. - -```typescript jsx export default async function createPlugin( env: PluginEnvironment, ): Promise { - env.eventBroker.publish({ - topic: 'publish.example', - eventPayload: { message: 'Hello, World!' }, - metadata: {}, + const eventsRouter = Router(); + + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + events: env.events, + logger: env.logger, }); + http.bind(eventsRouter); + + return eventsRouter; } ``` -Here is an example of a plugin subscribing to a topic. - -```typescript jsx -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - env.eventBroker.subscribe([ - { - supportsEventTopics: ['publish.example'], - onEvent: async (params: EventParams) => { - env.logger.info(`receieved ${params.topic} event`); - }, - }, - ]); -} -``` - -#### Implementing an `EventSubscriber` class - -More complex solutions might need the creation of a class that implements the `EventSubscriber` interface. e.g. - -```typescript jsx -import { EventSubscriber } from './EventSubscriber'; - -class ExampleSubscriber implements EventSubscriber { - // ... - - supportsEventTopics() { - return ['publish.example']; - } - - async onEvent(params: EventParams) { - env.logger.info(`receieved ${params.topic} event`); - } -} -``` - -#### Events Backend - -The events backend plugin provides a router to handler http events and publish the http requests onto the event -broker. - -To configure it add a file [`packages/backend/src/plugins/events.ts`](../../packages/backend/src/plugins/events.ts) -to your Backstage project. - -Additionally, add the events plugin to your backend. - -```diff -// packages/backend/src/index.ts -// [...] -+import events from './plugins/events'; -// [...] -+ const eventsEnv = useHotMemoize(module, () => createEnv('events')); -// [...] -+ apiRouter.use('/events', await events(eventsEnv)); -// [...] -``` - -#### Configuration - -In order to create HTTP endpoints to receive events for a certain -topic, you need to add them at your configuration: - -```yaml -events: - http: - topics: - - bitbucketCloud - - github - - whatever -``` - -Only those topics added to the configuration will result in -available endpoints. - -The example above would result in the following endpoints: - -``` -POST /api/events/http/bitbucketCloud -POST /api/events/http/github -POST /api/events/http/whatever -``` - -You may want to use these for webhooks by SCM providers -in combination with suitable event subscribers. - -However, it is not limited to these use cases. - ### Event-based Entity Providers You can implement the `EventSubscriber` interface on an `EntityProviders` to allow it to handle events from other plugins e.g. the event backend plugin @@ -189,74 +78,42 @@ Assuming you have configured the `eventBroker` into the `PluginEnvironment` you } ``` +## Configuration + +In order to create HTTP endpoints to receive events for a certain +topic, you need to add them at your configuration: + +```yaml +events: + http: + topics: + - bitbucketCloud + - github + - whatever +``` + +Only those topics added to the configuration will result in +available endpoints. + +The example above would result in the following endpoints: + +``` +POST /api/events/http/bitbucketCloud +POST /api/events/http/github +POST /api/events/http/whatever +``` + +You may want to use these for webhooks by SCM providers +in combination with suitable event subscribers. + +However, it is not limited to these use cases. + ## Use Cases -### Custom Event Broker - -Example using the `EventsBackend`: - -```ts -new EventsBackend(env.logger) - .setEventBroker(yourEventBroker) - // [...] - .start(); -``` - -Example using a module: - -```ts -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; - -// [...] - -export const yourModuleEventsModule = createBackendModule({ - pluginId: 'events', - moduleId: 'your-module', - register(env) { - // [...] - env.registerInit({ - deps: { - // [...] - events: eventsExtensionPoint, - // [...] - }, - async init({ /* ... */ events /*, ... */ }) { - // [...] - const yourEventBroker = new YourEventBroker(); - // [...] - events.setEventBroker(yourEventBroker); - }, - }); - }, -}); -``` - ### Request Validator -Example using the `EventsBackend`: - ```ts -const http = HttpPostIngressEventPublisher.fromConfig({ - config: env.config, - ingresses: { - yourTopic: { - validator: yourValidator, - }, - }, - logger: env.logger, -}); -http.bind(router); - -await new EventsBackend(env.logger) - .addPublishers(http) - // [...] - .start(); -``` - -Example using a module: - -```ts -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; // [...] @@ -282,3 +139,19 @@ export const eventsModuleYourFeature = createBackendModule({ }, }); ``` + +#### Legacy Backend System + +```ts +const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + events: env.events, + ingresses: { + yourTopic: { + validator: yourValidator, + }, + }, + logger: env.logger, +}); +http.bind(router); +``` diff --git a/plugins/events-node/README.md b/plugins/events-node/README.md index 44738222bc..ce4d705025 100644 --- a/plugins/events-node/README.md +++ b/plugins/events-node/README.md @@ -1,3 +1,82 @@ -# plugin-events-node +# `@backstage/plugin-events-node` -Houses types and utilities for building events-related modules. +This package defined basic types for event-based interactions inside of Backstage. + +Additionally, it provides the core event service `eventsServiceRef` of type `EventsService` +with its default implementation that uses the `DefaultEventsService` implementation. + +`DefaultEventsService` is a simple in-memory implementation +that requires the co-deployment of producers and consumers of events. + +## Installation + +Add `@backstage/plugin-events-node` as dependency to your plugin or plugin module package +to which you want to add event support. + +Use `eventsServiceRef` as a dependency at your plugin or plugin module. + +### Legacy Backend System + +Create an `EventsService` instance and add it to the environment. + +```ts +// packages/backend/src/plugins/events.ts +import { DefaultEventsService } from '@backstage/plugin-events-node'; + +// ... + +function makeCreateEnv(config: Config) { + // ... + const eventsService = DefaultEventsService.create({ logger: root }); + // ... + return (plugin: string): PluginEnvironment => { + // ... + return { + // ... + events: eventsService, + // ... + }; + }; +} +``` + +Use the `events` from the `PluginEnvironment` as desired: + +```ts +// packages/backend/src/plugins/events.ts +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + // ... + env.events; // ... + // ... +} +``` + +## Use Case + +### Exchange service implementation + +Create your custom service factory implementation: + +```ts +import { eventsServiceRef } from '@backstage/plugin-events-node'; +// ... +export const customEventsServiceFactory = createServiceFactory({ + service: eventsServiceRef, + deps: { + // add needed dependencies here + }, + async factory({ logger }) { + // add your custom logic here + return customEventsService; + }, +}); +``` + +and your custom implementation: + +```diff +// packages/backend/src/index.ts ++ backend.add(customEventsServiceFactory()); +```