Skip to content

Commit

Permalink
feat(microservices) add capability to use RegExp in Kafka Events
Browse files Browse the repository at this point in the history
  • Loading branch information
alfredoperez committed Oct 11, 2019
1 parent 21fb46e commit 475b837
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ export interface MessageHandler<TInput = any, TContext = any, TResult = any> {
(data: TInput, ctx?: TContext): Promise<Observable<TResult>>;
isEventHandler?: boolean;
}

export interface RegExpMessageHandler {
pattern: RegExp;
messageHandler: MessageHandler;
}
7 changes: 5 additions & 2 deletions packages/microservices/server/server-kafka.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ export class ServerKafka extends Server implements CustomTransportStrategy {
}

public async bindEvents(consumer: Consumer) {
const registeredPatterns = [...this.messageHandlers.keys()];
const subscribeToPattern = async (pattern: string) =>
const registeredPatterns = [
...this.messageHandlers.keys(),
...this.regExpMessageHandlers.map(handler => handler.pattern),
];
const subscribeToPattern = async (pattern: string | RegExp) =>
consumer.subscribe({
topic: pattern,
});
Expand Down
29 changes: 23 additions & 6 deletions packages/microservices/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
NatsOptions,
ReadPacket,
RedisOptions,
RegExpMessageHandler,
RmqOptions,
TcpOptions,
WritePacket,
Expand All @@ -34,6 +35,7 @@ import { NO_EVENT_HANDLER } from '../constants';

export abstract class Server {
protected readonly messageHandlers = new Map<string, MessageHandler>();
protected readonly regExpMessageHandlers = new Array<RegExpMessageHandler>();
protected readonly logger = new Logger(Server.name);
protected serializer: ConsumerSerializer;
protected deserializer: ConsumerDeserializer;
Expand All @@ -43,9 +45,13 @@ export abstract class Server {
callback: MessageHandler,
isEventHandler = false,
) {
const route = transformPatternToRoute(pattern);
callback.isEventHandler = isEventHandler;
this.messageHandlers.set(route, callback);
if (pattern.constructor.name === 'RegExp') {
this.regExpMessageHandlers.push({ pattern, messageHandler: callback });
} else {
const route = transformPatternToRoute(pattern);
callback.isEventHandler = isEventHandler;
this.messageHandlers.set(route, callback);
}
}

public getHandlers(): Map<string, MessageHandler> {
Expand All @@ -54,9 +60,20 @@ export abstract class Server {

public getHandlerByPattern(pattern: string): MessageHandler | null {
const route = this.getRouteFromPattern(pattern);
return this.messageHandlers.has(route)
? this.messageHandlers.get(route)
: null;
let handler = null;
// Try to find the message handler by name
if (this.messageHandlers.has(route)) {
return this.messageHandlers.get(route);
}

// If it was not found, iterate through the Regular Expression handlers
this.regExpMessageHandlers.forEach(regExpHandler => {
if (regExpHandler.pattern.exec(route) !== null) {
handler = regExpHandler.messageHandler;
}
});

return handler;
}

public send(
Expand Down
22 changes: 22 additions & 0 deletions packages/microservices/test/server/server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Observable, of, throwError as _throw } from 'rxjs';
import * as sinon from 'sinon';
import { Server } from '../../server/server';
import * as Utils from '../../utils';
import { RegExpMessageHandler } from '../../interfaces';

class TestServer extends Server {
public listen(callback: () => void) {}
Expand Down Expand Up @@ -197,6 +198,27 @@ describe('Server', () => {
});
});

describe('when handler exists and was added with a RegExp', () => {
beforeEach(() => {
sandbox.stub(server as any, 'regExpMessageHandlers').value([
({
pattern: /.*el.*/,
messageHandler: callback,
} as unknown) as RegExpMessageHandler,
]);
});

it('should return expected handler', () => {
messageHandlersHasSpy.returns(false);

const value = server.getHandlerByPattern(handlerRoute);

expect(messageHandlersHasSpy.called).to.be.true;
expect(messageHandlersGetSpy.called).to.be.false;
expect(value).to.be.equal(callback);
});
});

describe('when handler does not exists', () => {
it('should return null', () => {
messageHandlersHasSpy.returns(false);
Expand Down

0 comments on commit 475b837

Please sign in to comment.