@opra/kafka 1.0.2 → 1.0.4
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/cjs/kafka-adapter.js +59 -32
- package/esm/kafka-adapter.js +60 -33
- package/package.json +3 -3
- package/types/kafka-adapter.d.ts +16 -3
package/cjs/kafka-adapter.js
CHANGED
|
@@ -71,9 +71,14 @@ class KafkaAdapter extends core_1.PlatformAdapter {
|
|
|
71
71
|
}
|
|
72
72
|
/** Subscribe to channels */
|
|
73
73
|
for (const args of this._handlerArgs) {
|
|
74
|
-
const { consumer, operation,
|
|
74
|
+
const { consumer, operation, operationConfig } = args;
|
|
75
75
|
args.topics = Array.isArray(operation.channel) ? operation.channel : [operation.channel];
|
|
76
|
-
await consumer
|
|
76
|
+
await consumer
|
|
77
|
+
.subscribe({
|
|
78
|
+
...operationConfig.subscribe,
|
|
79
|
+
topics: args.topics,
|
|
80
|
+
})
|
|
81
|
+
.catch(e => {
|
|
77
82
|
this._emitError(e);
|
|
78
83
|
throw e;
|
|
79
84
|
});
|
|
@@ -137,17 +142,52 @@ class KafkaAdapter extends core_1.PlatformAdapter {
|
|
|
137
142
|
* @param operation
|
|
138
143
|
* @protected
|
|
139
144
|
*/
|
|
140
|
-
async
|
|
145
|
+
async _getOperationConfig(controller, instance, operation) {
|
|
141
146
|
if (typeof instance[operation.name] !== 'function')
|
|
142
147
|
return;
|
|
143
148
|
const proto = controller.ctor?.prototype || Object.getPrototypeOf(instance);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
if (Reflect.hasMetadata(common_1.RPC_CONTROLLER_METADATA, proto, operation.name))
|
|
150
|
+
return;
|
|
151
|
+
const operationConfig = {
|
|
152
|
+
consumer: {
|
|
153
|
+
groupId: constants_js_1.KAFKA_DEFAULT_GROUP,
|
|
154
|
+
},
|
|
155
|
+
subscribe: {},
|
|
156
|
+
};
|
|
157
|
+
if (this._config.defaults) {
|
|
158
|
+
if (this._config.defaults.subscribe) {
|
|
159
|
+
Object.assign(operationConfig.subscribe, this._config.defaults.subscribe);
|
|
160
|
+
}
|
|
161
|
+
if (this._config.defaults.consumer) {
|
|
162
|
+
Object.assign(operationConfig.consumer, this._config.defaults.consumer);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
let kafkaMetadata = Reflect.getMetadata(constants_js_1.KAFKA_OPERATION_METADATA, proto, operation.name);
|
|
166
|
+
if (!kafkaMetadata) {
|
|
167
|
+
const configResolver = Reflect.getMetadata(constants_js_1.KAFKA_OPERATION_METADATA_RESOLVER, proto, operation.name);
|
|
168
|
+
if (configResolver) {
|
|
169
|
+
kafkaMetadata = await configResolver();
|
|
170
|
+
}
|
|
149
171
|
}
|
|
150
|
-
|
|
172
|
+
if (kafkaMetadata) {
|
|
173
|
+
if (kafkaMetadata.subscribe) {
|
|
174
|
+
Object.assign(operationConfig.subscribe, kafkaMetadata.subscribe);
|
|
175
|
+
}
|
|
176
|
+
if (kafkaMetadata.consumer) {
|
|
177
|
+
if (typeof kafkaMetadata.consumer === 'object') {
|
|
178
|
+
Object.assign(operationConfig.consumer, kafkaMetadata.consumer);
|
|
179
|
+
operationConfig.selfConsumer = true;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
const x = this._config.consumers?.[kafkaMetadata.consumer];
|
|
183
|
+
if (x) {
|
|
184
|
+
operationConfig.consumer.groupId = kafkaMetadata.consumer;
|
|
185
|
+
Object.assign(operationConfig.consumer, x);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return operationConfig;
|
|
151
191
|
}
|
|
152
192
|
/**
|
|
153
193
|
*
|
|
@@ -163,16 +203,15 @@ class KafkaAdapter extends core_1.PlatformAdapter {
|
|
|
163
203
|
this._controllerInstances.set(controller, instance);
|
|
164
204
|
/** Build HandlerData array */
|
|
165
205
|
for (const operation of controller.operations.values()) {
|
|
166
|
-
const
|
|
167
|
-
if (!
|
|
206
|
+
const operationConfig = await this._getOperationConfig(controller, instance, operation);
|
|
207
|
+
if (!operationConfig)
|
|
168
208
|
continue;
|
|
169
|
-
// const consumerConfig = this._getConsumerConfig(operationOptions);
|
|
170
209
|
const args = {
|
|
171
210
|
consumer: null,
|
|
172
211
|
controller,
|
|
173
212
|
instance,
|
|
174
213
|
operation,
|
|
175
|
-
|
|
214
|
+
operationConfig,
|
|
176
215
|
handler: null,
|
|
177
216
|
topics: null,
|
|
178
217
|
};
|
|
@@ -191,28 +230,16 @@ class KafkaAdapter extends core_1.PlatformAdapter {
|
|
|
191
230
|
* @protected
|
|
192
231
|
*/
|
|
193
232
|
async _createConsumer(args) {
|
|
194
|
-
const {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
let consumer;
|
|
199
|
-
if (typeof operationOptions.consumer === 'object') {
|
|
200
|
-
consumer = this._consumers.get(operationOptions.consumer.groupId);
|
|
201
|
-
if (consumer) {
|
|
202
|
-
throw new Error(`Operation consumer for groupId (${operationOptions.consumer.groupId}) already exists`);
|
|
203
|
-
}
|
|
204
|
-
Object.assign(consumerConfig, operationOptions.consumer);
|
|
205
|
-
}
|
|
206
|
-
else if (operationOptions.consumer) {
|
|
207
|
-
const x = this._config.consumers?.[operationOptions.consumer];
|
|
208
|
-
Object.assign(consumerConfig, { ...x, groupId: operationOptions.consumer });
|
|
233
|
+
const { operationConfig } = args;
|
|
234
|
+
let consumer = this._consumers.get(operationConfig.consumer.groupId);
|
|
235
|
+
if (consumer && operationConfig.selfConsumer) {
|
|
236
|
+
throw new Error(`Operation consumer for groupId (${operationConfig.consumer.groupId}) already exists`);
|
|
209
237
|
}
|
|
210
|
-
consumer = this._consumers.get(consumerConfig.groupId);
|
|
211
238
|
/** Create consumers */
|
|
212
239
|
if (!consumer) {
|
|
213
|
-
consumer = this.kafka.consumer(
|
|
214
|
-
consumer[kGroupId] =
|
|
215
|
-
this._consumers.set(
|
|
240
|
+
consumer = this.kafka.consumer(operationConfig.consumer);
|
|
241
|
+
consumer[kGroupId] = operationConfig.consumer.groupId;
|
|
242
|
+
this._consumers.set(operationConfig.consumer.groupId, consumer);
|
|
216
243
|
}
|
|
217
244
|
args.consumer = consumer;
|
|
218
245
|
}
|
package/esm/kafka-adapter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RpcApi } from '@opra/common';
|
|
1
|
+
import { RPC_CONTROLLER_METADATA, RpcApi } from '@opra/common';
|
|
2
2
|
import { kAssetCache, PlatformAdapter } from '@opra/core';
|
|
3
3
|
import { Kafka, logLevel } from 'kafkajs';
|
|
4
4
|
import { vg } from 'valgen';
|
|
@@ -68,9 +68,14 @@ export class KafkaAdapter extends PlatformAdapter {
|
|
|
68
68
|
}
|
|
69
69
|
/** Subscribe to channels */
|
|
70
70
|
for (const args of this._handlerArgs) {
|
|
71
|
-
const { consumer, operation,
|
|
71
|
+
const { consumer, operation, operationConfig } = args;
|
|
72
72
|
args.topics = Array.isArray(operation.channel) ? operation.channel : [operation.channel];
|
|
73
|
-
await consumer
|
|
73
|
+
await consumer
|
|
74
|
+
.subscribe({
|
|
75
|
+
...operationConfig.subscribe,
|
|
76
|
+
topics: args.topics,
|
|
77
|
+
})
|
|
78
|
+
.catch(e => {
|
|
74
79
|
this._emitError(e);
|
|
75
80
|
throw e;
|
|
76
81
|
});
|
|
@@ -134,17 +139,52 @@ export class KafkaAdapter extends PlatformAdapter {
|
|
|
134
139
|
* @param operation
|
|
135
140
|
* @protected
|
|
136
141
|
*/
|
|
137
|
-
async
|
|
142
|
+
async _getOperationConfig(controller, instance, operation) {
|
|
138
143
|
if (typeof instance[operation.name] !== 'function')
|
|
139
144
|
return;
|
|
140
145
|
const proto = controller.ctor?.prototype || Object.getPrototypeOf(instance);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
if (Reflect.hasMetadata(RPC_CONTROLLER_METADATA, proto, operation.name))
|
|
147
|
+
return;
|
|
148
|
+
const operationConfig = {
|
|
149
|
+
consumer: {
|
|
150
|
+
groupId: KAFKA_DEFAULT_GROUP,
|
|
151
|
+
},
|
|
152
|
+
subscribe: {},
|
|
153
|
+
};
|
|
154
|
+
if (this._config.defaults) {
|
|
155
|
+
if (this._config.defaults.subscribe) {
|
|
156
|
+
Object.assign(operationConfig.subscribe, this._config.defaults.subscribe);
|
|
157
|
+
}
|
|
158
|
+
if (this._config.defaults.consumer) {
|
|
159
|
+
Object.assign(operationConfig.consumer, this._config.defaults.consumer);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
let kafkaMetadata = Reflect.getMetadata(KAFKA_OPERATION_METADATA, proto, operation.name);
|
|
163
|
+
if (!kafkaMetadata) {
|
|
164
|
+
const configResolver = Reflect.getMetadata(KAFKA_OPERATION_METADATA_RESOLVER, proto, operation.name);
|
|
165
|
+
if (configResolver) {
|
|
166
|
+
kafkaMetadata = await configResolver();
|
|
167
|
+
}
|
|
146
168
|
}
|
|
147
|
-
|
|
169
|
+
if (kafkaMetadata) {
|
|
170
|
+
if (kafkaMetadata.subscribe) {
|
|
171
|
+
Object.assign(operationConfig.subscribe, kafkaMetadata.subscribe);
|
|
172
|
+
}
|
|
173
|
+
if (kafkaMetadata.consumer) {
|
|
174
|
+
if (typeof kafkaMetadata.consumer === 'object') {
|
|
175
|
+
Object.assign(operationConfig.consumer, kafkaMetadata.consumer);
|
|
176
|
+
operationConfig.selfConsumer = true;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const x = this._config.consumers?.[kafkaMetadata.consumer];
|
|
180
|
+
if (x) {
|
|
181
|
+
operationConfig.consumer.groupId = kafkaMetadata.consumer;
|
|
182
|
+
Object.assign(operationConfig.consumer, x);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return operationConfig;
|
|
148
188
|
}
|
|
149
189
|
/**
|
|
150
190
|
*
|
|
@@ -160,16 +200,15 @@ export class KafkaAdapter extends PlatformAdapter {
|
|
|
160
200
|
this._controllerInstances.set(controller, instance);
|
|
161
201
|
/** Build HandlerData array */
|
|
162
202
|
for (const operation of controller.operations.values()) {
|
|
163
|
-
const
|
|
164
|
-
if (!
|
|
203
|
+
const operationConfig = await this._getOperationConfig(controller, instance, operation);
|
|
204
|
+
if (!operationConfig)
|
|
165
205
|
continue;
|
|
166
|
-
// const consumerConfig = this._getConsumerConfig(operationOptions);
|
|
167
206
|
const args = {
|
|
168
207
|
consumer: null,
|
|
169
208
|
controller,
|
|
170
209
|
instance,
|
|
171
210
|
operation,
|
|
172
|
-
|
|
211
|
+
operationConfig,
|
|
173
212
|
handler: null,
|
|
174
213
|
topics: null,
|
|
175
214
|
};
|
|
@@ -188,28 +227,16 @@ export class KafkaAdapter extends PlatformAdapter {
|
|
|
188
227
|
* @protected
|
|
189
228
|
*/
|
|
190
229
|
async _createConsumer(args) {
|
|
191
|
-
const {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
let consumer;
|
|
196
|
-
if (typeof operationOptions.consumer === 'object') {
|
|
197
|
-
consumer = this._consumers.get(operationOptions.consumer.groupId);
|
|
198
|
-
if (consumer) {
|
|
199
|
-
throw new Error(`Operation consumer for groupId (${operationOptions.consumer.groupId}) already exists`);
|
|
200
|
-
}
|
|
201
|
-
Object.assign(consumerConfig, operationOptions.consumer);
|
|
202
|
-
}
|
|
203
|
-
else if (operationOptions.consumer) {
|
|
204
|
-
const x = this._config.consumers?.[operationOptions.consumer];
|
|
205
|
-
Object.assign(consumerConfig, { ...x, groupId: operationOptions.consumer });
|
|
230
|
+
const { operationConfig } = args;
|
|
231
|
+
let consumer = this._consumers.get(operationConfig.consumer.groupId);
|
|
232
|
+
if (consumer && operationConfig.selfConsumer) {
|
|
233
|
+
throw new Error(`Operation consumer for groupId (${operationConfig.consumer.groupId}) already exists`);
|
|
206
234
|
}
|
|
207
|
-
consumer = this._consumers.get(consumerConfig.groupId);
|
|
208
235
|
/** Create consumers */
|
|
209
236
|
if (!consumer) {
|
|
210
|
-
consumer = this.kafka.consumer(
|
|
211
|
-
consumer[kGroupId] =
|
|
212
|
-
this._consumers.set(
|
|
237
|
+
consumer = this.kafka.consumer(operationConfig.consumer);
|
|
238
|
+
consumer[kGroupId] = operationConfig.consumer.groupId;
|
|
239
|
+
this._consumers.set(operationConfig.consumer.groupId, consumer);
|
|
213
240
|
}
|
|
214
241
|
args.consumer = consumer;
|
|
215
242
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/kafka",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Opra Kafka package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@opra/common": "^1.0.
|
|
9
|
-
"@opra/core": "^1.0.
|
|
8
|
+
"@opra/common": "^1.0.4",
|
|
9
|
+
"@opra/core": "^1.0.4",
|
|
10
10
|
"node-events-async": "^1.0.0",
|
|
11
11
|
"tslib": "^2.7.0",
|
|
12
12
|
"valgen": "^5.10.0"
|
package/types/kafka-adapter.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ export declare namespace KafkaAdapter {
|
|
|
11
11
|
interface Config extends PlatformAdapter.Options {
|
|
12
12
|
client: StrictOmit<KafkaConfig, 'logCreator' | 'logLevel'>;
|
|
13
13
|
consumers?: Record<string, StrictOmit<ConsumerConfig, 'groupId'>>;
|
|
14
|
+
defaults?: {
|
|
15
|
+
consumer?: ConsumerConfig;
|
|
16
|
+
subscribe?: {
|
|
17
|
+
fromBeginning?: boolean;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
14
20
|
document: ApiDocument;
|
|
15
21
|
interceptors?: (InterceptorFunction | IKafkaInterceptor)[];
|
|
16
22
|
logger?: ILogger;
|
|
@@ -21,7 +27,9 @@ export declare namespace KafkaAdapter {
|
|
|
21
27
|
* groupId or ConsumerConfig
|
|
22
28
|
*/
|
|
23
29
|
consumer?: string | ConsumerConfig;
|
|
24
|
-
|
|
30
|
+
subscribe?: {
|
|
31
|
+
fromBeginning?: boolean;
|
|
32
|
+
};
|
|
25
33
|
}
|
|
26
34
|
/**
|
|
27
35
|
* @type InterceptorFunction
|
|
@@ -34,12 +42,17 @@ export declare namespace KafkaAdapter {
|
|
|
34
42
|
intercept(context: KafkaContext, next: NextCallback): Promise<any>;
|
|
35
43
|
};
|
|
36
44
|
}
|
|
45
|
+
export interface OperationConfig {
|
|
46
|
+
consumer: ConsumerConfig;
|
|
47
|
+
selfConsumer?: boolean;
|
|
48
|
+
subscribe?: KafkaAdapter.OperationOptions['subscribe'];
|
|
49
|
+
}
|
|
37
50
|
interface HandlerArguments {
|
|
38
51
|
consumer: Consumer;
|
|
39
52
|
controller: RpcController;
|
|
40
53
|
instance: any;
|
|
41
54
|
operation: RpcOperation;
|
|
42
|
-
|
|
55
|
+
operationConfig: OperationConfig;
|
|
43
56
|
handler: EachMessageHandler;
|
|
44
57
|
topics: (string | RegExp)[];
|
|
45
58
|
}
|
|
@@ -81,7 +94,7 @@ export declare class KafkaAdapter extends PlatformAdapter {
|
|
|
81
94
|
* @param operation
|
|
82
95
|
* @protected
|
|
83
96
|
*/
|
|
84
|
-
protected
|
|
97
|
+
protected _getOperationConfig(controller: RpcController, instance: any, operation: RpcOperation): Promise<OperationConfig | undefined>;
|
|
85
98
|
/**
|
|
86
99
|
*
|
|
87
100
|
* @protected
|