@financialforcedev/orizuru
Version:
Streamlined communication between Heroku dynos / other worker processes
221 lines • 24 kB
JavaScript
"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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2luZGV4L3NlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRzs7Ozs7Ozs7Ozs7O0FBRUg7O0dBRUc7QUFFSCxtQ0FBc0M7QUFDdEMsc0RBQThCO0FBSTlCLDBCQUFxRDtBQUNyRCwwQ0FBdUQ7QUFDdkQsbUVBQXFEO0FBQ3JELDZDQUFtRDtBQUNuRCwrQ0FBcUQ7QUFFckQsTUFBTSxNQUFNLEdBQUcsaUJBQU8sQ0FBQyxNQUFNLENBQUM7QUFFOUI7Ozs7O0dBS0c7QUFDSCxNQUFhLE1BQU8sU0FBUSxxQkFBWTtJQXVEdkM7Ozs7O09BS0c7SUFDSCxZQUFZLE9BQXdCO1FBRW5DLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSTtZQUVILDhCQUE4QjtZQUM5QixJQUFJLHdCQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFFdkIsaUJBQWlCO1lBQ2pCLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxpQkFBTyxFQUFFLENBQUM7WUFFMUMsb0JBQW9CO1lBQ3BCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxhQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFNUMsMERBQTBEO1lBQzFELElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLElBQVcsRUFBRSxFQUFFO2dCQUNyRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztZQUVILHlEQUF5RDtZQUN6RCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxhQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFXLEVBQUUsRUFBRTtnQkFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDakMsQ0FBQyxDQUFDLENBQUM7WUFFSCxpREFBaUQ7WUFDakQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEVBQUUsQ0FBQztZQUU5Qiw2QkFBNkI7WUFDN0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLHNCQUFjLEVBQUUsQ0FBQztTQUV0QztRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNkLE1BQU0sQ0FBQyxDQUFDO1NBQ1I7SUFFRixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLFFBQVEsQ0FBQyxPQUFvQztRQUVuRCw4QkFBOEI7UUFDOUIsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVyRSxNQUFNLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLEdBQUcsMkJBQTJCLENBQUM7UUFFeEYsSUFBSSxNQUFNLEdBQVEsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXhELDRFQUE0RTtRQUM1RSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBRVosSUFBSSxDQUFDLElBQUksQ0FBQyxrQ0FBa0MsV0FBVyxHQUFHLENBQUMsQ0FBQztZQUU1RCxpQkFBaUI7WUFDakIsTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDO1lBRWxCLGdDQUFnQztZQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFFckMsbUNBQW1DO1lBQ25DLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUM7U0FFL0M7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixjQUFjLEtBQUssTUFBTSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV4RSx5QkFBeUI7UUFDekIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFVBQVUsRUFBRSxjQUFXLENBQUMsSUFBSSxFQUFFLDJCQUEyQixDQUFDLENBQUMsQ0FBQztRQUVuRixPQUFPLElBQUksQ0FBQztJQUViLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBeUM7UUFFNUQsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV2QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTtZQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7WUFDekUsSUFBSSxRQUFRLEVBQUU7Z0JBQ2IsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2Y7UUFDRixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUV4QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBeUM7UUFDM0QsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsNkNBQTZDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztnQkFDN0UsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxRQUFRLEVBQUU7b0JBQ2IsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUNmO1lBQ0YsQ0FBQyxDQUFDLENBQUM7U0FDSDthQUFNO1lBQ04sTUFBTSxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztTQUNwRTtJQUNGLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLEdBQUcsQ0FBQyxPQUFlLEVBQUUsR0FBUTtRQUNuQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDOUIsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxHQUFHLENBQUMsSUFBWSxFQUFFLEdBQUcsUUFBcUQ7UUFDaEYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsSUFBVyxVQUFVO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNwQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQVcsU0FBUztRQUNuQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsS0FBVTtRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxJQUFJLENBQUMsS0FBVTtRQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQzs7QUE5T0Q7O0dBRUc7QUFDb0IsbUJBQVksR0FBRyxZQUFZLENBQUM7QUFFbkQ7O0dBRUc7QUFDb0IsWUFBSyxHQUFHLE1BQU0sRUFBRSxDQUFDO0FBRXhDOztHQUVHO0FBQ29CLFdBQUksR0FBRyxNQUFNLEVBQUUsQ0FBQztBQWZ4Qyx3QkFrUEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LTIwMTksIEZpbmFuY2lhbEZvcmNlLmNvbSwgaW5jXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXG4gKiAgIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAtIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqIC0gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICogLSBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBGaW5hbmNpYWxGb3JjZS5jb20sIGluYyBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiAqICAgICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcbiAqICAgICAgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORFxuICogIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVNcbiAqICBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTFxuICogIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLFxuICogIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EU1xuICogIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWVxuICogIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuICogIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbi8qKlxuICogQG1vZHVsZSBzZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudHMnO1xuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBFcnJvclJlcXVlc3RIYW5kbGVyLCBSZXF1ZXN0SGFuZGxlciB9IGZyb20gJ2V4cHJlc3Mtc2VydmUtc3RhdGljLWNvcmUnO1xuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5cbmltcG9ydCB7IElTZXJ2ZXJJbXBsLCBPcHRpb25zLCBQdWJsaXNoZXIgfSBmcm9tICcuLic7XG5pbXBvcnQgeyBjcmVhdGUgYXMgY3JlYXRlUm91dGUgfSBmcm9tICcuL3NlcnZlci9yb3V0ZSc7XG5pbXBvcnQgKiBhcyBST1VURV9NRVRIT0QgZnJvbSAnLi9zZXJ2ZXIvcm91dGVNZXRob2QnO1xuaW1wb3J0IHsgUm91dGVWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvci9yb3V0ZSc7XG5pbXBvcnQgeyBTZXJ2ZXJWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvci9zZXJ2ZXInO1xuXG5jb25zdCBSb3V0ZXIgPSBleHByZXNzLlJvdXRlcjtcblxuLyoqXG4gKiBUaGUgU2VydmVyIGZvciBjcmVhdGluZyByb3V0ZXMgaW4gYSB3ZWIgZHlubyBiYXNlZCBvbiBBdnJvIHNjaGVtYXMuXG4gKlxuICogTWVzc2FnZXMgYXJlIGNvbnN1bWVkIGJ5IHtAbGluayBIYW5kbGVyfS5cbiAqIEBleHRlbmRzIEV2ZW50RW1pdHRlclxuICovXG5leHBvcnQgY2xhc3MgU2VydmVyIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuXHQvKipcblx0ICogVGhlIEhUVFAgbWV0aG9kcyAoREVMRVRFLCBHRVQsIEhFQUQsIE9QVElPTlMsIFBBVENILCBQT1NULCBQVVQsIFRSQUNFKVxuXHQgKi9cblx0cHVibGljIHN0YXRpYyByZWFkb25seSBST1VURV9NRVRIT0QgPSBST1VURV9NRVRIT0Q7XG5cblx0LyoqXG5cdCAqIFRoZSBlcnJvciBldmVudCBzeW1ib2wuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEVSUk9SID0gU3ltYm9sKCk7XG5cblx0LyoqXG5cdCAqIFRoZSBpbmZvIGV2ZW50IHN5bWJvbC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSU5GTyA9IFN5bWJvbCgpO1xuXG5cdC8qKlxuXHQgKiBUaGUgc2VydmVyIG9wdGlvbnMuXG5cdCAqL1xuXHRwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogT3B0aW9ucy5JU2VydmVyO1xuXG5cdC8qKlxuXHQgKiBUaGUgcHVibGlzaGVyIHRoYXQgaXMgdXNlZCB0byBwdWJsaXNoIE9yaXp1cnUgbWVzc2FnZXMgdmlhIHRoZSB0cmFuc3BvcnQgbGF5ZXIuXG5cdCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IHB1Ymxpc2hlckltcGw6IFB1Ymxpc2hlcjtcblxuXHQvKipcblx0ICogVGhlIHNlcnZlciBpbXBsZW1lbnRhdGlvbi5cblx0ICpcblx0ICogRXhwcmVzcyBpcyB1c2VkIGJ5IGRlZmF1bHQuXG5cdCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IHNlcnZlcjogSVNlcnZlckltcGw7XG5cblx0LyoqXG5cdCAqIFRoZSByb3V0ZSB2YWxpZGF0b3IuXG5cdCAqXG5cdCAqIFRoaXMgdmFsaWRhdGVzIHRoYXQgdGhlIHJvdXRlcyB0aGF0IGFyZSBhZGRlZCB0byB0aGUgc2VydmVyIGNvbnRhaW4gdGhlIGNvcnJlY3QgaW5mb3JtYXRpb24uXG5cdCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IHZhbGlkYXRvcjogUm91dGVWYWxpZGF0b3I7XG5cblx0LyoqXG5cdCAqIEFuIGludGVybmFsIG1hcCBvZiBlYWNoIG9mIHRoZSByb3V0ZXMgdG8gdGhlIGFwcHJvcHJpYXRlIEV4cHJlc3MgUm91dGVyLlxuXHQgKlxuXHQgKiBGb3IgZXhhbXBsZSwgaWYgYSByb3V0ZSBpcyBhZGRlZCB1c2luZyB0aGUgR0VUIGFuZCBQT1NUIG1ldGhvZCwgdGhlIG1hcCBjb250YWluc1xuXHQgKiBhIHNpbmdsZSBlbnRyeSBmb3IgdGhlIHJvdXRlIHdpdGggYm90aCB0aGUgR0VUIGFuZCBQT1NUIG1ldGhvZHMgYWRkZWQgdG8gYSBzaW5nbGVcblx0ICogcm91dGVyLlxuXHQgKi9cblx0cHJpdmF0ZSByZWFkb25seSByb3V0ZXJDb25maWd1cmF0aW9uOiB7IFtzOiBzdHJpbmddOiBleHByZXNzLlJvdXRlciB9O1xuXG5cdC8qKlxuXHQgKiBUaGUgcm9vdCBIVFRQIHNlcnZlciB0aGF0IGlzIHVzZWQgdG8gcmVjaWV2ZSBpbmNvbWluZyB0cmFmZmljLlxuXHQgKi9cblx0cHJpdmF0ZSBodHRwU2VydmVyPzogaHR0cC5TZXJ2ZXI7XG5cblx0LyoqXG5cdCAqIENvbnN0cnVjdHMgYSBuZXcgJ1NlcnZlcicuXG5cdCAqXG5cdCAqIEBleGFtcGxlXG5cdCAqIGNvbnN0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoKTtcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMuSVNlcnZlcikge1xuXG5cdFx0c3VwZXIoKTtcblxuXHRcdHRyeSB7XG5cblx0XHRcdC8vIFZhbGlkYXRlIHRoZSBzZXJ2ZXIgb3B0aW9uc1xuXHRcdFx0bmV3IFNlcnZlclZhbGlkYXRvcihvcHRpb25zKTtcblxuXHRcdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuXHRcdFx0Ly8gQWRkIHRoZSBzZXJ2ZXJcblx0XHRcdHRoaXMuc2VydmVyID0gb3B0aW9ucy5zZXJ2ZXIgfHwgZXhwcmVzcygpO1xuXG5cdFx0XHQvLyBBZGQgdGhlIHB1Ymxpc2hlclxuXHRcdFx0dGhpcy5wdWJsaXNoZXJJbXBsID0gbmV3IFB1Ymxpc2hlcihvcHRpb25zKTtcblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgIHRoZSBwdWJsaXNoZXIgZW1pdHMgc2VydmVyIGVycm9yIGV2ZW50c1xuXHRcdFx0dGhpcy5wdWJsaXNoZXIub24oUHVibGlzaGVyLkVSUk9SLCAoLi4uYXJnczogYW55W10pID0+IHtcblx0XHRcdFx0dGhpcy5lbWl0KFNlcnZlci5FUlJPUiwgLi4uYXJncyk7XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgIHRoZSBwdWJsaXNoZXIgZW1pdHMgc2VydmVyIGluZm8gZXZlbnRzXG5cdFx0XHR0aGlzLnB1Ymxpc2hlci5vbihQdWJsaXNoZXIuSU5GTywgKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG5cdFx0XHRcdHRoaXMuZW1pdChTZXJ2ZXIuSU5GTywgLi4uYXJncyk7XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gRGVmaW5lIHRoZSByb3V0ZXIgY29uZmlndXJhdGlvbiBmb3IgdGhlIHNlcnZlclxuXHRcdFx0dGhpcy5yb3V0ZXJDb25maWd1cmF0aW9uID0ge307XG5cblx0XHRcdC8vIERlZmluZSB0aGUgcm91dGUgdmFsaWRhdG9yXG5cdFx0XHR0aGlzLnZhbGlkYXRvciA9IG5ldyBSb3V0ZVZhbGlkYXRvcigpO1xuXG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0dGhpcy5lcnJvcihlKTtcblx0XHRcdHRocm93IGU7XG5cdFx0fVxuXG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIHJvdXRlIHRvIHRoZSBzZXJ2ZXIuXG5cdCAqXG5cdCAqIEBwYXJhbSBvcHRpb25zIFRoZSByb3V0ZSBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAqL1xuXHRwdWJsaWMgYWRkUm91dGUob3B0aW9uczogT3B0aW9ucy5JUm91dGVDb25maWd1cmF0aW9uKSB7XG5cblx0XHQvLyBWYWxpZGF0ZSB0aGUgcm91dGUgb3B0aW9ucy5cblx0XHRjb25zdCB2YWxpZGF0ZWRSb3V0ZUNvbmZpZ3VyYXRpb24gPSB0aGlzLnZhbGlkYXRvci52YWxpZGF0ZShvcHRpb25zKTtcblxuXHRcdGNvbnN0IHsgYXBpRW5kcG9pbnQsIG1pZGRsZXdhcmUsIGZ1bGxTY2hlbWFOYW1lLCBtZXRob2QgfSA9IHZhbGlkYXRlZFJvdXRlQ29uZmlndXJhdGlvbjtcblxuXHRcdGxldCByb3V0ZXI6IGFueSA9IHRoaXMucm91dGVyQ29uZmlndXJhdGlvblthcGlFbmRwb2ludF07XG5cblx0XHQvLyBJZiB3ZSBkb24ndCBoYXZlIHRoZSByb3V0ZXIgZm9yIHRoaXMgZW5kcG9pbnQgdGhlbiB3ZSBuZWVkIHRvIGNyZWF0ZSBvbmUuXG5cdFx0aWYgKCFyb3V0ZXIpIHtcblxuXHRcdFx0dGhpcy5pbmZvKGBDcmVhdGluZyByb3V0ZXIgZm9yIG5hbWVzcGFjZTogJHthcGlFbmRwb2ludH0uYCk7XG5cblx0XHRcdC8vIENyZWF0ZSByb3V0ZXIuXG5cdFx0XHRyb3V0ZXIgPSBSb3V0ZXIoKTtcblxuXHRcdFx0Ly8gQWRkIHRoZSByb3V0ZXIgdG8gdGhlIHNlcnZlci5cblx0XHRcdHRoaXMuc2VydmVyLnVzZShhcGlFbmRwb2ludCwgcm91dGVyKTtcblxuXHRcdFx0Ly8gVXBkYXRlIHRoZSByb3V0ZXIgY29uZmlndXJhdGlvbi5cblx0XHRcdHRoaXMucm91dGVyQ29uZmlndXJhdGlvblthcGlFbmRwb2ludF0gPSByb3V0ZXI7XG5cblx0XHR9XG5cblx0XHR0aGlzLmluZm8oYEFkZGluZyByb3V0ZTogJHtmdWxsU2NoZW1hTmFtZX0gKCR7bWV0aG9kLnRvVXBwZXJDYXNlKCl9KS5gKTtcblxuXHRcdC8vIEFkZCB0aGUgcm91dGVyIG1ldGhvZC5cblx0XHRyb3V0ZXJbbWV0aG9kXSgnLycsIC4uLm1pZGRsZXdhcmUsIGNyZWF0ZVJvdXRlKHRoaXMsIHZhbGlkYXRlZFJvdXRlQ29uZmlndXJhdGlvbikpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgdGhlIHNlcnZlciBsaXN0ZW5pbmcgZm9yIGNvbm5lY3Rpb25zLlxuXHQgKiBUaGlzIGFsc28gaW5pdGlhbGlzZXMgdGhlIHRyYW5zcG9ydCBjb25uZWN0aW9uLlxuXHQgKlxuXHQgKiBAcGFyYW0gW2NhbGxiYWNrXSBPcHRpb25hbCBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlIHNlcnZlciBoYXMgc3RhcnRlZCBsaXN0ZW5pbmcgdG8gY29ubmVjdGlvbnMuXG5cdCAqL1xuXHRwdWJsaWMgYXN5bmMgbGlzdGVuKGNhbGxiYWNrPzogKGFwcDogT3JpenVydS5JU2VydmVyKSA9PiB2b2lkKSB7XG5cblx0XHRhd2FpdCB0aGlzLm9wdGlvbnMudHJhbnNwb3J0LmNvbm5lY3QoKTtcblxuXHRcdHRoaXMuaHR0cFNlcnZlciA9IHRoaXMuc2VydmVyLmxpc3Rlbih0aGlzLm9wdGlvbnMucG9ydCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5pbmZvKGBMaXN0ZW5pbmcgdG8gbmV3IGNvbm5lY3Rpb25zIG9uIHBvcnQ6ICR7dGhpcy5vcHRpb25zLnBvcnR9LmApO1xuXHRcdFx0aWYgKGNhbGxiYWNrKSB7XG5cdFx0XHRcdGNhbGxiYWNrKHRoaXMpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzLmh0dHBTZXJ2ZXI7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTdG9wcyB0aGUgc2VydmVyIGZyb20gYWNjZXB0aW5nIG5ldyBjb25uZWN0aW9ucy5cblx0ICpcblx0ICogQHBhcmFtIFtjYWxsYmFja10gT3B0aW9uYWwgY2FsbGJhY2sgdG8gaW52b2tlIGFmdGVyIHRoZSBzZXJ2ZXIgaGFzIHN0b3BwZWQgbGlzdGVuaW5nIHRvIGNvbm5lY3Rpb25zLlxuXHQgKi9cblx0cHVibGljIGFzeW5jIGNsb3NlKGNhbGxiYWNrPzogKGFwcDogT3JpenVydS5JU2VydmVyKSA9PiB2b2lkKSB7XG5cdFx0aWYgKHRoaXMuaHR0cFNlcnZlcikge1xuXHRcdFx0YXdhaXQgdGhpcy5odHRwU2VydmVyLmNsb3NlKGFzeW5jICgpID0+IHtcblx0XHRcdFx0dGhpcy5pbmZvKGBTdG9wcGVkIGxpc3RlbmluZyB0byBjb25uZWN0aW9ucyBvbiBwb3J0OiAke3RoaXMub3B0aW9ucy5wb3J0fS5gKTtcblx0XHRcdFx0YXdhaXQgdGhpcy5vcHRpb25zLnRyYW5zcG9ydC5jbG9zZSgpO1xuXHRcdFx0XHRpZiAoY2FsbGJhY2spIHtcblx0XHRcdFx0XHRjYWxsYmFjayh0aGlzKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IEVycm9yKCdUaGUgc2VydmVyIGhhcyBub3Qgc3RhcnRlZCBsaXN0ZW5pbmcgdG8gY29ubmVjdGlvbnMuJyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFzc2lnbnMgc2V0dGluZyBgbmFtZWAgdG8gYHZhbHVlYC5cblx0ICpcblx0ICogQHBhcmFtIHNldHRpbmcgVGhlIHNldHRpbmcgbmFtZS5cblx0ICogQHBhcmFtIHZhbCBUaGUgc2V0dGluZyB2YWx1ZS5cblx0ICovXG5cdHB1YmxpYyBzZXQoc2V0dGluZzogc3RyaW5nLCB2YWw6IGFueSkge1xuXHRcdHRoaXMuc2VydmVyLnNldChzZXR0aW5nLCB2YWwpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVzZSB0aGUgZ2l2ZW4gcmVxdWVzdCBoYW5kbGVycyBmb3IgdGhlIHNwZWNpZmllZCBwYXRocy5cblx0ICpcblx0ICogQHBhcmFtIHBhdGggVGhlIHBhdGggZm9yIHRoZSBpbmNvbWluZyByZXF1ZXN0LlxuXHQgKiBAcGFyYW0gaGFuZGxlcnMgVGhlIG1pZGRsZXdhcmUgdG8gYmUgdXNlZCB3aGVuIHByb2Nlc3NpbmcgdGhlIGluY29taW5nIHJlcXVlc3QuXG5cdCAqL1xuXHRwdWJsaWMgdXNlKHBhdGg6IHN0cmluZywgLi4uaGFuZGxlcnM6IEFycmF5PEVycm9yUmVxdWVzdEhhbmRsZXIgfCBSZXF1ZXN0SGFuZGxlcj4pIHtcblx0XHR0aGlzLnNlcnZlci51c2UocGF0aCwgLi4uaGFuZGxlcnMpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHNlcnZlciBpbXBsZW1lbnRhdGlvbi5cblx0ICpcblx0ICogRGVmYXVsdHMgdG8gZXhwcmVzcy5cblx0ICpcblx0ICogQGV4YW1wbGVcblx0ICogLy8gcmV0dXJucyB0aGUgc2VydmVyIGltcGxlbWVudGF0aW9uXG5cdCAqIHNlcnZlci5zZXJ2ZXJJbXBsLmxpc3RlbignODA4MCcpO1xuXHQgKiBAcmV0dXJucyBUaGUgc2VydmVyIGltcGxlbWVudGF0aW9uLlxuXHQgKi9cblx0cHVibGljIGdldCBzZXJ2ZXJJbXBsKCkge1xuXHRcdHJldHVybiB0aGlzLnNlcnZlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBtZXNzYWdlIHB1Ymxpc2hlci5cblx0ICpcblx0ICogQHJldHVybnMgVGhlIG1lc3NhZ2UgcHVibGlzaGVyLlxuXHQgKi9cblx0cHVibGljIGdldCBwdWJsaXNoZXIoKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVibGlzaGVySW1wbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbWl0IGFuIGVycm9yIGV2ZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0gZXZlbnQgVGhlIGVycm9yIGV2ZW50LlxuXHQgKi9cblx0cHVibGljIGVycm9yKGV2ZW50OiBhbnkpIHtcblx0XHR0aGlzLmVtaXQoU2VydmVyLkVSUk9SLCBldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogRW1pdCBhbiBpbmZvIGV2ZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0gZXZlbnQgVGhlIGluZm8gZXZlbnQuXG5cdCAqL1xuXHRwdWJsaWMgaW5mbyhldmVudDogYW55KSB7XG5cdFx0dGhpcy5lbWl0KFNlcnZlci5JTkZPLCBldmVudCk7XG5cdH1cblxufVxuIl19