UNPKG

@financialforcedev/orizuru

Version:

Streamlined communication between Heroku dynos / other worker processes

221 lines 24 kB
"use strict"; /* * Copyright (c) 2017-2019, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); /** * @module server */ const events_1 = require("events"); const express_1 = __importDefault(require("express")); const __1 = require(".."); const route_1 = require("./server/route"); const ROUTE_METHOD = __importStar(require("./server/routeMethod")); const route_2 = require("./validator/route"); const server_1 = require("./validator/server"); const Router = express_1.default.Router; /** * The Server for creating routes in a web dyno based on Avro schemas. * * Messages are consumed by {@link Handler}. * @extends EventEmitter */ class Server extends events_1.EventEmitter { /** * Constructs a new 'Server'. * * @example * const server = new Server(); */ constructor(options) { super(); try { // Validate the server options new server_1.ServerValidator(options); this.options = options; // Add the server this.server = options.server || express_1.default(); // Add the publisher this.publisherImpl = new __1.Publisher(options); // Make sure that the publisher emits server error events this.publisher.on(__1.Publisher.ERROR, (...args) => { this.emit(Server.ERROR, ...args); }); // Make sure that the publisher emits server info events this.publisher.on(__1.Publisher.INFO, (...args) => { this.emit(Server.INFO, ...args); }); // Define the router configuration for the server this.routerConfiguration = {}; // Define the route validator this.validator = new route_2.RouteValidator(); } catch (e) { this.error(e); throw e; } } /** * Adds a route to the server. * * @param options The route configuration options. */ addRoute(options) { // Validate the route options. const validatedRouteConfiguration = this.validator.validate(options); const { apiEndpoint, middleware, fullSchemaName, method } = validatedRouteConfiguration; let router = this.routerConfiguration[apiEndpoint]; // If we don't have the router for this endpoint then we need to create one. if (!router) { this.info(`Creating router for namespace: ${apiEndpoint}.`); // Create router. router = Router(); // Add the router to the server. this.server.use(apiEndpoint, router); // Update the router configuration. this.routerConfiguration[apiEndpoint] = router; } this.info(`Adding route: ${fullSchemaName} (${method.toUpperCase()}).`); // Add the router method. router[method]('/', ...middleware, route_1.create(this, validatedRouteConfiguration)); return this; } /** * Starts the server listening for connections. * This also initialises the transport connection. * * @param [callback] Optional callback to invoke after the server has started listening to connections. */ async listen(callback) { await this.options.transport.connect(); this.httpServer = this.server.listen(this.options.port, () => { this.info(`Listening to new connections on port: ${this.options.port}.`); if (callback) { callback(this); } }); return this.httpServer; } /** * Stops the server from accepting new connections. * * @param [callback] Optional callback to invoke after the server has stopped listening to connections. */ async close(callback) { if (this.httpServer) { await this.httpServer.close(async () => { this.info(`Stopped listening to connections on port: ${this.options.port}.`); await this.options.transport.close(); if (callback) { callback(this); } }); } else { throw Error('The server has not started listening to connections.'); } } /** * Assigns setting `name` to `value`. * * @param setting The setting name. * @param val The setting value. */ set(setting, val) { this.server.set(setting, val); return this; } /** * Use the given request handlers for the specified paths. * * @param path The path for the incoming request. * @param handlers The middleware to be used when processing the incoming request. */ use(path, ...handlers) { this.server.use(path, ...handlers); return this; } /** * Returns the server implementation. * * Defaults to express. * * @example * // returns the server implementation * server.serverImpl.listen('8080'); * @returns The server implementation. */ get serverImpl() { return this.server; } /** * Returns the message publisher. * * @returns The message publisher. */ get publisher() { return this.publisherImpl; } /** * Emit an error event. * * @param event The error event. */ error(event) { this.emit(Server.ERROR, event); } /** * Emit an info event. * * @param event The info event. */ info(event) { this.emit(Server.INFO, event); } } /** * The HTTP methods (DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE) */ Server.ROUTE_METHOD = ROUTE_METHOD; /** * The error event symbol. */ Server.ERROR = Symbol(); /** * The info event symbol. */ Server.INFO = Symbol(); exports.Server = Server; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2luZGV4L3NlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRzs7Ozs7Ozs7Ozs7O0FBRUg7O0dBRUc7QUFFSCxtQ0FBc0M7QUFDdEMsc0RBQThCO0FBSTlCLDBCQUFxRDtBQUNyRCwwQ0FBdUQ7QUFDdkQsbUVBQXFEO0FBQ3JELDZDQUFtRDtBQUNuRCwrQ0FBcUQ7QUFFckQsTUFBTSxNQUFNLEdBQUcsaUJBQU8sQ0FBQyxNQUFNLENBQUM7QUFFOUI7Ozs7O0dBS0c7QUFDSCxNQUFhLE1BQU8sU0FBUSxxQkFBWTtJQXVEdkM7Ozs7O09BS0c7SUFDSCxZQUFZLE9BQXdCO1FBRW5DLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSTtZQUVILDhCQUE4QjtZQUM5QixJQUFJLHdCQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFFdkIsaUJBQWlCO1lBQ2pCLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxpQkFBTyxFQUFFLENBQUM7WUFFMUMsb0JBQW9CO1lBQ3BCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxhQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFNUMsMERBQTBEO1lBQzFELElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLElBQVcsRUFBRSxFQUFFO2dCQUNyRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztZQUVILHlEQUF5RDtZQUN6RCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxhQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFX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TUFBTSxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztTQUNwRTtJQUNGLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLEdBQUcsQ0FBQyxPQUFlLEVBQUUsR0FBUTtRQUNuQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDOUIsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxHQUFHLENBQUMsSUFBWSxFQUFFLEdBQUcsUUFBcUQ7UUFDaEYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsSUFBVyxVQUFVO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNwQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQVcsU0FBUztRQUNuQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsS0FBVTtRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxJQUFJLENBQUMsS0FBVTtRQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQzs7QUE5T0Q7O0dBRUc7QUFDb0IsbUJBQVksR0FBRyxZQUFZLENBQUM7QUFFbkQ7O0dBRUc7QUFDb0IsWUFBSyxHQUFHLE1BQU0sRUFBRSxDQUFDO0FBRXhDOztHQUVHO0FBQ29CLFdBQUksR0FBRyxNQUFNLEVBQUUsQ0FBQztBQWZ4Qyx3QkFrUEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LTIwMTksIEZpbmFuY2lhbEZvcmNlLmNvbSwgaW5jXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXG4gKiAgIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAtIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqIC0gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICogLSBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBGaW5hbmNpYWxGb3JjZS5jb20sIGluYyBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiAqICAgICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcbiAqICAgICAgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORFxuICogIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVNcbiAqICBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTFxuICogIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLFxuICogIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EU1xuICogIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWVxuICogIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuICogIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbi8qKlxuICogQG1vZHVsZSBzZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudHMnO1xuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBFcnJvclJlcXVlc3RIYW5kbGVyLCBSZXF1ZXN0SGFuZGxlciB9IGZyb20gJ2V4cHJlc3Mtc2VydmUtc3RhdGljLWNvcmUnO1xuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5cbmltcG9ydCB7IElTZXJ2ZXJJbXBsLCBPcHRpb25zLCBQdWJsaXNoZXIgfSBmcm9tICcuLic7XG5pbXBvcnQgeyBjcmVhdGUgYXMgY3JlYXRlUm91dGUgfSBmcm9tICcuL3NlcnZlci9yb3V0ZSc7XG5pbXBvcnQgKiBhcyBST1VURV9NRVRIT0QgZnJvbSAnLi9zZXJ2ZXIvcm91dGVNZXRob2QnO1xuaW1wb3J0IHsgUm91dGVWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvci9yb3V0ZSc7XG5pbXBvcnQgeyBTZXJ2ZXJWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvci9zZXJ2ZXInO1xuXG5jb25zdCBSb3V0ZXIgPSBleHByZXNzLlJvdXRlcjtcblxuLyoqXG4gKiBUaGUgU2VydmVyIGZvciBjcmVhdGluZyByb3V0ZXMgaW4gYSB3ZWIgZHlubyBiYXNlZCBvbiBBdnJvIHNjaGVtYXMuXG4gKlxuICogTWVzc2FnZXMgYXJlIGNvbnN1bWVkIGJ5IHtAbGluayBIYW5kbGVyfS5cbiAqIEBleHRlbmRzIEV2ZW50RW1pdHRlclxuICovXG5leHBvcnQgY2xhc3MgU2VydmVyIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuXHQvKipcblx0ICogVGhlIEhUVFAgbWV0aG9kcyAoREVMRVRFLCBHRVQsIEhFQUQsIE9QVElPTlMsIFBBVENILCBQT1NULCBQVVQsIFRSQUNFKVxuXHQgKi9cblx0cHVibGljIHN0YXRpYyByZWFkb25seSBST1VURV9NRVRIT0QgPSBST1VURV9NRVRIT0Q7XG5cblx0LyoqXG5cdCAqIFRoZSBlcnJvciBldmVudCBzeW1ib2wuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEVSUk9SID0gU3ltYm9sKCk7XG5cblx0LyoqXG5cdCAqIFRoZSBpbmZvIGV2ZW50IHN5bWJvbC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSU5GTyA9IFN5bWJvbCgpO1xuXG5cdC8qKlxuXHQgKiBUaGUgc2VydmVyIG9wdGlvbnMuXG5cdCAqL1xuXHRwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogT3B0aW9ucy5JU2VydmVyO1xuXG5cdC8qKlxuXHQgKiBUaGUgcHVibGlzaGVyIHRoYXQgaXMgdXNlZCB0byBwdWJsaXNoIE9yaXp1cnUgbWVzc2FnZXMgdmlhIHRoZSB0cmFuc3BvcnQgbGF5ZXIuXG5cdCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IHB1Ymxpc2hlckltcGw6IFB1Ymxpc2hlcjtcblxuXHQvKipcblx0ICogVGhlIHNlcnZlciBpbXBsZW1lbnRhdGlvbi5cblx0ICpcblx0ICogRXhwcmVzcyBpcyB1c2VkIGJ5IGRlZmF1bHQuXG5cdCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IHNlcnZlcjogSVNlcnZlckltcGw7XG5cblx0LyoqXG5cdCAqIFRoZSByb3V0ZSB2YWxpZGF0b3IuXG5cdCAqXG5cdCAqIFRoaXMgdmFsaWRhdGVzIHRoYXQgdGhlIHJvdXRlcyB0aGF0IGFyZSBhZGRlZCB0byB0aGUgc2VydmVyIGNvbnRhaW4gdGhlIGNvcnJlY3QgaW5mb3JtYXRpb24uXG5cdCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IHZhbGlkYXRvcjogUm91dGVWYWxpZGF0b3I7XG5cblx0LyoqXG5cdCAqIEFuIGludGVybmFsIG1hcCBvZiBlYWNoIG9mIHRoZSByb3V0ZXMgdG8gdGhlIGFwcHJvcHJpYXRlIEV4cHJlc3MgUm91dGVyLlxuXHQgKlxuXHQgKiBGb3IgZXhhbXBsZSwgaWYgYSByb3V0ZSBpcyBhZGRlZCB1c2luZyB0aGUgR0VUIGFuZCBQT1NUIG1ldGhvZCwgdGhlIG1hcCBjb250YWluc1xuXHQgKiBhIHNpbmdsZSBlbnRyeSBmb3IgdGhlIHJvdXRlIHdpdGggYm90aCB0aGUgR0VUIGFuZCBQT1NUIG1ldGhvZHMgYWRkZWQgdG8gYSBzaW5nbGVcblx0ICogcm91dGVyLlxuXHQgKi9cblx0cHJpdmF0ZSByZWFkb25seSByb3V0ZXJDb25maWd1cmF0aW9uOiB7IFtzOiBzdHJpbmddOiBleHByZXNzLlJvdXRlciB9O1xuXG5cdC8qKlxuXHQgKiBUaGUgcm9vdCBIVFRQIHNlcnZlciB0aGF0IGlzIHVzZWQgdG8gcmVjaWV2ZSBpbmNvbWluZyB0cmFmZmljLlxuXHQgKi9cblx0cHJpdmF0ZSBodHRwU2VydmVyPzogaHR0cC5TZXJ2ZXI7XG5cblx0LyoqXG5cdCAqIENvbnN0cnVjdHMgYSBuZXcgJ1NlcnZlcicuXG5cdCAqXG5cdCAqIEBleGFtcGxlXG5cdCAqIGNvbnN0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoKTtcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMuSVNlcnZlcikge1xuXG5cdFx0c3VwZXIoKTtcblxuXHRcdHRyeSB7XG5cblx0XHRcdC8vIFZhbGlkYXRlIHRoZSBzZXJ2ZXIgb3B0aW9uc1xuXHRcdFx0bmV3IFNlcnZlclZhbGlkYXRvcihvcHRpb25zKTtcblxuXHRcdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuXHRcdFx0Ly8gQWRkIHRoZSBzZXJ2ZXJcblx0XHRcdHRoaXMuc2VydmVyID0gb3B0aW9ucy5zZXJ2ZXIgfHwgZXhwcmVzcygpO1xuXG5cdFx0XHQvLyBBZGQgdGhlIHB1Ymxpc2hlclxuXHRcdFx0dGhpcy5wdWJsaXNoZXJJbXBsID0gbmV3IFB1Ymxpc2hlcihvcHRpb25zKTtcblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgIHRoZSBwdWJsaXNoZXIgZW1pdHMgc2VydmVyIGVycm9yIGV2ZW50c1xuXHRcdFx0dGhpcy5wdWJsaXNoZXIub24oUHVibGlzaGVyLkVSUk9SLCAoLi4uYXJnczogYW55W10pID0+IHtcblx0XHRcdFx0dGhpcy5lbWl0KFNlcnZlci5FUlJPUiwgLi4uYXJncyk7XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgIHRoZSBwdWJsaXNoZXIgZW1pdHMgc2VydmVyIGluZm8gZXZlbnRzXG5cdFx0XHR0aGlzLnB1Ymxpc2hlci5vbihQdWJsaXNoZXIuSU5GTywgKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG5cdFx0XHRcdHRoaXMuZW1pdChTZXJ2ZXIuSU5GTywgLi4uYXJncyk7XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gRGVmaW5lIHRoZSByb3V0ZXIgY29uZmlndXJhdGlvbiBmb3IgdGhlIHNlcnZlclxuXHRcdFx0dGhpcy5yb3V0ZXJDb25maWd1cmF0aW9uID0ge307XG5cblx0XHRcdC8vIERlZmluZSB0aGUgcm91dGUgdmFsaWRhdG9yXG5cdFx0XHR0aGlzLnZhbGlkYXRvciA9IG5ldyBSb3V0ZVZhbGlkYXRvcigpO1xuXG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0dGhpcy5lcnJvcihlKTtcblx0XHRcdHRocm93IGU7XG5cdFx0fVxuXG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIHJvdXRlIHRvIHRoZSBzZXJ2ZXIuXG5cdCAqXG5cdCAqIEBwYXJhbSBvcHRpb25zIFRoZSByb3V0ZSBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAqL1xuXHRwdWJsaWMgYWRkUm91dGUob3B0aW9uczogT3B0aW9ucy5JUm91dGVDb25maWd1cmF0aW9uKSB7XG5cblx0XHQvLyBWYWxpZGF0ZSB0aGUgcm91dGUgb3B0aW9ucy5cblx0XHRjb25zdCB2YWxpZGF0ZWRSb3V0ZUNvbmZpZ3VyYXRpb24gPSB0aGlzLnZhbGlkYXRvci52YWxpZGF0ZShvcHRpb25zKTtcblxuXHRcdGNvbnN0IHsgYXBpRW5kcG9pbnQsIG1pZGRsZXdhcmUsIGZ1bGxTY2hlbWFOYW1lLCBtZXRob2QgfSA9IHZhbGlkYXRlZFJvdXRlQ29uZmlndXJhdGlvbjtcblxuXHRcdGxldCByb3V0ZXI6IGFueSA9IHRoaXMucm91dGVyQ29uZmlndXJhdGlvblthcGlFbmRwb2ludF07XG5cblx0XHQvLyBJZiB3ZSBkb24ndCBoYXZlIHRoZSByb3V0ZXIgZm9yIHRoaXMgZW5kcG9pbnQgdGhlbiB3ZSBuZWVkIHRvIGNyZWF0ZSBvbmUuXG5cdFx0aWYgKCFyb3V0ZXIpIHtcblxuXHRcdFx0dGhpcy5pbmZvKGBDcmVhdGluZyByb3V0ZXIgZm9yIG5hbWVzcGFjZTogJHthcGlFbmRwb2ludH0uYCk7XG5cblx0XHRcdC8vIENyZWF0ZSByb3V0ZXIuXG5cdFx0XHRyb3V0ZXIgPSBSb3V0ZXIoKTtcblxuXHRcdFx0Ly8gQWRkIHRoZSByb3V0ZXIgdG8gdGhlIHNlcnZlci5cblx0XHRcdHRoaXMuc2VydmVyLnVzZShhcGlFbmRwb2ludCwgcm91dGVyKTtcblxuXHRcdFx0Ly8gVXBkYXRlIHRoZSByb3V0ZXIgY29uZmlndXJhdGlvbi5cblx0XHRcdHRoaXMucm91dGVyQ29uZmlndXJhdGlvblthcGlFbmRwb2ludF0gPSByb3V0ZXI7XG5cblx0XHR9XG5cblx0XHR0aGlzLmluZm8oYEFkZGluZyByb3V0ZTogJHtmdWxsU2NoZW1hTmFtZX0gKCR7bWV0aG9kLnRvVXBwZXJDYXNlKCl9KS5gKTtcblxuXHRcdC8vIEFkZCB0aGUgcm91dGVyIG1ldGhvZC5cblx0XHRyb3V0ZXJbbWV0aG9kXSgnLycsIC4uLm1pZGRsZXdhcmUsIGNyZWF0ZVJvdXRlKHRoaXMsIHZhbGlkYXRlZFJvdXRlQ29uZmlndXJhdGlvbikpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgdGhlIHNlcnZlciBsaXN0ZW5pbmcgZm9yIGNvbm5lY3Rpb25zLlxuXHQgKiBUaGlzIGFsc28gaW5pdGlhbGlzZXMgdGhlIHRyYW5zcG9ydCBjb25uZWN0aW9uLlxuXHQgKlxuXHQgKiBAcGFyYW0gW2NhbGxiYWNrXSBPcHRpb25hbCBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlIHNlcnZlciBoYXMgc3RhcnRlZCBsaXN0ZW5pbmcgdG8gY29ubmVjdGlvbnMuXG5cdCAqL1xuXHRwdWJsaWMgYXN5bmMgbGlzdGVuKGNhbGxiYWNrPzogKGFwcDogT3JpenVydS5JU2VydmVyKSA9PiB2b2lkKSB7XG5cblx0XHRhd2FpdCB0aGlzLm9wdGlvbnMudHJhbnNwb3J0LmNvbm5lY3QoKTtcblxuXHRcdHRoaXMuaHR0cFNlcnZlciA9IHRoaXMuc2VydmVyLmxpc3Rlbih0aGlzLm9wdGlvbnMucG9ydCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5pbmZvKGBMaXN0ZW5pbmcgdG8gbmV3IGNvbm5lY3Rpb25zIG9uIHBvcnQ6ICR7dGhpcy5vcHRpb25zLnBvcnR9LmApO1xuXHRcdFx0aWYgKGNhbGxiYWNrKSB7XG5cdFx0XHRcdGNhbGxiYWNrKHRoaXMpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzLmh0dHBTZXJ2ZXI7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTdG9wcyB0aGUgc2VydmVyIGZyb20gYWNjZXB0aW5nIG5ldyBjb25uZWN0aW9ucy5cblx0ICpcblx0ICogQHBhcmFtIFtjYWxsYmFja10gT3B0aW9uYWwgY2FsbGJhY2sgdG8gaW52b2tlIGFmdGVyIHRoZSBzZXJ2ZXIgaGFzIHN0b3BwZWQgbGlzdGVuaW5nIHRvIGNvbm5lY3Rpb25zLlxuXHQgKi9cblx0cHVibGljIGFzeW5jIGNsb3NlKGNhbGxiYWNrPzogKGFwcDogT3JpenVydS5JU2VydmVyKSA9PiB2b2lkKSB7XG5cdFx0aWYgKHRoaXMuaHR0cFNlcnZlcikge1xuXHRcdFx0YXdhaXQgdGhpcy5odHRwU2VydmVyLmNsb3NlKGFzeW5jICgpID0+IHtcblx0XHRcdFx0dGhpcy5pbmZvKGBTdG9wcGVkIGxpc3RlbmluZyB0byBjb25uZWN0aW9ucyBvbiBwb3J0OiAke3RoaXMub3B0aW9ucy5wb3J0fS5gKTtcblx0XHRcdFx0YXdhaXQgdGhpcy5vcHRpb25zLnRyYW5zcG9ydC5jbG9zZSgpO1xuXHRcdFx0XHRpZiAoY2FsbGJhY2spIHtcblx0XHRcdFx0XHRjYWxsYmFjayh0aGlzKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IEVycm9yKCdUaGUgc2VydmVyIGhhcyBub3Qgc3RhcnRlZCBsaXN0ZW5pbmcgdG8gY29ubmVjdGlvbnMuJyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFzc2lnbnMgc2V0dGluZyBgbmFtZWAgdG8gYHZhbHVlYC5cblx0ICpcblx0ICogQHBhcmFtIHNldHRpbmcgVGhlIHNldHRpbmcgbmFtZS5cblx0ICogQHBhcmFtIHZhbCBUaGUgc2V0dGluZyB2YWx1ZS5cblx0ICovXG5cdHB1YmxpYyBzZXQoc2V0dGluZzogc3RyaW5nLCB2YWw6IGFueSkge1xuXHRcdHRoaXMuc2VydmVyLnNldChzZXR0aW5nLCB2YWwpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVzZSB0aGUgZ2l2ZW4gcmVxdWVzdCBoYW5kbGVycyBmb3IgdGhlIHNwZWNpZmllZCBwYXRocy5cblx0ICpcblx0ICogQHBhcmFtIHBhdGggVGhlIHBhdGggZm9yIHRoZSBpbmNvbWluZyByZXF1ZXN0LlxuXHQgKiBAcGFyYW0gaGFuZGxlcnMgVGhlIG1pZGRsZXdhcmUgdG8gYmUgdXNlZCB3aGVuIHByb2Nlc3NpbmcgdGhlIGluY29taW5nIHJlcXVlc3QuXG5cdCAqL1xuXHRwdWJsaWMgdXNlKHBhdGg6IHN0cmluZywgLi4uaGFuZGxlcnM6IEFycmF5PEVycm9yUmVxdWVzdEhhbmRsZXIgfCBSZXF1ZXN0SGFuZGxlcj4pIHtcblx0XHR0aGlzLnNlcnZlci51c2UocGF0aCwgLi4uaGFuZGxlcnMpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHNlcnZlciBpbXBsZW1lbnRhdGlvbi5cblx0ICpcblx0ICogRGVmYXVsdHMgdG8gZXhwcmVzcy5cblx0ICpcblx0ICogQGV4YW1wbGVcblx0ICogLy8gcmV0dXJucyB0aGUgc2VydmVyIGltcGxlbWVudGF0aW9uXG5cdCAqIHNlcnZlci5zZXJ2ZXJJbXBsLmxpc3RlbignODA4MCcpO1xuXHQgKiBAcmV0dXJucyBUaGUgc2VydmVyIGltcGxlbWVudGF0aW9uLlxuXHQgKi9cblx0cHVibGljIGdldCBzZXJ2ZXJJbXBsKCkge1xuXHRcdHJldHVybiB0aGlzLnNlcnZlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBtZXNzYWdlIHB1Ymxpc2hlci5cblx0ICpcblx0ICogQHJldHVybnMgVGhlIG1lc3NhZ2UgcHVibGlzaGVyLlxuXHQgKi9cblx0cHVibGljIGdldCBwdWJsaXNoZXIoKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVibGlzaGVySW1wbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbWl0IGFuIGVycm9yIGV2ZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0gZXZlbnQgVGhlIGVycm9yIGV2ZW50LlxuXHQgKi9cblx0cHVibGljIGVycm9yKGV2ZW50OiBhbnkpIHtcblx0XHR0aGlzLmVtaXQoU2VydmVyLkVSUk9SLCBldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogRW1pdCBhbiBpbmZvIGV2ZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0gZXZlbnQgVGhlIGluZm8gZXZlbnQuXG5cdCAqL1xuXHRwdWJsaWMgaW5mbyhldmVudDogYW55KSB7XG5cdFx0dGhpcy5lbWl0KFNlcnZlci5JTkZPLCBldmVudCk7XG5cdH1cblxufVxuIl19