UNPKG

rsocket-rxjs

Version:
119 lines (118 loc) 4.84 kB
import { defer, Observable, of } from "rxjs"; import { BackpressureStrategy } from "../../api/rsocket.api"; import { factory } from '../../core/config-log4j'; import { EncodingRSocketResponder } from "../encoding-rsocket-responder"; import { WellKnownMimeTypes } from "../well-known-mime-types"; export class RequestResponseMapping { constructor(route, handler, options) { this.route = route; this.handler = handler; this.options = options; } } export class RequestStreamMapping { constructor(route, handler, options, backpressureStrategy = BackpressureStrategy.BufferDelay) { this.route = route; this.handler = handler; this.options = options; this.backpressureStrategy = backpressureStrategy; } } export class RequestFNFMapping { constructor(route, handler, options) { this.route = route; this.handler = handler; this.options = options; } } const log = factory.getLogger('rsocket.extensions.messages.RSocketRoutingResponder'); export class RSocketRoutingResponder extends EncodingRSocketResponder { constructor(encodingRSocket) { super(encodingRSocket); this.encodingRSocket = encodingRSocket; this._requestResponseMappers = []; this._requestStreamMappers = []; this._requestFNFMappers = []; } removeHandler(route) { this._requestResponseMappers = this._requestResponseMappers.filter(v => v.route != route); this._requestStreamMappers = this._requestStreamMappers.filter(v => v.route != route); this._requestFNFMappers = this._requestFNFMappers.filter(v => v.route != route); } addRequestResponseHandler(route, handler, options) { this.addMapping(new RequestResponseMapping(route, handler, options), this._requestResponseMappers); } addRequestStreamHandler(route, handler, options, backpressureStrategy = BackpressureStrategy.BufferDelay) { this.addMapping(new RequestStreamMapping(route, handler, options, backpressureStrategy), this._requestStreamMappers); } addRequestFNFHandler(route, handler, options) { this.addMapping(new RequestFNFMapping(route, handler, options), this._requestFNFMappers); } addMapping(mapping, target) { if (target.findIndex(m => m.route == mapping.route) == -1) { target.push(mapping); } else { throw new Error(`Mapping for topic ${mapping} already registered`); } } handleDecodedRequestStream(payload) { const mapper = this.getMapping(this.getTopic(payload), this._requestStreamMappers); const stream = defer(() => { log.debug("Executing Request Stream Handler for: " + mapper.route); const result = mapper.handler(payload); let obs; if (result instanceof Observable) { obs = result; } else { obs = of(result); } return obs; }); return { stream: stream, backpressureStrategy: mapper.backpressureStrategy }; } handleDecodedRequestResponse(payload) { return defer(() => { const mapper = this.getMapping(this.getTopic(payload), this._requestResponseMappers); log.debug("Executing Request Response Handler for: " + mapper.route); const result = mapper.handler(payload); let obs; if (result instanceof Observable) { obs = result; } else { obs = of(result); } return obs; }); } handleDecodedFireAndForget(payload) { const mapper = this.getMapping(this.getTopic(payload), this._requestFNFMappers); log.debug('Executing Request FNF Handler for: ' + mapper.route); mapper.handler(payload); } getMapping(route, target) { const mapping = target.find(m => m.route == route); if (mapping == undefined) { throw Error(`No handler registered for ${route}`); } return mapping; } getTopic(payload) { if (payload.metadata == undefined) { throw new Error('Cannot get route. No metadata defined'); } if (payload.metadataMimeType == WellKnownMimeTypes.MESSAGE_X_RSOCKET_ROUTING_V0.name) { return payload.metadata; } if (payload.metadataMimeType == WellKnownMimeTypes.MESSAGE_X_RSOCKET_COMPOSITE_METADATA_V0.name) { let compositeMetadata = payload.metadata; return compositeMetadata.route; } throw new Error('Failed to get route information from metadata'); } }