@backstage/plugin-events-backend 0.2.21 → 0.3.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -10
- package/README.md +60 -187
- package/alpha/package.json +1 -1
- package/dist/alpha.cjs.js +20 -36
- package/dist/alpha.cjs.js.map +1 -1
- package/dist/cjs/{HttpPostIngressEventPublisher-6e928c08.cjs.js → HttpPostIngressEventPublisher-a08684c9.cjs.js} +5 -58
- package/dist/cjs/HttpPostIngressEventPublisher-a08684c9.cjs.js.map +1 -0
- package/dist/index.cjs.js +36 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +29 -20
- package/package.json +30 -30
- package/dist/cjs/HttpPostIngressEventPublisher-6e928c08.cjs.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,82 @@
|
|
|
1
1
|
# @backstage/plugin-events-backend
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.3.0-next.0
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Minor Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- @backstage/backend-common@0.21.2
|
|
9
|
-
- @backstage/backend-plugin-api@0.6.12
|
|
10
|
-
- @backstage/plugin-events-node@0.2.21
|
|
7
|
+
- c4bd794: BREAKING CHANGE: Migrate `HttpPostIngressEventPublisher` and `eventsPlugin` to use `EventsService`.
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
Uses the `EventsService` instead of `EventBroker` at `HttpPostIngressEventPublisher`,
|
|
10
|
+
dropping the use of `EventPublisher` including `setEventBroker(..)`.
|
|
11
|
+
|
|
12
|
+
Now, `HttpPostIngressEventPublisher.fromConfig` requires `events: EventsService` as option.
|
|
13
|
+
|
|
14
|
+
```diff
|
|
15
|
+
const http = HttpPostIngressEventPublisher.fromConfig({
|
|
16
|
+
config: env.config,
|
|
17
|
+
+ events: env.events,
|
|
18
|
+
logger: env.logger,
|
|
19
|
+
});
|
|
20
|
+
http.bind(eventsRouter);
|
|
21
|
+
|
|
22
|
+
// e.g. at packages/backend/src/plugins/events.ts
|
|
23
|
+
- await new EventsBackend(env.logger)
|
|
24
|
+
- .setEventBroker(env.eventBroker)
|
|
25
|
+
- .addPublishers(http)
|
|
26
|
+
- .start();
|
|
27
|
+
|
|
28
|
+
// or for other kinds of setups
|
|
29
|
+
- await Promise.all(http.map(publisher => publisher.setEventBroker(eventBroker)));
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`eventsPlugin` uses the `eventsServiceRef` as dependency.
|
|
33
|
+
Unsupported (and deprecated) extension point methods will throw an error to prevent unintended behavior.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
|
37
|
+
```
|
|
13
38
|
|
|
14
39
|
### Patch Changes
|
|
15
40
|
|
|
41
|
+
- 56969b6: Add new `EventsService` as well as `eventsServiceRef` for the new backend system.
|
|
42
|
+
|
|
43
|
+
**Summary:**
|
|
44
|
+
|
|
45
|
+
- new:
|
|
46
|
+
`EventsService`, `eventsServiceRef`, `TestEventsService`
|
|
47
|
+
- deprecated:
|
|
48
|
+
`EventBroker`, `EventPublisher`, `EventSubscriber`, `DefaultEventBroker`, `EventsBackend`,
|
|
49
|
+
most parts of `EventsExtensionPoint` (alpha),
|
|
50
|
+
`TestEventBroker`, `TestEventPublisher`, `TestEventSubscriber`
|
|
51
|
+
|
|
52
|
+
Add the `eventsServiceRef` as dependency to your backend plugins
|
|
53
|
+
or backend plugin modules.
|
|
54
|
+
|
|
55
|
+
**Details:**
|
|
56
|
+
|
|
57
|
+
The previous implementation using the `EventsExtensionPoint` was added in the early stages
|
|
58
|
+
of the new backend system and does not respect the plugin isolation.
|
|
59
|
+
This made it not compatible anymore with the new backend system.
|
|
60
|
+
|
|
61
|
+
Additionally, the previous interfaces had some room for simplification,
|
|
62
|
+
supporting less exposure of internal concerns as well.
|
|
63
|
+
|
|
64
|
+
Hereby, this change adds a new `EventsService` interface as replacement for the now deprecated `EventBroker`.
|
|
65
|
+
The new interface does not require any `EventPublisher` or `EventSubscriber` interfaces anymore.
|
|
66
|
+
Instead, it is expected that the `EventsService` gets passed into publishers and subscribers,
|
|
67
|
+
and used internally. There is no need to expose anything of that at their own interfaces.
|
|
68
|
+
|
|
69
|
+
Most parts of `EventsExtensionPoint` (alpha) are deprecated as well and were not usable
|
|
70
|
+
(by other plugins or their modules) anyway.
|
|
71
|
+
|
|
72
|
+
The `DefaultEventBroker` implementation is deprecated and wraps the new `DefaultEventsService` implementation.
|
|
73
|
+
Optionally, an instance can be passed as argument to allow mixed setups to operate alongside.
|
|
74
|
+
|
|
16
75
|
- Updated dependencies
|
|
17
|
-
- @backstage/
|
|
18
|
-
- @backstage/backend-
|
|
19
|
-
- @backstage/plugin-
|
|
76
|
+
- @backstage/plugin-events-node@0.3.0-next.0
|
|
77
|
+
- @backstage/backend-common@0.21.3-next.0
|
|
78
|
+
- @backstage/backend-plugin-api@0.6.13-next.0
|
|
79
|
+
- @backstage/config@1.1.2-next.0
|
|
20
80
|
|
|
21
81
|
## 0.2.19
|
|
22
82
|
|
package/README.md
CHANGED
|
@@ -1,137 +1,84 @@
|
|
|
1
|
-
# events-backend
|
|
1
|
+
# `@backstage/plugin-events-backend`
|
|
2
2
|
|
|
3
3
|
Welcome to the events-backend backend plugin!
|
|
4
4
|
|
|
5
|
-
This
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Additionally, it uses a simple in-process implementation for
|
|
10
|
-
the `EventBroker` by default which you can replace with a more sophisticated
|
|
11
|
-
implementation of your choice as you need (e.g., via module).
|
|
12
|
-
|
|
13
|
-
Some of these (non-exhaustive) may provide added persistence,
|
|
14
|
-
or use external systems like AWS EventBridge, AWS SNS, Kafka, etc.
|
|
5
|
+
This package is based on [events-node](../events-node) and its `eventsServiceRef`
|
|
6
|
+
that is at the core of the event support.
|
|
7
|
+
It provides an `eventsPlugin` (exported as `default`).
|
|
15
8
|
|
|
16
9
|
By default, the plugin ships with support to receive events via HTTP endpoints
|
|
17
|
-
`POST /api/events/http/{topic}` and will publish these
|
|
18
|
-
|
|
10
|
+
`POST /api/events/http/{topic}` and will publish these to the `EventsService`.
|
|
11
|
+
|
|
12
|
+
HTTP ingresses can be enabled by config, or using the extension point
|
|
13
|
+
of the `eventsPlugin`.
|
|
14
|
+
Additionally, the latter allows to add a request validator
|
|
15
|
+
(e.g., signature verification).
|
|
19
16
|
|
|
20
17
|
## Installation
|
|
21
18
|
|
|
22
19
|
```bash
|
|
23
20
|
# From your Backstage root directory
|
|
24
|
-
yarn --cwd packages/backend add @backstage/plugin-events-backend
|
|
21
|
+
yarn --cwd packages/backend add @backstage/plugin-events-backend
|
|
25
22
|
```
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
```ts title="packages/backend/src/index.ts"
|
|
30
|
-
backend.add(import('@backstage/plugin-events-backend/alpha'));
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Add to backend (old)
|
|
34
|
-
|
|
35
|
-
#### Event Broker
|
|
36
|
-
|
|
37
|
-
First you will need to add and implementation of the `EventBroker` interface to the backend plugin environment.
|
|
38
|
-
This will allow event broker instance any backend plugins to publish and subscribe to events in order to communicate
|
|
39
|
-
between them.
|
|
40
|
-
|
|
41
|
-
Add the following to `makeCreateEnv`
|
|
42
|
-
|
|
43
|
-
```diff
|
|
24
|
+
```ts
|
|
44
25
|
// packages/backend/src/index.ts
|
|
45
|
-
|
|
46
|
-
+ const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' }));
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Then update plugin environment to include the event broker.
|
|
50
|
-
|
|
51
|
-
```diff
|
|
52
|
-
// packages/backend/src/types.ts
|
|
53
|
-
+ import { EventBroker } from '@backstage/plugin-events-node';
|
|
54
|
-
+ eventBroker: EventBroker;
|
|
26
|
+
backend.add(import('@backstage/plugin-events-backend/alpha'));
|
|
55
27
|
```
|
|
56
28
|
|
|
57
|
-
|
|
29
|
+
### Legacy Backend System
|
|
58
30
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
```typescript jsx
|
|
65
|
-
export default async function createPlugin(
|
|
66
|
-
env: PluginEnvironment,
|
|
67
|
-
): Promise<Router> {
|
|
68
|
-
env.eventBroker.publish({
|
|
69
|
-
topic: 'publish.example',
|
|
70
|
-
eventPayload: { message: 'Hello, World!' },
|
|
71
|
-
metadata: {},
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Here is an example of a plugin subscribing to a topic.
|
|
31
|
+
```ts
|
|
32
|
+
// packages/backend/src/plugins/events.ts
|
|
33
|
+
import { HttpPostIngressEventPublisher } from '@backstage/plugin-events-backend';
|
|
34
|
+
import { Router } from 'express';
|
|
35
|
+
import { PluginEnvironment } from '../types';
|
|
77
36
|
|
|
78
|
-
```typescript jsx
|
|
79
37
|
export default async function createPlugin(
|
|
80
38
|
env: PluginEnvironment,
|
|
81
39
|
): Promise<Router> {
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
supportsEventTopics: ['publish.example'],
|
|
85
|
-
onEvent: async (params: EventParams) => {
|
|
86
|
-
env.logger.info(`receieved ${params.topic} event`);
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
]);
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
#### Implementing an `EventSubscriber` class
|
|
94
|
-
|
|
95
|
-
More complex solutions might need the creation of a class that implements the `EventSubscriber` interface. e.g.
|
|
96
|
-
|
|
97
|
-
```typescript jsx
|
|
98
|
-
import { EventSubscriber } from './EventSubscriber';
|
|
40
|
+
const eventsRouter = Router();
|
|
99
41
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
42
|
+
const http = HttpPostIngressEventPublisher.fromConfig({
|
|
43
|
+
config: env.config,
|
|
44
|
+
events: env.events,
|
|
45
|
+
logger: env.logger,
|
|
46
|
+
});
|
|
47
|
+
http.bind(eventsRouter);
|
|
106
48
|
|
|
107
|
-
|
|
108
|
-
env.logger.info(`receieved ${params.topic} event`);
|
|
109
|
-
}
|
|
49
|
+
return eventsRouter;
|
|
110
50
|
}
|
|
111
51
|
```
|
|
112
52
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
The events backend plugin provides a router to handler http events and publish the http requests onto the event
|
|
116
|
-
broker.
|
|
53
|
+
### Event-based Entity Providers
|
|
117
54
|
|
|
118
|
-
|
|
119
|
-
|
|
55
|
+
You can implement the `EventSubscriber` interface on an `EntityProviders` to allow it to handle events from other plugins e.g. the event backend plugin
|
|
56
|
+
mentioned above.
|
|
120
57
|
|
|
121
|
-
|
|
58
|
+
Assuming you have configured the `eventBroker` into the `PluginEnvironment` you can pass the broker to the entity provider for it to subscribe.
|
|
122
59
|
|
|
123
60
|
```diff
|
|
124
|
-
// packages/backend/src/
|
|
125
|
-
|
|
126
|
-
+import
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
61
|
+
// packages/backend/src/plugins/catalog.ts
|
|
62
|
+
import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
|
|
63
|
+
+import { DemoEventBasedEntityProvider } from './DemoEventBasedEntityProvider';
|
|
64
|
+
import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend';
|
|
65
|
+
import { Router } from 'express';
|
|
66
|
+
import { PluginEnvironment } from '../types';
|
|
67
|
+
|
|
68
|
+
export default async function createPlugin(
|
|
69
|
+
env: PluginEnvironment,
|
|
70
|
+
): Promise<Router> {
|
|
71
|
+
const builder = await CatalogBuilder.create(env);
|
|
72
|
+
builder.addProcessor(new ScaffolderEntitiesProcessor());
|
|
73
|
+
+ const demoProvider = new DemoEventBasedEntityProvider({ logger: env.logger, topics: ['example'], eventBroker: env.eventBroker });
|
|
74
|
+
+ builder.addEntityProvider(demoProvider);
|
|
75
|
+
const { processingEngine, router } = await builder.build();
|
|
76
|
+
await processingEngine.start();
|
|
77
|
+
return router;
|
|
78
|
+
}
|
|
132
79
|
```
|
|
133
80
|
|
|
134
|
-
|
|
81
|
+
## Configuration
|
|
135
82
|
|
|
136
83
|
In order to create HTTP endpoints to receive events for a certain
|
|
137
84
|
topic, you need to add them at your configuration:
|
|
@@ -161,57 +108,18 @@ in combination with suitable event subscribers.
|
|
|
161
108
|
|
|
162
109
|
However, it is not limited to these use cases.
|
|
163
110
|
|
|
164
|
-
### Event-based Entity Providers
|
|
165
|
-
|
|
166
|
-
You can implement the `EventSubscriber` interface on an `EntityProviders` to allow it to handle events from other plugins e.g. the event backend plugin
|
|
167
|
-
mentioned above.
|
|
168
|
-
|
|
169
|
-
Assuming you have configured the `eventBroker` into the `PluginEnvironment` you can pass the broker to the entity provider for it to subscribe.
|
|
170
|
-
|
|
171
|
-
```diff
|
|
172
|
-
// packages/backend/src/plugins/catalog.ts
|
|
173
|
-
import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
|
|
174
|
-
+import { DemoEventBasedEntityProvider } from './DemoEventBasedEntityProvider';
|
|
175
|
-
import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend';
|
|
176
|
-
import { Router } from 'express';
|
|
177
|
-
import { PluginEnvironment } from '../types';
|
|
178
|
-
|
|
179
|
-
export default async function createPlugin(
|
|
180
|
-
env: PluginEnvironment,
|
|
181
|
-
): Promise<Router> {
|
|
182
|
-
const builder = await CatalogBuilder.create(env);
|
|
183
|
-
builder.addProcessor(new ScaffolderEntitiesProcessor());
|
|
184
|
-
+ const demoProvider = new DemoEventBasedEntityProvider({ logger: env.logger, topics: ['example'], eventBroker: env.eventBroker });
|
|
185
|
-
+ builder.addEntityProvider(demoProvider);
|
|
186
|
-
const { processingEngine, router } = await builder.build();
|
|
187
|
-
await processingEngine.start();
|
|
188
|
-
return router;
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
111
|
## Use Cases
|
|
193
112
|
|
|
194
|
-
###
|
|
195
|
-
|
|
196
|
-
Example using the `EventsBackend`:
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
new EventsBackend(env.logger)
|
|
200
|
-
.setEventBroker(yourEventBroker)
|
|
201
|
-
// [...]
|
|
202
|
-
.start();
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Example using a module:
|
|
113
|
+
### Request Validator
|
|
206
114
|
|
|
207
115
|
```ts
|
|
208
|
-
import { eventsExtensionPoint } from '@backstage/plugin-events-node';
|
|
116
|
+
import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha';
|
|
209
117
|
|
|
210
118
|
// [...]
|
|
211
119
|
|
|
212
|
-
export const
|
|
120
|
+
export const eventsModuleYourFeature = createBackendModule({
|
|
213
121
|
pluginId: 'events',
|
|
214
|
-
moduleId: 'your-
|
|
122
|
+
moduleId: 'your-feature',
|
|
215
123
|
register(env) {
|
|
216
124
|
// [...]
|
|
217
125
|
env.registerInit({
|
|
@@ -222,22 +130,22 @@ export const yourModuleEventsModule = createBackendModule({
|
|
|
222
130
|
},
|
|
223
131
|
async init({ /* ... */ events /*, ... */ }) {
|
|
224
132
|
// [...]
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
133
|
+
events.addHttpPostIngress({
|
|
134
|
+
topic: 'your-topic',
|
|
135
|
+
validator: yourValidator,
|
|
136
|
+
});
|
|
228
137
|
},
|
|
229
138
|
});
|
|
230
139
|
},
|
|
231
140
|
});
|
|
232
141
|
```
|
|
233
142
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Example using the `EventsBackend`:
|
|
143
|
+
#### Legacy Backend System
|
|
237
144
|
|
|
238
145
|
```ts
|
|
239
146
|
const http = HttpPostIngressEventPublisher.fromConfig({
|
|
240
147
|
config: env.config,
|
|
148
|
+
events: env.events,
|
|
241
149
|
ingresses: {
|
|
242
150
|
yourTopic: {
|
|
243
151
|
validator: yourValidator,
|
|
@@ -246,39 +154,4 @@ const http = HttpPostIngressEventPublisher.fromConfig({
|
|
|
246
154
|
logger: env.logger,
|
|
247
155
|
});
|
|
248
156
|
http.bind(router);
|
|
249
|
-
|
|
250
|
-
await new EventsBackend(env.logger)
|
|
251
|
-
.addPublishers(http)
|
|
252
|
-
// [...]
|
|
253
|
-
.start();
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
Example using a module:
|
|
257
|
-
|
|
258
|
-
```ts
|
|
259
|
-
import { eventsExtensionPoint } from '@backstage/plugin-events-node';
|
|
260
|
-
|
|
261
|
-
// [...]
|
|
262
|
-
|
|
263
|
-
export const eventsModuleYourFeature = createBackendModule({
|
|
264
|
-
pluginId: 'events',
|
|
265
|
-
moduleId: 'your-feature',
|
|
266
|
-
register(env) {
|
|
267
|
-
// [...]
|
|
268
|
-
env.registerInit({
|
|
269
|
-
deps: {
|
|
270
|
-
// [...]
|
|
271
|
-
events: eventsExtensionPoint,
|
|
272
|
-
// [...]
|
|
273
|
-
},
|
|
274
|
-
async init({ /* ... */ events /*, ... */ }) {
|
|
275
|
-
// [...]
|
|
276
|
-
events.addHttpPostIngress({
|
|
277
|
-
topic: 'your-topic',
|
|
278
|
-
validator: yourValidator,
|
|
279
|
-
});
|
|
280
|
-
},
|
|
281
|
-
});
|
|
282
|
-
},
|
|
283
|
-
});
|
|
284
157
|
```
|
package/alpha/package.json
CHANGED
package/dist/alpha.cjs.js
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
6
|
-
var backendCommon = require('@backstage/backend-common');
|
|
7
6
|
var alpha = require('@backstage/plugin-events-node/alpha');
|
|
8
|
-
var
|
|
7
|
+
var pluginEventsNode = require('@backstage/plugin-events-node');
|
|
9
8
|
var Router = require('express-promise-router');
|
|
9
|
+
var HttpPostIngressEventPublisher = require('./cjs/HttpPostIngressEventPublisher-a08684c9.cjs.js');
|
|
10
|
+
require('@backstage/backend-common');
|
|
10
11
|
require('express');
|
|
11
12
|
|
|
12
13
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -26,48 +27,34 @@ var __privateAdd = (obj, member, value) => {
|
|
|
26
27
|
throw TypeError("Cannot add the same private member more than once");
|
|
27
28
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
28
29
|
};
|
|
29
|
-
var
|
|
30
|
-
__accessCheck(obj, member, "write to private field");
|
|
31
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
32
|
-
return value;
|
|
33
|
-
};
|
|
34
|
-
var _eventBroker, _httpPostIngresses, _publishers, _subscribers;
|
|
30
|
+
var _httpPostIngresses;
|
|
35
31
|
class EventsExtensionPointImpl {
|
|
36
32
|
constructor() {
|
|
37
|
-
__privateAdd(this, _eventBroker, void 0);
|
|
38
33
|
__privateAdd(this, _httpPostIngresses, []);
|
|
39
|
-
__privateAdd(this, _publishers, []);
|
|
40
|
-
__privateAdd(this, _subscribers, []);
|
|
41
34
|
}
|
|
42
|
-
setEventBroker(
|
|
43
|
-
|
|
35
|
+
setEventBroker(_) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
"setEventBroker is not supported anymore; use eventsServiceRef instead"
|
|
38
|
+
);
|
|
44
39
|
}
|
|
45
|
-
addPublishers(
|
|
46
|
-
|
|
40
|
+
addPublishers(_) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
"addPublishers is not supported anymore; use EventsService instead"
|
|
43
|
+
);
|
|
47
44
|
}
|
|
48
|
-
addSubscribers(
|
|
49
|
-
|
|
45
|
+
addSubscribers(_) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"addSubscribers is not supported anymore; use EventsService instead"
|
|
48
|
+
);
|
|
50
49
|
}
|
|
51
50
|
addHttpPostIngress(options) {
|
|
52
51
|
__privateGet(this, _httpPostIngresses).push(options);
|
|
53
52
|
}
|
|
54
|
-
get eventBroker() {
|
|
55
|
-
return __privateGet(this, _eventBroker);
|
|
56
|
-
}
|
|
57
|
-
get publishers() {
|
|
58
|
-
return __privateGet(this, _publishers);
|
|
59
|
-
}
|
|
60
|
-
get subscribers() {
|
|
61
|
-
return __privateGet(this, _subscribers);
|
|
62
|
-
}
|
|
63
53
|
get httpPostIngresses() {
|
|
64
54
|
return __privateGet(this, _httpPostIngresses);
|
|
65
55
|
}
|
|
66
56
|
}
|
|
67
|
-
_eventBroker = new WeakMap();
|
|
68
57
|
_httpPostIngresses = new WeakMap();
|
|
69
|
-
_publishers = new WeakMap();
|
|
70
|
-
_subscribers = new WeakMap();
|
|
71
58
|
const eventsPlugin = backendPluginApi.createBackendPlugin({
|
|
72
59
|
pluginId: "events",
|
|
73
60
|
register(env) {
|
|
@@ -76,12 +63,11 @@ const eventsPlugin = backendPluginApi.createBackendPlugin({
|
|
|
76
63
|
env.registerInit({
|
|
77
64
|
deps: {
|
|
78
65
|
config: backendPluginApi.coreServices.rootConfig,
|
|
66
|
+
events: pluginEventsNode.eventsServiceRef,
|
|
79
67
|
logger: backendPluginApi.coreServices.logger,
|
|
80
68
|
router: backendPluginApi.coreServices.httpRouter
|
|
81
69
|
},
|
|
82
|
-
async init({ config, logger, router }) {
|
|
83
|
-
var _a;
|
|
84
|
-
const winstonLogger = backendCommon.loggerToWinstonLogger(logger);
|
|
70
|
+
async init({ config, events, logger, router }) {
|
|
85
71
|
const ingresses = Object.fromEntries(
|
|
86
72
|
extensionPoint.httpPostIngresses.map((ingress) => [
|
|
87
73
|
ingress.topic,
|
|
@@ -90,15 +76,13 @@ const eventsPlugin = backendPluginApi.createBackendPlugin({
|
|
|
90
76
|
);
|
|
91
77
|
const http = HttpPostIngressEventPublisher.HttpPostIngressEventPublisher.fromConfig({
|
|
92
78
|
config,
|
|
79
|
+
events,
|
|
93
80
|
ingresses,
|
|
94
|
-
logger
|
|
81
|
+
logger
|
|
95
82
|
});
|
|
96
83
|
const eventsRouter = Router__default["default"]();
|
|
97
84
|
http.bind(eventsRouter);
|
|
98
85
|
router.use(eventsRouter);
|
|
99
|
-
const eventBroker = (_a = extensionPoint.eventBroker) != null ? _a : new HttpPostIngressEventPublisher.DefaultEventBroker(winstonLogger);
|
|
100
|
-
eventBroker.subscribe(extensionPoint.subscribers);
|
|
101
|
-
[extensionPoint.publishers, http].flat().forEach((publisher) => publisher.setEventBroker(eventBroker));
|
|
102
86
|
}
|
|
103
87
|
});
|
|
104
88
|
}
|
package/dist/alpha.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.cjs.js","sources":["../src/service/EventsPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport {
|
|
1
|
+
{"version":3,"file":"alpha.cjs.js","sources":["../src/service/EventsPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport {\n eventsExtensionPoint,\n EventsExtensionPoint,\n} from '@backstage/plugin-events-node/alpha';\nimport {\n eventsServiceRef,\n HttpPostIngressOptions,\n} from '@backstage/plugin-events-node';\nimport Router from 'express-promise-router';\nimport { HttpPostIngressEventPublisher } from './http';\n\nclass EventsExtensionPointImpl implements EventsExtensionPoint {\n #httpPostIngresses: HttpPostIngressOptions[] = [];\n\n setEventBroker(_: any): void {\n throw new Error(\n 'setEventBroker is not supported anymore; use eventsServiceRef instead',\n );\n }\n\n addPublishers(_: any): void {\n throw new Error(\n 'addPublishers is not supported anymore; use EventsService instead',\n );\n }\n\n addSubscribers(_: any): void {\n throw new Error(\n 'addSubscribers is not supported anymore; use EventsService instead',\n );\n }\n\n addHttpPostIngress(options: HttpPostIngressOptions) {\n this.#httpPostIngresses.push(options);\n }\n\n get httpPostIngresses() {\n return this.#httpPostIngresses;\n }\n}\n\n/**\n * Events plugin\n *\n * @alpha\n */\nexport const eventsPlugin = createBackendPlugin({\n pluginId: 'events',\n register(env) {\n const extensionPoint = new EventsExtensionPointImpl();\n env.registerExtensionPoint(eventsExtensionPoint, extensionPoint);\n\n env.registerInit({\n deps: {\n config: coreServices.rootConfig,\n events: eventsServiceRef,\n logger: coreServices.logger,\n router: coreServices.httpRouter,\n },\n async init({ config, events, logger, router }) {\n const ingresses = Object.fromEntries(\n extensionPoint.httpPostIngresses.map(ingress => [\n ingress.topic,\n ingress as Omit<HttpPostIngressOptions, 'topic'>,\n ]),\n );\n\n const http = HttpPostIngressEventPublisher.fromConfig({\n config,\n events,\n ingresses,\n logger,\n });\n const eventsRouter = Router();\n http.bind(eventsRouter);\n router.use(eventsRouter);\n },\n });\n },\n});\n"],"names":["createBackendPlugin","eventsExtensionPoint","coreServices","eventsServiceRef","HttpPostIngressEventPublisher","Router"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,kBAAA,CAAA;AA+BA,MAAM,wBAAyD,CAAA;AAAA,EAA/D,WAAA,GAAA;AACE,IAAA,YAAA,CAAA,IAAA,EAAA,kBAAA,EAA+C,EAAC,CAAA,CAAA;AAAA,GAAA;AAAA,EAEhD,eAAe,CAAc,EAAA;AAC3B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,uEAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,cAAc,CAAc,EAAA;AAC1B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,mEAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,eAAe,CAAc,EAAA;AAC3B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,oEAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,mBAAmB,OAAiC,EAAA;AAClD,IAAK,YAAA,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAmB,KAAK,OAAO,CAAA,CAAA;AAAA,GACtC;AAAA,EAEA,IAAI,iBAAoB,GAAA;AACtB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAA;AAAA,GACd;AACF,CAAA;AA3BE,kBAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAkCK,MAAM,eAAeA,oCAAoB,CAAA;AAAA,EAC9C,QAAU,EAAA,QAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAM,MAAA,cAAA,GAAiB,IAAI,wBAAyB,EAAA,CAAA;AACpD,IAAI,GAAA,CAAA,sBAAA,CAAuBC,4BAAsB,cAAc,CAAA,CAAA;AAE/D,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,MAAQ,EAAAC,iCAAA;AAAA,QACR,QAAQD,6BAAa,CAAA,MAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,UAAA;AAAA,OACvB;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,QAAQ,MAAQ,EAAA,MAAA,EAAQ,QAAU,EAAA;AAC7C,QAAA,MAAM,YAAY,MAAO,CAAA,WAAA;AAAA,UACvB,cAAA,CAAe,iBAAkB,CAAA,GAAA,CAAI,CAAW,OAAA,KAAA;AAAA,YAC9C,OAAQ,CAAA,KAAA;AAAA,YACR,OAAA;AAAA,WACD,CAAA;AAAA,SACH,CAAA;AAEA,QAAM,MAAA,IAAA,GAAOE,4DAA8B,UAAW,CAAA;AAAA,UACpD,MAAA;AAAA,UACA,MAAA;AAAA,UACA,SAAA;AAAA,UACA,MAAA;AAAA,SACD,CAAA,CAAA;AACD,QAAA,MAAM,eAAeC,0BAAO,EAAA,CAAA;AAC5B,QAAA,IAAA,CAAK,KAAK,YAAY,CAAA,CAAA;AACtB,QAAA,MAAA,CAAO,IAAI,YAAY,CAAA,CAAA;AAAA,OACzB;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
|
|
@@ -9,49 +9,6 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
9
9
|
var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
|
|
10
10
|
var Router__default = /*#__PURE__*/_interopDefaultLegacy(Router);
|
|
11
11
|
|
|
12
|
-
var __defProp$1 = Object.defineProperty;
|
|
13
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
-
var __publicField$1 = (obj, key, value) => {
|
|
15
|
-
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
16
|
-
return value;
|
|
17
|
-
};
|
|
18
|
-
class DefaultEventBroker {
|
|
19
|
-
constructor(logger) {
|
|
20
|
-
this.logger = logger;
|
|
21
|
-
__publicField$1(this, "subscribers", {});
|
|
22
|
-
}
|
|
23
|
-
async publish(params) {
|
|
24
|
-
var _a;
|
|
25
|
-
this.logger.debug(
|
|
26
|
-
`Event received: topic=${params.topic}, metadata=${JSON.stringify(
|
|
27
|
-
params.metadata
|
|
28
|
-
)}, payload=${JSON.stringify(params.eventPayload)}`
|
|
29
|
-
);
|
|
30
|
-
const subscribed = (_a = this.subscribers[params.topic]) != null ? _a : [];
|
|
31
|
-
await Promise.all(
|
|
32
|
-
subscribed.map(async (subscriber) => {
|
|
33
|
-
try {
|
|
34
|
-
await subscriber.onEvent(params);
|
|
35
|
-
} catch (error) {
|
|
36
|
-
this.logger.error(
|
|
37
|
-
`Subscriber "${subscriber.constructor.name}" failed to process event`,
|
|
38
|
-
error
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
subscribe(...subscribers) {
|
|
45
|
-
subscribers.flat().forEach((subscriber) => {
|
|
46
|
-
subscriber.supportsEventTopics().forEach((topic) => {
|
|
47
|
-
var _a;
|
|
48
|
-
this.subscribers[topic] = (_a = this.subscribers[topic]) != null ? _a : [];
|
|
49
|
-
this.subscribers[topic].push(subscriber);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
12
|
var __accessCheck = (obj, member, msg) => {
|
|
56
13
|
if (!member.has(obj))
|
|
57
14
|
throw TypeError("Cannot " + msg);
|
|
@@ -91,17 +48,11 @@ class RequestValidationContextImpl {
|
|
|
91
48
|
}
|
|
92
49
|
_rejectionDetails = new WeakMap();
|
|
93
50
|
|
|
94
|
-
var __defProp = Object.defineProperty;
|
|
95
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
96
|
-
var __publicField = (obj, key, value) => {
|
|
97
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
98
|
-
return value;
|
|
99
|
-
};
|
|
100
51
|
class HttpPostIngressEventPublisher {
|
|
101
|
-
constructor(logger, ingresses) {
|
|
52
|
+
constructor(events, logger, ingresses) {
|
|
53
|
+
this.events = events;
|
|
102
54
|
this.logger = logger;
|
|
103
55
|
this.ingresses = ingresses;
|
|
104
|
-
__publicField(this, "eventBroker");
|
|
105
56
|
}
|
|
106
57
|
static fromConfig(env) {
|
|
107
58
|
var _a, _b;
|
|
@@ -112,14 +63,11 @@ class HttpPostIngressEventPublisher {
|
|
|
112
63
|
ingresses[topic] = {};
|
|
113
64
|
}
|
|
114
65
|
});
|
|
115
|
-
return new HttpPostIngressEventPublisher(env.logger, ingresses);
|
|
66
|
+
return new HttpPostIngressEventPublisher(env.events, env.logger, ingresses);
|
|
116
67
|
}
|
|
117
68
|
bind(router) {
|
|
118
69
|
router.use("/http", this.createRouter(this.ingresses));
|
|
119
70
|
}
|
|
120
|
-
async setEventBroker(eventBroker) {
|
|
121
|
-
this.eventBroker = eventBroker;
|
|
122
|
-
}
|
|
123
71
|
createRouter(ingresses) {
|
|
124
72
|
const router = Router__default["default"]();
|
|
125
73
|
router.use(express__default["default"].json());
|
|
@@ -143,7 +91,7 @@ class HttpPostIngressEventPublisher {
|
|
|
143
91
|
return;
|
|
144
92
|
}
|
|
145
93
|
const eventPayload = request.body;
|
|
146
|
-
await this.
|
|
94
|
+
await this.events.publish({
|
|
147
95
|
topic,
|
|
148
96
|
eventPayload,
|
|
149
97
|
metadata: request.headers
|
|
@@ -154,6 +102,5 @@ class HttpPostIngressEventPublisher {
|
|
|
154
102
|
}
|
|
155
103
|
}
|
|
156
104
|
|
|
157
|
-
exports.DefaultEventBroker = DefaultEventBroker;
|
|
158
105
|
exports.HttpPostIngressEventPublisher = HttpPostIngressEventPublisher;
|
|
159
|
-
//# sourceMappingURL=HttpPostIngressEventPublisher-
|
|
106
|
+
//# sourceMappingURL=HttpPostIngressEventPublisher-a08684c9.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpPostIngressEventPublisher-a08684c9.cjs.js","sources":["../../src/service/http/validation/RequestValidationContextImpl.ts","../../src/service/http/HttpPostIngressEventPublisher.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n RequestRejectionDetails,\n RequestValidationContext,\n} from '@backstage/plugin-events-node';\n\nexport class RequestValidationContextImpl implements RequestValidationContext {\n #rejectionDetails: RequestRejectionDetails | undefined;\n\n reject(details?: Partial<RequestRejectionDetails>): void {\n this.#rejectionDetails = {\n status: details?.status ?? 403,\n payload: details?.payload ?? {},\n };\n }\n\n wasRejected(): boolean {\n return this.#rejectionDetails !== undefined;\n }\n\n get rejectionDetails() {\n return this.#rejectionDetails;\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { errorHandler } from '@backstage/backend-common';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport {\n EventsService,\n HttpPostIngressOptions,\n RequestValidator,\n} from '@backstage/plugin-events-node';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { RequestValidationContextImpl } from './validation';\n\n/**\n * Publishes events received from their origin (e.g., webhook events from an SCM system)\n * via HTTP POST endpoint and passes the request body as event payload to the registered subscribers.\n *\n * @public\n */\n// TODO(pjungermann): add prom metrics? (see plugins/catalog-backend/src/util/metrics.ts, etc.)\nexport class HttpPostIngressEventPublisher {\n static fromConfig(env: {\n config: Config;\n events: EventsService;\n ingresses?: { [topic: string]: Omit<HttpPostIngressOptions, 'topic'> };\n logger: LoggerService;\n }): HttpPostIngressEventPublisher {\n const topics =\n env.config.getOptionalStringArray('events.http.topics') ?? [];\n\n const ingresses = env.ingresses ?? {};\n topics.forEach(topic => {\n // don't overwrite topic settings\n // (e.g., added at the config as well as argument)\n if (!ingresses[topic]) {\n ingresses[topic] = {};\n }\n });\n\n return new HttpPostIngressEventPublisher(env.events, env.logger, ingresses);\n }\n\n private constructor(\n private readonly events: EventsService,\n private readonly logger: LoggerService,\n private readonly ingresses: {\n [topic: string]: Omit<HttpPostIngressOptions, 'topic'>;\n },\n ) {}\n\n bind(router: express.Router): void {\n router.use('/http', this.createRouter(this.ingresses));\n }\n\n private createRouter(ingresses: {\n [topic: string]: Omit<HttpPostIngressOptions, 'topic'>;\n }): express.Router {\n const router = Router();\n router.use(express.json());\n\n Object.keys(ingresses).forEach(topic =>\n this.addRouteForTopic(router, topic, ingresses[topic].validator),\n );\n\n router.use(errorHandler());\n return router;\n }\n\n private addRouteForTopic(\n router: express.Router,\n topic: string,\n validator?: RequestValidator,\n ): void {\n const path = `/${topic}`;\n\n router.post(path, async (request, response) => {\n const requestDetails = {\n body: request.body,\n headers: request.headers,\n };\n const context = new RequestValidationContextImpl();\n await validator?.(requestDetails, context);\n if (context.wasRejected()) {\n response\n .status(context.rejectionDetails!.status)\n .json(context.rejectionDetails!.payload);\n return;\n }\n\n const eventPayload = request.body;\n await this.events.publish({\n topic,\n eventPayload,\n metadata: request.headers,\n });\n\n response.status(202).json({ status: 'accepted' });\n });\n\n // TODO(pjungermann): We don't really know the externally defined path prefix here,\n // however it is more useful for users to have it. Is there a better way?\n this.logger.info(`Registered /api/events/http${path} to receive events`);\n }\n}\n"],"names":["Router","express","errorHandler"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,iBAAA,CAAA;AAqBO,MAAM,4BAAiE,CAAA;AAAA,EAAvE,WAAA,GAAA;AACL,IAAA,YAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAAA,GAAA;AAAA,EAEA,OAAO,OAAkD,EAAA;AAxB3D,IAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAyBI,IAAA,YAAA,CAAA,IAAA,EAAK,iBAAoB,EAAA;AAAA,MACvB,MAAA,EAAA,CAAQ,EAAS,GAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,MAAA,KAAT,IAAmB,GAAA,EAAA,GAAA,GAAA;AAAA,MAC3B,OAAS,EAAA,CAAA,EAAA,GAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,OAAT,KAAA,IAAA,GAAA,EAAA,GAAoB,EAAC;AAAA,KAChC,CAAA,CAAA;AAAA,GACF;AAAA,EAEA,WAAuB,GAAA;AACrB,IAAA,OAAO,mBAAK,iBAAsB,CAAA,KAAA,KAAA,CAAA,CAAA;AAAA,GACpC;AAAA,EAEA,IAAI,gBAAmB,GAAA;AACrB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,iBAAA,CAAA,CAAA;AAAA,GACd;AACF,CAAA;AAhBE,iBAAA,GAAA,IAAA,OAAA,EAAA;;ACaK,MAAM,6BAA8B,CAAA;AAAA,EAsBjC,WAAA,CACW,MACA,EAAA,MAAA,EACA,SAGjB,EAAA;AALiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA,CAAA;AAAA,GAGhB;AAAA,EA3BH,OAAO,WAAW,GAKgB,EAAA;AAzCpC,IAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AA0CI,IAAA,MAAM,UACJ,EAAI,GAAA,GAAA,CAAA,MAAA,CAAO,uBAAuB,oBAAoB,CAAA,KAAtD,YAA2D,EAAC,CAAA;AAE9D,IAAA,MAAM,SAAY,GAAA,CAAA,EAAA,GAAA,GAAA,CAAI,SAAJ,KAAA,IAAA,GAAA,EAAA,GAAiB,EAAC,CAAA;AACpC,IAAA,MAAA,CAAO,QAAQ,CAAS,KAAA,KAAA;AAGtB,MAAI,IAAA,CAAC,SAAU,CAAA,KAAK,CAAG,EAAA;AACrB,QAAU,SAAA,CAAA,KAAK,IAAI,EAAC,CAAA;AAAA,OACtB;AAAA,KACD,CAAA,CAAA;AAED,IAAA,OAAO,IAAI,6BAA8B,CAAA,GAAA,CAAI,MAAQ,EAAA,GAAA,CAAI,QAAQ,SAAS,CAAA,CAAA;AAAA,GAC5E;AAAA,EAUA,KAAK,MAA8B,EAAA;AACjC,IAAA,MAAA,CAAO,IAAI,OAAS,EAAA,IAAA,CAAK,YAAa,CAAA,IAAA,CAAK,SAAS,CAAC,CAAA,CAAA;AAAA,GACvD;AAAA,EAEQ,aAAa,SAEF,EAAA;AACjB,IAAA,MAAM,SAASA,0BAAO,EAAA,CAAA;AACtB,IAAO,MAAA,CAAA,GAAA,CAAIC,2BAAQ,CAAA,IAAA,EAAM,CAAA,CAAA;AAEzB,IAAO,MAAA,CAAA,IAAA,CAAK,SAAS,CAAE,CAAA,OAAA;AAAA,MAAQ,CAAA,KAAA,KAC7B,KAAK,gBAAiB,CAAA,MAAA,EAAQ,OAAO,SAAU,CAAA,KAAK,EAAE,SAAS,CAAA;AAAA,KACjE,CAAA;AAEA,IAAO,MAAA,CAAA,GAAA,CAAIC,4BAAc,CAAA,CAAA;AACzB,IAAO,OAAA,MAAA,CAAA;AAAA,GACT;AAAA,EAEQ,gBAAA,CACN,MACA,EAAA,KAAA,EACA,SACM,EAAA;AACN,IAAM,MAAA,IAAA,GAAO,IAAI,KAAK,CAAA,CAAA,CAAA;AAEtB,IAAA,MAAA,CAAO,IAAK,CAAA,IAAA,EAAM,OAAO,OAAA,EAAS,QAAa,KAAA;AAC7C,MAAA,MAAM,cAAiB,GAAA;AAAA,QACrB,MAAM,OAAQ,CAAA,IAAA;AAAA,QACd,SAAS,OAAQ,CAAA,OAAA;AAAA,OACnB,CAAA;AACA,MAAM,MAAA,OAAA,GAAU,IAAI,4BAA6B,EAAA,CAAA;AACjD,MAAA,OAAM,uCAAY,cAAgB,EAAA,OAAA,CAAA,CAAA,CAAA;AAClC,MAAI,IAAA,OAAA,CAAQ,aAAe,EAAA;AACzB,QACG,QAAA,CAAA,MAAA,CAAO,QAAQ,gBAAkB,CAAA,MAAM,EACvC,IAAK,CAAA,OAAA,CAAQ,iBAAkB,OAAO,CAAA,CAAA;AACzC,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,MAAM,eAAe,OAAQ,CAAA,IAAA,CAAA;AAC7B,MAAM,MAAA,IAAA,CAAK,OAAO,OAAQ,CAAA;AAAA,QACxB,KAAA;AAAA,QACA,YAAA;AAAA,QACA,UAAU,OAAQ,CAAA,OAAA;AAAA,OACnB,CAAA,CAAA;AAED,MAAA,QAAA,CAAS,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,YAAY,CAAA,CAAA;AAAA,KACjD,CAAA,CAAA;AAID,IAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAA8B,2BAAA,EAAA,IAAI,CAAoB,kBAAA,CAAA,CAAA,CAAA;AAAA,GACzE;AACF;;;;"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -2,11 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var pluginEventsNode = require('@backstage/plugin-events-node');
|
|
6
|
+
var HttpPostIngressEventPublisher = require('./cjs/HttpPostIngressEventPublisher-a08684c9.cjs.js');
|
|
6
7
|
require('@backstage/backend-common');
|
|
7
8
|
require('express');
|
|
8
9
|
require('express-promise-router');
|
|
9
10
|
|
|
11
|
+
var __defProp$1 = Object.defineProperty;
|
|
12
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
+
var __publicField$1 = (obj, key, value) => {
|
|
14
|
+
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
15
|
+
return value;
|
|
16
|
+
};
|
|
17
|
+
class DefaultEventBroker {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param logger - logger
|
|
21
|
+
* @param events - replacement that gets wrapped to support not yet migrated implementations.
|
|
22
|
+
* An instance can be passed (required for a mixed mode), otherwise a new instance gets created internally.
|
|
23
|
+
* @deprecated use `DefaultEventsService` directly instead
|
|
24
|
+
*/
|
|
25
|
+
constructor(logger, events) {
|
|
26
|
+
__publicField$1(this, "events");
|
|
27
|
+
this.events = events != null ? events : pluginEventsNode.DefaultEventsService.create({ logger });
|
|
28
|
+
}
|
|
29
|
+
async publish(params) {
|
|
30
|
+
return this.events.publish(params);
|
|
31
|
+
}
|
|
32
|
+
subscribe(...subscribers) {
|
|
33
|
+
subscribers.flat().forEach(async (subscriber) => {
|
|
34
|
+
await this.events.subscribe({
|
|
35
|
+
id: subscriber.constructor.name,
|
|
36
|
+
topics: subscriber.supportsEventTopics(),
|
|
37
|
+
onEvent: subscriber.onEvent.bind(subscriber)
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
10
43
|
var __defProp = Object.defineProperty;
|
|
11
44
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
45
|
var __publicField = (obj, key, value) => {
|
|
@@ -18,7 +51,7 @@ class EventsBackend {
|
|
|
18
51
|
__publicField(this, "eventBroker");
|
|
19
52
|
__publicField(this, "publishers", []);
|
|
20
53
|
__publicField(this, "subscribers", []);
|
|
21
|
-
this.eventBroker = new
|
|
54
|
+
this.eventBroker = new DefaultEventBroker(logger);
|
|
22
55
|
}
|
|
23
56
|
setEventBroker(eventBroker) {
|
|
24
57
|
this.eventBroker = eventBroker;
|
|
@@ -43,7 +76,7 @@ class EventsBackend {
|
|
|
43
76
|
}
|
|
44
77
|
}
|
|
45
78
|
|
|
46
|
-
exports.DefaultEventBroker = HttpPostIngressEventPublisher.DefaultEventBroker;
|
|
47
79
|
exports.HttpPostIngressEventPublisher = HttpPostIngressEventPublisher.HttpPostIngressEventPublisher;
|
|
80
|
+
exports.DefaultEventBroker = DefaultEventBroker;
|
|
48
81
|
exports.EventsBackend = EventsBackend;
|
|
49
82
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/service/EventsBackend.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EventBroker,\n EventPublisher,\n EventSubscriber,\n} from '@backstage/plugin-events-node';\nimport { Logger } from 'winston';\nimport { DefaultEventBroker } from './DefaultEventBroker';\n\n/**\n * A builder that helps wire up all component parts of the event management.\n *\n * @public\n */\nexport class EventsBackend {\n private eventBroker: EventBroker;\n private publishers: EventPublisher[] = [];\n private subscribers: EventSubscriber[] = [];\n\n constructor(logger: Logger) {\n this.eventBroker = new DefaultEventBroker(logger);\n }\n\n setEventBroker(eventBroker: EventBroker): EventsBackend {\n this.eventBroker = eventBroker;\n return this;\n }\n\n addPublishers(\n ...publishers: Array<EventPublisher | Array<EventPublisher>>\n ): EventsBackend {\n this.publishers.push(...publishers.flat());\n return this;\n }\n\n addSubscribers(\n ...subscribers: Array<EventSubscriber | Array<EventSubscriber>>\n ): EventsBackend {\n this.subscribers.push(...subscribers.flat());\n return this;\n }\n\n /**\n * Wires up and returns all component parts of the event management.\n */\n async start(): Promise<void> {\n this.eventBroker.subscribe(this.subscribers);\n this.publishers.forEach(publisher =>\n publisher.setEventBroker(this.eventBroker),\n );\n }\n}\n"],"names":["
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/service/DefaultEventBroker.ts","../src/service/EventsBackend.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport {\n DefaultEventsService,\n EventBroker,\n EventParams,\n EventsService,\n EventSubscriber,\n} from '@backstage/plugin-events-node';\n\n/**\n * In process event broker which will pass the event to all registered subscribers\n * interested in it.\n * Events will not be persisted in any form.\n *\n * @public\n * @deprecated use `DefaultEventsService` from `@backstage/plugin-events-node` instead\n */\nexport class DefaultEventBroker implements EventBroker {\n private readonly events: EventsService;\n\n /**\n *\n * @param logger - logger\n * @param events - replacement that gets wrapped to support not yet migrated implementations.\n * An instance can be passed (required for a mixed mode), otherwise a new instance gets created internally.\n * @deprecated use `DefaultEventsService` directly instead\n */\n constructor(logger: LoggerService, events?: EventsService) {\n this.events = events ?? DefaultEventsService.create({ logger });\n }\n\n async publish(params: EventParams): Promise<void> {\n return this.events.publish(params);\n }\n\n subscribe(\n ...subscribers: Array<EventSubscriber | Array<EventSubscriber>>\n ): void {\n subscribers.flat().forEach(async subscriber => {\n await this.events.subscribe({\n id: subscriber.constructor.name,\n topics: subscriber.supportsEventTopics(),\n onEvent: subscriber.onEvent.bind(subscriber),\n });\n });\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EventBroker,\n EventPublisher,\n EventSubscriber,\n} from '@backstage/plugin-events-node';\nimport { Logger } from 'winston';\nimport { DefaultEventBroker } from './DefaultEventBroker';\n\n/**\n * A builder that helps wire up all component parts of the event management.\n *\n * @public\n * @deprecated `EventBroker`, `EventPublisher`, and `EventSubscriber` got replaced by `EventsService` and its methods.\n */\nexport class EventsBackend {\n private eventBroker: EventBroker;\n private publishers: EventPublisher[] = [];\n private subscribers: EventSubscriber[] = [];\n\n constructor(logger: Logger) {\n this.eventBroker = new DefaultEventBroker(logger);\n }\n\n setEventBroker(eventBroker: EventBroker): EventsBackend {\n this.eventBroker = eventBroker;\n return this;\n }\n\n addPublishers(\n ...publishers: Array<EventPublisher | Array<EventPublisher>>\n ): EventsBackend {\n this.publishers.push(...publishers.flat());\n return this;\n }\n\n addSubscribers(\n ...subscribers: Array<EventSubscriber | Array<EventSubscriber>>\n ): EventsBackend {\n this.subscribers.push(...subscribers.flat());\n return this;\n }\n\n /**\n * Wires up and returns all component parts of the event management.\n */\n async start(): Promise<void> {\n this.eventBroker.subscribe(this.subscribers);\n this.publishers.forEach(publisher =>\n publisher.setEventBroker(this.eventBroker),\n );\n }\n}\n"],"names":["__publicField","DefaultEventsService"],"mappings":";;;;;;;;;;;;;;;;AAiCO,MAAM,kBAA0C,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUrD,WAAA,CAAY,QAAuB,MAAwB,EAAA;AAT3D,IAAiBA,eAAA,CAAA,IAAA,EAAA,QAAA,CAAA,CAAA;AAUf,IAAA,IAAA,CAAK,SAAS,MAAU,IAAA,IAAA,GAAA,MAAA,GAAAC,qCAAA,CAAqB,MAAO,CAAA,EAAE,QAAQ,CAAA,CAAA;AAAA,GAChE;AAAA,EAEA,MAAM,QAAQ,MAAoC,EAAA;AAChD,IAAO,OAAA,IAAA,CAAK,MAAO,CAAA,OAAA,CAAQ,MAAM,CAAA,CAAA;AAAA,GACnC;AAAA,EAEA,aACK,WACG,EAAA;AACN,IAAA,WAAA,CAAY,IAAK,EAAA,CAAE,OAAQ,CAAA,OAAM,UAAc,KAAA;AAC7C,MAAM,MAAA,IAAA,CAAK,OAAO,SAAU,CAAA;AAAA,QAC1B,EAAA,EAAI,WAAW,WAAY,CAAA,IAAA;AAAA,QAC3B,MAAA,EAAQ,WAAW,mBAAoB,EAAA;AAAA,QACvC,OAAS,EAAA,UAAA,CAAW,OAAQ,CAAA,IAAA,CAAK,UAAU,CAAA;AAAA,OAC5C,CAAA,CAAA;AAAA,KACF,CAAA,CAAA;AAAA,GACH;AACF;;;;;;;;AChCO,MAAM,aAAc,CAAA;AAAA,EAKzB,YAAY,MAAgB,EAAA;AAJ5B,IAAQ,aAAA,CAAA,IAAA,EAAA,aAAA,CAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,cAA+B,EAAC,CAAA,CAAA;AACxC,IAAA,aAAA,CAAA,IAAA,EAAQ,eAAiC,EAAC,CAAA,CAAA;AAGxC,IAAK,IAAA,CAAA,WAAA,GAAc,IAAI,kBAAA,CAAmB,MAAM,CAAA,CAAA;AAAA,GAClD;AAAA,EAEA,eAAe,WAAyC,EAAA;AACtD,IAAA,IAAA,CAAK,WAAc,GAAA,WAAA,CAAA;AACnB,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAAA,EAEA,iBACK,UACY,EAAA;AACf,IAAA,IAAA,CAAK,UAAW,CAAA,IAAA,CAAK,GAAG,UAAA,CAAW,MAAM,CAAA,CAAA;AACzC,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAAA,EAEA,kBACK,WACY,EAAA;AACf,IAAA,IAAA,CAAK,WAAY,CAAA,IAAA,CAAK,GAAG,WAAA,CAAY,MAAM,CAAA,CAAA;AAC3C,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAuB,GAAA;AAC3B,IAAK,IAAA,CAAA,WAAA,CAAY,SAAU,CAAA,IAAA,CAAK,WAAW,CAAA,CAAA;AAC3C,IAAA,IAAA,CAAK,UAAW,CAAA,OAAA;AAAA,MAAQ,CACtB,SAAA,KAAA,SAAA,CAAU,cAAe,CAAA,IAAA,CAAK,WAAW,CAAA;AAAA,KAC3C,CAAA;AAAA,GACF;AACF;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { EventBroker, EventPublisher, EventSubscriber,
|
|
1
|
+
import { EventBroker, EventPublisher, EventSubscriber, EventsService, EventParams, HttpPostIngressOptions } from '@backstage/plugin-events-node';
|
|
2
2
|
import { Logger } from 'winston';
|
|
3
|
+
import { LoggerService } from '@backstage/backend-plugin-api';
|
|
3
4
|
import { Config } from '@backstage/config';
|
|
4
5
|
import express from 'express';
|
|
5
6
|
|
|
@@ -7,6 +8,7 @@ import express from 'express';
|
|
|
7
8
|
* A builder that helps wire up all component parts of the event management.
|
|
8
9
|
*
|
|
9
10
|
* @public
|
|
11
|
+
* @deprecated `EventBroker`, `EventPublisher`, and `EventSubscriber` got replaced by `EventsService` and its methods.
|
|
10
12
|
*/
|
|
11
13
|
declare class EventsBackend {
|
|
12
14
|
private eventBroker;
|
|
@@ -22,43 +24,50 @@ declare class EventsBackend {
|
|
|
22
24
|
start(): Promise<void>;
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
/**
|
|
28
|
+
* In process event broker which will pass the event to all registered subscribers
|
|
29
|
+
* interested in it.
|
|
30
|
+
* Events will not be persisted in any form.
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
33
|
+
* @deprecated use `DefaultEventsService` from `@backstage/plugin-events-node` instead
|
|
34
|
+
*/
|
|
35
|
+
declare class DefaultEventBroker implements EventBroker {
|
|
36
|
+
private readonly events;
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @param logger - logger
|
|
40
|
+
* @param events - replacement that gets wrapped to support not yet migrated implementations.
|
|
41
|
+
* An instance can be passed (required for a mixed mode), otherwise a new instance gets created internally.
|
|
42
|
+
* @deprecated use `DefaultEventsService` directly instead
|
|
43
|
+
*/
|
|
44
|
+
constructor(logger: LoggerService, events?: EventsService);
|
|
45
|
+
publish(params: EventParams): Promise<void>;
|
|
46
|
+
subscribe(...subscribers: Array<EventSubscriber | Array<EventSubscriber>>): void;
|
|
47
|
+
}
|
|
48
|
+
|
|
25
49
|
/**
|
|
26
50
|
* Publishes events received from their origin (e.g., webhook events from an SCM system)
|
|
27
51
|
* via HTTP POST endpoint and passes the request body as event payload to the registered subscribers.
|
|
28
52
|
*
|
|
29
53
|
* @public
|
|
30
54
|
*/
|
|
31
|
-
declare class HttpPostIngressEventPublisher
|
|
55
|
+
declare class HttpPostIngressEventPublisher {
|
|
56
|
+
private readonly events;
|
|
32
57
|
private readonly logger;
|
|
33
58
|
private readonly ingresses;
|
|
34
|
-
private eventBroker?;
|
|
35
59
|
static fromConfig(env: {
|
|
36
60
|
config: Config;
|
|
61
|
+
events: EventsService;
|
|
37
62
|
ingresses?: {
|
|
38
63
|
[topic: string]: Omit<HttpPostIngressOptions, 'topic'>;
|
|
39
64
|
};
|
|
40
|
-
logger:
|
|
65
|
+
logger: LoggerService;
|
|
41
66
|
}): HttpPostIngressEventPublisher;
|
|
42
67
|
private constructor();
|
|
43
68
|
bind(router: express.Router): void;
|
|
44
|
-
setEventBroker(eventBroker: EventBroker): Promise<void>;
|
|
45
69
|
private createRouter;
|
|
46
70
|
private addRouteForTopic;
|
|
47
71
|
}
|
|
48
72
|
|
|
49
|
-
/**
|
|
50
|
-
* In process event broker which will pass the event to all registered subscribers
|
|
51
|
-
* interested in it.
|
|
52
|
-
* Events will not be persisted in any form.
|
|
53
|
-
*
|
|
54
|
-
* @public
|
|
55
|
-
*/
|
|
56
|
-
declare class DefaultEventBroker implements EventBroker {
|
|
57
|
-
private readonly logger;
|
|
58
|
-
constructor(logger: Logger);
|
|
59
|
-
private readonly subscribers;
|
|
60
|
-
publish(params: EventParams): Promise<void>;
|
|
61
|
-
subscribe(...subscribers: Array<EventSubscriber | Array<EventSubscriber>>): void;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
73
|
export { DefaultEventBroker, EventsBackend, HttpPostIngressEventPublisher };
|
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-events-backend",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"version": "0.3.0-next.0",
|
|
4
|
+
"backstage": {
|
|
5
|
+
"role": "backend-plugin"
|
|
6
|
+
},
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
10
|
+
"homepage": "https://backstage.io",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/backstage/backstage",
|
|
14
|
+
"directory": "plugins/events-backend"
|
|
15
|
+
},
|
|
16
|
+
"license": "Apache-2.0",
|
|
10
17
|
"exports": {
|
|
11
18
|
".": {
|
|
12
19
|
"require": "./dist/index.cjs.js",
|
|
@@ -20,45 +27,38 @@
|
|
|
20
27
|
},
|
|
21
28
|
"./package.json": "./package.json"
|
|
22
29
|
},
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
"directory": "plugins/events-backend"
|
|
31
|
-
},
|
|
30
|
+
"main": "./dist/index.cjs.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"files": [
|
|
33
|
+
"config.d.ts",
|
|
34
|
+
"dist",
|
|
35
|
+
"alpha"
|
|
36
|
+
],
|
|
32
37
|
"scripts": {
|
|
33
|
-
"start": "backstage-cli package start",
|
|
34
38
|
"build": "backstage-cli package build",
|
|
35
|
-
"lint": "backstage-cli package lint",
|
|
36
|
-
"test": "backstage-cli package test",
|
|
37
39
|
"clean": "backstage-cli package clean",
|
|
40
|
+
"lint": "backstage-cli package lint",
|
|
38
41
|
"prepack": "backstage-cli package prepack",
|
|
39
|
-
"postpack": "backstage-cli package postpack"
|
|
42
|
+
"postpack": "backstage-cli package postpack",
|
|
43
|
+
"start": "backstage-cli package start",
|
|
44
|
+
"test": "backstage-cli package test"
|
|
40
45
|
},
|
|
41
46
|
"dependencies": {
|
|
42
|
-
"@backstage/backend-common": "^0.21.
|
|
43
|
-
"@backstage/backend-plugin-api": "^0.6.
|
|
44
|
-
"@backstage/config": "^1.1.
|
|
45
|
-
"@backstage/plugin-events-node": "^0.
|
|
47
|
+
"@backstage/backend-common": "^0.21.3-next.0",
|
|
48
|
+
"@backstage/backend-plugin-api": "^0.6.13-next.0",
|
|
49
|
+
"@backstage/config": "^1.1.2-next.0",
|
|
50
|
+
"@backstage/plugin-events-node": "^0.3.0-next.0",
|
|
46
51
|
"@types/express": "^4.17.6",
|
|
47
52
|
"express": "^4.17.1",
|
|
48
53
|
"express-promise-router": "^4.1.0",
|
|
49
54
|
"winston": "^3.2.1"
|
|
50
55
|
},
|
|
51
56
|
"devDependencies": {
|
|
52
|
-
"@backstage/backend-common": "^0.21.
|
|
53
|
-
"@backstage/backend-test-utils": "^0.3.
|
|
54
|
-
"@backstage/cli": "^0.25.
|
|
55
|
-
"@backstage/plugin-events-backend-test-utils": "^0.1.
|
|
57
|
+
"@backstage/backend-common": "^0.21.3-next.0",
|
|
58
|
+
"@backstage/backend-test-utils": "^0.3.3-next.0",
|
|
59
|
+
"@backstage/cli": "^0.25.3-next.0",
|
|
60
|
+
"@backstage/plugin-events-backend-test-utils": "^0.1.23-next.0",
|
|
56
61
|
"supertest": "^6.1.3"
|
|
57
62
|
},
|
|
58
|
-
"files": [
|
|
59
|
-
"config.d.ts",
|
|
60
|
-
"dist",
|
|
61
|
-
"alpha"
|
|
62
|
-
],
|
|
63
63
|
"configSchema": "config.d.ts"
|
|
64
64
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HttpPostIngressEventPublisher-6e928c08.cjs.js","sources":["../../src/service/DefaultEventBroker.ts","../../src/service/http/validation/RequestValidationContextImpl.ts","../../src/service/http/HttpPostIngressEventPublisher.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EventBroker,\n EventParams,\n EventSubscriber,\n} from '@backstage/plugin-events-node';\nimport { Logger } from 'winston';\n\n/**\n * In process event broker which will pass the event to all registered subscribers\n * interested in it.\n * Events will not be persisted in any form.\n *\n * @public\n */\n// TODO(pjungermann): add prom metrics? (see plugins/catalog-backend/src/util/metrics.ts, etc.)\nexport class DefaultEventBroker implements EventBroker {\n constructor(private readonly logger: Logger) {}\n\n private readonly subscribers: {\n [topic: string]: EventSubscriber[];\n } = {};\n\n async publish(params: EventParams): Promise<void> {\n this.logger.debug(\n `Event received: topic=${params.topic}, metadata=${JSON.stringify(\n params.metadata,\n )}, payload=${JSON.stringify(params.eventPayload)}`,\n );\n\n const subscribed = this.subscribers[params.topic] ?? [];\n await Promise.all(\n subscribed.map(async subscriber => {\n try {\n await subscriber.onEvent(params);\n } catch (error) {\n this.logger.error(\n `Subscriber \"${subscriber.constructor.name}\" failed to process event`,\n error,\n );\n }\n }),\n );\n }\n\n subscribe(\n ...subscribers: Array<EventSubscriber | Array<EventSubscriber>>\n ): void {\n subscribers.flat().forEach(subscriber => {\n subscriber.supportsEventTopics().forEach(topic => {\n this.subscribers[topic] = this.subscribers[topic] ?? [];\n this.subscribers[topic].push(subscriber);\n });\n });\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n RequestRejectionDetails,\n RequestValidationContext,\n} from '@backstage/plugin-events-node';\n\nexport class RequestValidationContextImpl implements RequestValidationContext {\n #rejectionDetails: RequestRejectionDetails | undefined;\n\n reject(details?: Partial<RequestRejectionDetails>): void {\n this.#rejectionDetails = {\n status: details?.status ?? 403,\n payload: details?.payload ?? {},\n };\n }\n\n wasRejected(): boolean {\n return this.#rejectionDetails !== undefined;\n }\n\n get rejectionDetails() {\n return this.#rejectionDetails;\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { errorHandler } from '@backstage/backend-common';\nimport { Config } from '@backstage/config';\nimport {\n EventBroker,\n EventPublisher,\n HttpPostIngressOptions,\n RequestValidator,\n} from '@backstage/plugin-events-node';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Logger } from 'winston';\nimport { RequestValidationContextImpl } from './validation';\n\n/**\n * Publishes events received from their origin (e.g., webhook events from an SCM system)\n * via HTTP POST endpoint and passes the request body as event payload to the registered subscribers.\n *\n * @public\n */\n// TODO(pjungermann): add prom metrics? (see plugins/catalog-backend/src/util/metrics.ts, etc.)\nexport class HttpPostIngressEventPublisher implements EventPublisher {\n private eventBroker?: EventBroker;\n\n static fromConfig(env: {\n config: Config;\n ingresses?: { [topic: string]: Omit<HttpPostIngressOptions, 'topic'> };\n logger: Logger;\n }): HttpPostIngressEventPublisher {\n const topics =\n env.config.getOptionalStringArray('events.http.topics') ?? [];\n\n const ingresses = env.ingresses ?? {};\n topics.forEach(topic => {\n // don't overwrite topic settings\n // (e.g., added at the config as well as argument)\n if (!ingresses[topic]) {\n ingresses[topic] = {};\n }\n });\n\n return new HttpPostIngressEventPublisher(env.logger, ingresses);\n }\n\n private constructor(\n private readonly logger: Logger,\n private readonly ingresses: {\n [topic: string]: Omit<HttpPostIngressOptions, 'topic'>;\n },\n ) {}\n\n bind(router: express.Router): void {\n router.use('/http', this.createRouter(this.ingresses));\n }\n\n async setEventBroker(eventBroker: EventBroker): Promise<void> {\n this.eventBroker = eventBroker;\n }\n\n private createRouter(ingresses: {\n [topic: string]: Omit<HttpPostIngressOptions, 'topic'>;\n }): express.Router {\n const router = Router();\n router.use(express.json());\n\n Object.keys(ingresses).forEach(topic =>\n this.addRouteForTopic(router, topic, ingresses[topic].validator),\n );\n\n router.use(errorHandler());\n return router;\n }\n\n private addRouteForTopic(\n router: express.Router,\n topic: string,\n validator?: RequestValidator,\n ): void {\n const path = `/${topic}`;\n\n router.post(path, async (request, response) => {\n const requestDetails = {\n body: request.body,\n headers: request.headers,\n };\n const context = new RequestValidationContextImpl();\n await validator?.(requestDetails, context);\n if (context.wasRejected()) {\n response\n .status(context.rejectionDetails!.status)\n .json(context.rejectionDetails!.payload);\n return;\n }\n\n const eventPayload = request.body;\n await this.eventBroker!.publish({\n topic,\n eventPayload,\n metadata: request.headers,\n });\n\n response.status(202).json({ status: 'accepted' });\n });\n\n // TODO(pjungermann): We don't really know the externally defined path prefix here,\n // however it is more useful for users to have it. Is there a better way?\n this.logger.info(`Registered /api/events/http${path} to receive events`);\n }\n}\n"],"names":["__publicField","Router","express","errorHandler"],"mappings":"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"}
|