UNPKG

@cdklabs/cdk-hyperledger-fabric-network

Version:

CDK construct to deploy a Hyperledger Fabric network running on Amazon Managed Blockchain

161 lines 24.5 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.HyperledgerFabricNode = exports.STARTER_INSTANCE_TYPES = exports.InstanceType = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 const cdk = require("aws-cdk-lib"); const managedblockchain = require("aws-cdk-lib/aws-managedblockchain"); const customresources = require("aws-cdk-lib/custom-resources"); const constructs = require("constructs"); const network = require("./network"); const utilities = require("./utilities"); /** * Supported instance types for Managed Blockchain nodes */ var InstanceType; (function (InstanceType) { InstanceType["BURSTABLE3_SMALL"] = "bc.t3.small"; InstanceType["BURSTABLE3_MEDIUM"] = "bc.t3.medium"; InstanceType["BURSTABLE3_LARGE"] = "bc.t3.large"; InstanceType["BURSTABLE3_XLARGE"] = "bc.t3.xlarge"; InstanceType["STANDARD5_LARGE"] = "bc.m5.large"; InstanceType["STANDARD5_XLARGE"] = "bc.m5.xlarge"; InstanceType["STANDARD5_XLARGE2"] = "bc.m5.2xlarge"; InstanceType["STANDARD5_XLARGE4"] = "bc.m5.4xlarge"; InstanceType["COMPUTE5_LARGE"] = "bc.c5.large"; InstanceType["COMPUTE5_XLARGE"] = "bc.c5.xlarge"; InstanceType["COMPUTE5_XLARGE2"] = "bc.c5.2xlarge"; InstanceType["COMPUTE5_XLARGE4"] = "bc.c5.4xlarge"; })(InstanceType || (exports.InstanceType = InstanceType = {})); /** * Valid instance types for starter networks */ exports.STARTER_INSTANCE_TYPES = [ InstanceType.BURSTABLE3_SMALL, InstanceType.BURSTABLE3_MEDIUM, ]; /** * Creates a Hyperledger Fabric node on an Amazon Managed Blockchain network */ class HyperledgerFabricNode extends constructs.Construct { /** * Build out a list of HyperledgerFabricNode constructs given a list of input property * objects; additionally checks to ensure node count is supported given the network type */ static constructNodes(scope, nodeProps) { // If no node configurations are provided, create one; the empty object // will be populated with defaults when passed to the node constructor if (typeof nodeProps === 'undefined') nodeProps = [{}]; const starter = scope.networkEdition === network.NetworkEdition.STARTER; if (starter && nodeProps.length > 2) { throw new Error('A starter network can have at most 2 nodes per member.'); } if (!starter && nodeProps.length > 3) { throw new Error('A standard network can have at most 3 nodes per member.'); } // Construct the node list, using an index value in the identifier return Array.from(nodeProps.entries()).map(e => new HyperledgerFabricNode(scope, `Node${e[0]}`, e[1])); } constructor(scope, id, props) { super(scope, id); // These cannot be readonly since they have to be set after construction // due the race condition documented in https://github.com/aws/aws-cdk/issues/18237. this.endpoint = ''; this.eventEndpoint = ''; // Collect metadata on the stack const region = cdk.Stack.of(this).region; // Populate instance variables from input properties, using defaults if values not provided if (typeof props === 'undefined') props = {}; this.availabilityZone = props.availabilityZone ?? `${region}a`; this.instanceType = props.instanceType ?? InstanceType.BURSTABLE3_SMALL; this.enableChaincodeLogging = props.enableChaincodeLogging ?? true; this.enableNodeLogging = props.enableNodeLogging ?? true; this.networkId = scope.networkId; this.memberId = scope.memberId; // Ensure the parameters captured above are valid, so we don't // need to wait until deployment time to discover an error utilities.validateRegion(region); utilities.validateAvailabilityZone(region, this.availabilityZone); if (scope.networkEdition === network.NetworkEdition.STARTER && !exports.STARTER_INSTANCE_TYPES.includes(this.instanceType)) { const starterInstanceTypeList = exports.STARTER_INSTANCE_TYPES.join(', '); throw new Error(`Instance type in a starter network must be one of the following: ${starterInstanceTypeList}.`); } // Build out the Cloudformation construct for the network/member const node = new managedblockchain.CfnNode(this, 'Node', { networkId: this.networkId, memberId: this.memberId, nodeConfiguration: { availabilityZone: this.availabilityZone, instanceType: this.instanceType, }, }); // Capture data included in the Cloudformation output in instance variables this.nodeId = node.getAtt('NodeId').toString(); } /** * Configure logging for the node via SDK call; this function * should be merged back into the constructor once the race condition is solved */ configureLogging(sdkCallPolicy) { // This call doesn't really need all the permissions its using in the // provided policy, but since the policy must be constructed all at once // this is the only way to do it effectively const logPublishingConfiguration = { Fabric: { ChaincodeLogs: { Cloudwatch: { Enabled: this.enableChaincodeLogging }, }, PeerLogs: { Cloudwatch: { Enabled: this.enableNodeLogging }, }, }, }; const configureNodeLogSdkCall = { service: 'ManagedBlockchain', action: 'updateNode', parameters: { NetworkId: this.networkId, MemberId: this.memberId, NodeId: this.nodeId, LogPublishingConfiguration: logPublishingConfiguration, }, physicalResourceId: customresources.PhysicalResourceId.of('Id'), }; new customresources.AwsCustomResource(this, 'ConfigureNodeLogResource', { policy: sdkCallPolicy, onCreate: configureNodeLogSdkCall, onUpdate: configureNodeLogSdkCall, }); } /** * Populate the output properties that must be fetched via SDK call; this function * should be merged back into the constructor once the race condition is solved */ fetchData(dataSdkCallPolicy) { // This call doesn't really need all the permissions its using in the // provided policy, but since the policy must be constructed all at once // this is the only way to do it effectively const nodeDataSdkCall = { service: 'ManagedBlockchain', action: 'getNode', parameters: { NetworkId: this.networkId, MemberId: this.memberId, NodeId: this.nodeId }, physicalResourceId: customresources.PhysicalResourceId.of('Id'), }; const nodeData = new customresources.AwsCustomResource(this, 'NodeDataResource', { policy: dataSdkCallPolicy, onCreate: nodeDataSdkCall, onUpdate: nodeDataSdkCall, }); // Grab items out of the above return values and stick them in output properties this.endpoint = nodeData.getResponseField('Node.FrameworkAttributes.Fabric.PeerEndpoint'); this.eventEndpoint = nodeData.getResponseField('Node.FrameworkAttributes.Fabric.PeerEventEndpoint'); } } exports.HyperledgerFabricNode = HyperledgerFabricNode; _a = JSII_RTTI_SYMBOL_1; HyperledgerFabricNode[_a] = { fqn: "@cdklabs/cdk-hyperledger-fabric-network.HyperledgerFabricNode", version: "0.8.918" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ub2RlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscUVBQXFFO0FBQ3JFLGlDQUFpQztBQUdqQyxtQ0FBbUM7QUFDbkMsdUVBQXVFO0FBQ3ZFLGdFQUFnRTtBQUNoRSx5Q0FBeUM7QUFFekMscUNBQXFDO0FBQ3JDLHlDQUF5QztBQUd6Qzs7R0FFRztBQUNILElBQVksWUFhWDtBQWJELFdBQVksWUFBWTtJQUN0QixnREFBZ0MsQ0FBQTtJQUNoQyxrREFBa0MsQ0FBQTtJQUNsQyxnREFBZ0MsQ0FBQTtJQUNoQyxrREFBa0MsQ0FBQTtJQUNsQywrQ0FBK0IsQ0FBQTtJQUMvQixpREFBaUMsQ0FBQTtJQUNqQyxtREFBbUMsQ0FBQTtJQUNuQyxtREFBbUMsQ0FBQTtJQUNuQyw4Q0FBOEIsQ0FBQTtJQUM5QixnREFBZ0MsQ0FBQTtJQUNoQyxrREFBa0MsQ0FBQTtJQUNsQyxrREFBa0MsQ0FBQTtBQUNwQyxDQUFDLEVBYlcsWUFBWSw0QkFBWixZQUFZLFFBYXZCO0FBR0Q7O0dBRUc7QUFDVSxRQUFBLHNCQUFzQixHQUFHO0lBQ3BDLFlBQVksQ0FBQyxnQkFBZ0I7SUFDN0IsWUFBWSxDQUFDLGlCQUFpQjtDQUMvQixDQUFDO0FBbUNGOztHQUVHO0FBQ0gsTUFBYSxxQkFBc0IsU0FBUSxVQUFVLENBQUMsU0FBUztJQUU3RDs7O09BR0c7SUFDSSxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQXVDLEVBQUUsU0FBNkM7UUFDakgsdUVBQXVFO1FBQ3ZFLHNFQUFzRTtRQUN0RSxJQUFJLE9BQU8sU0FBUyxLQUFLLFdBQVc7WUFBRSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN2RCxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsY0FBYyxLQUFLLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1FBQ3hFLElBQUksT0FBTyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEdBQUcs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QUFRLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDdkYsa0JBQWtCLEVBQUUsZUFBZSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUM7U0FDaEUsQ0FBQztRQUNGLE1BQU0sUUFBUSxHQUFHLElBQUksZUFBZSxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtZQUMvRSxNQUFNLEVBQUUsaUJBQWlCO1lBQ3pCLFFBQVEsRUFBRSxlQUFlO1lBQ3pCLFFBQVEsRUFBRSxlQUFlO1NBQzFCLENBQUMsQ0FBQztRQUVILGdGQUFnRjtRQUNoRixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1FBQzFGLElBQUksQ0FBQyxhQUFhLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDLG1EQUFtRCxDQUFDLENBQUM7SUFFdEcsQ0FBQzs7QUFuS0gsc0RBcUtDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlULTBcblxuXG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgbWFuYWdlZGJsb2NrY2hhaW4gZnJvbSAnYXdzLWNkay1saWIvYXdzLW1hbmFnZWRibG9ja2NoYWluJztcbmltcG9ydCAqIGFzIGN1c3RvbXJlc291cmNlcyBmcm9tICdhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzJztcbmltcG9ydCAqIGFzIGNvbnN0cnVjdHMgZnJvbSAnY29uc3RydWN0cyc7XG5cbmltcG9ydCAqIGFzIG5ldHdvcmsgZnJvbSAnLi9uZXR3b3JrJztcbmltcG9ydCAqIGFzIHV0aWxpdGllcyBmcm9tICcuL3V0aWxpdGllcyc7XG5cblxuLyoqXG4gKiBTdXBwb3J0ZWQgaW5zdGFuY2UgdHlwZXMgZm9yIE1hbmFnZWQgQmxvY2tjaGFpbiBub2Rlc1xuICovXG5leHBvcnQgZW51bSBJbnN0YW5jZVR5cGUge1xuICBCVVJTVEFCTEUzX1NNQUxMID0gJ2JjLnQzLnNtYWxsJyxcbiAgQlVSU1RBQkxFM19NRURJVU0gPSAnYmMudDMubWVkaXVtJyxcbiAgQlVSU1RBQkxFM19MQVJHRSA9ICdiYy50My5sYXJnZScsXG4gIEJVUlNUQUJMRTNfWExBUkdFID0gJ2JjLnQzLnhsYXJnZScsXG4gIFNUQU5EQVJENV9MQVJHRSA9ICdiYy5tNS5sYXJnZScsXG4gIFNUQU5EQVJENV9YTEFSR0UgPSAnYmMubTUueGxhcmdlJyxcbiAgU1RBTkRBUkQ1X1hMQVJHRTIgPSAnYmMubTUuMnhsYXJnZScsXG4gIFNUQU5EQVJENV9YTEFSR0U0ID0gJ2JjLm01LjR4bGFyZ2UnLFxuICBDT01QVVRFNV9MQVJHRSA9ICdiYy5jNS5sYXJnZScsXG4gIENPTVBVVEU1X1hMQVJHRSA9ICdiYy5jNS54bGFyZ2UnLFxuICBDT01QVVRFNV9YTEFSR0UyID0gJ2JjLmM1LjJ4bGFyZ2UnLFxuICBDT01QVVRFNV9YTEFSR0U0ID0gJ2JjLmM1LjR4bGFyZ2UnLFxufVxuXG5cbi8qKlxuICogVmFsaWQgaW5zdGFuY2UgdHlwZXMgZm9yIHN0YXJ0ZXIgbmV0d29ya3NcbiAqL1xuZXhwb3J0IGNvbnN0IFNUQVJURVJfSU5TVEFOQ0VfVFlQRVMgPSBbXG4gIEluc3RhbmNlVHlwZS5CVVJTVEFCTEUzX1NNQUxMLFxuICBJbnN0YW5jZVR5cGUuQlVSU1RBQkxFM19NRURJVU0sXG5dO1xuXG5cbi8qKlxuICogQ29uc3RydWN0IHByb3BlcnRpZXMgZm9yIGBIeXBlcmxlZGdlckZhYnJpY05vZGVgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSHlwZXJsZWRnZXJGYWJyaWNOb2RlUHJvcHMge1xuXG4gIC8qKlxuICAgKiBUaGUgQXZhaWxhYmlsaXR5IFpvbmUgaW4gd2hpY2ggdGhlIG5vZGUgd2lsbCBiZSBjcmVhdGVkXG4gICAqIEBkZWZhdWx0IC0gVGhlIGZpcnN0IEFaIGluIHRoZSByZWdpb25cbiAgICovXG4gIHJlYWRvbmx5IGF2YWlsYWJpbGl0eVpvbmU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIGluc3RhbmNlIHR5cGUgZm9yIHRoZSBub2RlXG4gICAqIEBkZWZhdWx0IC0gQlVSU1RBQkxFM19TTUFMTFxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFuY2VUeXBlPzogSW5zdGFuY2VUeXBlO1xuXG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiB0byBlbmFibGUgb3IgZGlzYWJsZSBjaGFpbmNvZGUgbG9nZ2luZ1xuICAgKiBAZGVmYXVsdCAtIHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZUNoYWluY29kZUxvZ2dpbmc/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiB0byBlbmFibGUgb3IgZGlzYWJsZSBub2RlIGxvZ2dpbmdcbiAgICogQGRlZmF1bHQgLSB0cnVlXG4gICAqL1xuICByZWFkb25seSBlbmFibGVOb2RlTG9nZ2luZz86IGJvb2xlYW47XG5cbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBIeXBlcmxlZGdlciBGYWJyaWMgbm9kZSBvbiBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmtcbiAqL1xuZXhwb3J0IGNsYXNzIEh5cGVybGVkZ2VyRmFicmljTm9kZSBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogQnVpbGQgb3V0IGEgbGlzdCBvZiBIeXBlcmxlZGdlckZhYnJpY05vZGUgY29uc3RydWN0cyBnaXZlbiBhIGxpc3Qgb2YgaW5wdXQgcHJvcGVydHlcbiAgICogb2JqZWN0czsgYWRkaXRpb25hbGx5IGNoZWNrcyB0byBlbnN1cmUgbm9kZSBjb3VudCBpcyBzdXBwb3J0ZWQgZ2l2ZW4gdGhlIG5ldHdvcmsgdHlwZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb25zdHJ1Y3ROb2RlcyhzY29wZTogbmV0d29yay5IeXBlcmxlZGdlckZhYnJpY05ldHdvcmssIG5vZGVQcm9wcz86IEFycmF5PEh5cGVybGVkZ2VyRmFicmljTm9kZVByb3BzPikge1xuICAgIC8vIElmIG5vIG5vZGUgY29uZmlndXJhdGlvbnMgYXJlIHByb3ZpZGVkLCBjcmVhdGUgb25lOyB0aGUgZW1wdHkgb2JqZWN0XG4gICAgLy8gd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCBkZWZhdWx0cyB3aGVuIHBhc3NlZCB0byB0aGUgbm9kZSBjb25zdHJ1Y3RvclxuICAgIGlmICh0eXBlb2Ygbm9kZVByb3BzID09PSAndW5kZWZpbmVkJykgbm9kZVByb3BzID0gW3t9XTtcbiAgICBjb25zdCBzdGFydGVyID0gc2NvcGUubmV0d29ya0VkaXRpb24gPT09IG5ldHdvcmsuTmV0d29ya0VkaXRpb24uU1RBUlRFUjtcbiAgICBpZiAoc3RhcnRlciAmJiBub2RlUHJvcHMubGVuZ3RoID4gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIHN0YXJ0ZXIgbmV0d29yayBjYW4gaGF2ZSBhdCBtb3N0IDIgbm9kZXMgcGVyIG1lbWJlci4nKTtcbiAgICB9XG4gICAgaWYgKCFzdGFydGVyICYmIG5vZGVQcm9wcy5sZW5ndGggPiAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Egc3RhbmRhcmQgbmV0d29yayBjYW4gaGF2ZSBhdCBtb3N0IDMgbm9kZXMgcGVyIG1lbWJlci4nKTtcbiAgICB9XG4gICAgLy8gQ29uc3RydWN0IHRoZSBub2RlIGxpc3QsIHVzaW5nIGFuIGluZGV4IHZhbHVlIGluIHRoZSBpZGVudGlmaWVyXG4gICAgcmV0dXJuIEFycmF5LmZyb20obm9kZVByb3BzLmVudHJpZXMoKSkubWFwKGUgPT4gbmV3IEh5cGVybGVkZ2VyRmFicmljTm9kZShzY29wZSwgYE5vZGUke2VbMF19YCwgZVsxXSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrIGlkZW50aWZpZXJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBuZXR3b3JrSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogTWFuYWdlZCBCbG9ja2NoYWluIG1lbWJlciBpZGVudGlmaWVyXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbWVtYmVySWQ6IHN0cmluZztcblxuICAvKipcbiAgICogTWFuYWdlZCBCbG9ja2NoYWluIG5vZGUgaWRlbnRpZmllciBnZW5lcmF0ZWQgb24gY29uc3RydWN0aW9uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbm9kZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBdmFpbGFiaWxpdHkgWm9uZSBpbiB3aGljaCB0aGUgbm9kZSBleGlzdHNcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIGluc3RhbmNlIHR5cGUgZm9yIHRoZSBub2RlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaW5zdGFuY2VUeXBlOiBJbnN0YW5jZVR5cGU7XG5cbiAgLyoqXG4gICAqIFRoZSBjb25maWd1cmF0aW9uIHRvIGVuYWJsZSBvciBkaXNhYmxlIGNoYWluY29kZSBsb2dnaW5nXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZW5hYmxlQ2hhaW5jb2RlTG9nZ2luZzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGNvbmZpZ3VyYXRpb24gdG8gZW5hYmxlIG9yIGRpc2FibGUgbm9kZSBsb2dnaW5nXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZW5hYmxlTm9kZUxvZ2dpbmc6IGJvb2xlYW47XG5cbiAgLy8gVGhlc2UgY2Fubm90IGJlIHJlYWRvbmx5IHNpbmNlIHRoZXkgaGF2ZSB0byBiZSBzZXQgYWZ0ZXIgY29uc3RydWN0aW9uXG4gIC8vIGR1ZSB0aGUgcmFjZSBjb25kaXRpb24gZG9jdW1lbnRlZCBpbiBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzLzE4MjM3LlxuICBwdWJsaWMgZW5kcG9pbnQ6IHN0cmluZyA9ICcnO1xuICBwdWJsaWMgZXZlbnRFbmRwb2ludDogc3RyaW5nID0gJyc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IG5ldHdvcmsuSHlwZXJsZWRnZXJGYWJyaWNOZXR3b3JrLCBpZDogc3RyaW5nLCBwcm9wcz86IEh5cGVybGVkZ2VyRmFicmljTm9kZVByb3BzKSB7XG5cbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gQ29sbGVjdCBtZXRhZGF0YSBvbiB0aGUgc3RhY2tcbiAgICBjb25zdCByZWdpb24gPSBjZGsuU3RhY2sub2YodGhpcykucmVnaW9uO1xuXG4gICAgLy8gUG9wdWxhdGUgaW5zdGFuY2UgdmFyaWFibGVzIGZyb20gaW5wdXQgcHJvcGVydGllcywgdXNpbmcgZGVmYXVsdHMgaWYgdmFsdWVzIG5vdCBwcm92aWRlZFxuICAgIGlmICh0eXBlb2YgcHJvcHMgPT09ICd1bmRlZmluZWQnKSBwcm9wcyA9IHt9O1xuICAgIHRoaXMuYXZhaWxhYmlsaXR5Wm9uZSA9IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUgPz8gYCR7cmVnaW9ufWFgO1xuICAgIHRoaXMuaW5zdGFuY2VUeXBlID0gcHJvcHMuaW5zdGFuY2VUeXBlID8/IEluc3RhbmNlVHlwZS5CVVJTVEFCTEUzX1NNQUxMO1xuICAgIHRoaXMuZW5hYmxlQ2hhaW5jb2RlTG9nZ2luZyA9IHByb3BzLmVuYWJsZUNoYWluY29kZUxvZ2dpbmcgPz8gdHJ1ZTtcbiAgICB0aGlzLmVuYWJsZU5vZGVMb2dnaW5nID0gcHJvcHMuZW5hYmxlTm9kZUxvZ2dpbmcgPz8gdHJ1ZTtcbiAgICB0aGlzLm5ldHdvcmtJZCA9IHNjb3BlLm5ldHdvcmtJZDtcbiAgICB0aGlzLm1lbWJlcklkID0gc2NvcGUubWVtYmVySWQ7XG5cbiAgICAvLyBFbnN1cmUgdGhlIHBhcmFtZXRlcnMgY2FwdHVyZWQgYWJvdmUgYXJlIHZhbGlkLCBzbyB3ZSBkb24ndFxuICAgIC8vIG5lZWQgdG8gd2FpdCB1bnRpbCBkZXBsb3ltZW50IHRpbWUgdG8gZGlzY292ZXIgYW4gZXJyb3JcbiAgICB1dGlsaXRpZXMudmFsaWRhdGVSZWdpb24ocmVnaW9uKTtcbiAgICB1dGlsaXRpZXMudmFsaWRhdGVBdmFpbGFiaWxpdHlab25lKHJlZ2lvbiwgdGhpcy5hdmFpbGFiaWxpdHlab25lKTtcbiAgICBpZiAoc2NvcGUubmV0d29ya0VkaXRpb24gPT09IG5ldHdvcmsuTmV0d29ya0VkaXRpb24uU1RBUlRFUiAmJiAhU1RBUlRFUl9JTlNUQU5DRV9UWVBFUy5pbmNsdWRlcyh0aGlzLmluc3RhbmNlVHlwZSkpIHtcbiAgICAgIGNvbnN0IHN0YXJ0ZXJJbnN0YW5jZVR5cGVMaXN0ID0gU1RBUlRFUl9JTlNUQU5DRV9UWVBFUy5qb2luKCcsICcpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnN0YW5jZSB0eXBlIGluIGEgc3RhcnRlciBuZXR3b3JrIG11c3QgYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6ICR7c3RhcnRlckluc3RhbmNlVHlwZUxpc3R9LmApO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIG91dCB0aGUgQ2xvdWRmb3JtYXRpb24gY29uc3RydWN0IGZvciB0aGUgbmV0d29yay9tZW1iZXJcbiAgICBjb25zdCBub2RlID0gbmV3IG1hbmFnZWRibG9ja2NoYWluLkNmbk5vZGUodGhpcywgJ05vZGUnLCB7XG4gICAgICBuZXR3b3JrSWQ6IHRoaXMubmV0d29ya0lkLFxuICAgICAgbWVtYmVySWQ6IHRoaXMubWVtYmVySWQsXG4gICAgICBub2RlQ29uZmlndXJhdGlvbjoge1xuICAgICAgICBhdmFpbGFiaWxpdHlab25lOiB0aGlzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgIGluc3RhbmNlVHlwZTogdGhpcy5pbnN0YW5jZVR5cGUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gQ2FwdHVyZSBkYXRhIGluY2x1ZGVkIGluIHRoZSBDbG91ZGZvcm1hdGlvbiBvdXRwdXQgaW4gaW5zdGFuY2UgdmFyaWFibGVzXG4gICAgdGhpcy5ub2RlSWQgPSBub2RlLmdldEF0dCgnTm9kZUlkJykudG9TdHJpbmcoKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyZSBsb2dnaW5nIGZvciB0aGUgbm9kZSB2aWEgU0RLIGNhbGw7IHRoaXMgZnVuY3Rpb25cbiAgICogc2hvdWxkIGJlIG1lcmdlZCBiYWNrIGludG8gdGhlIGNvbnN0cnVjdG9yIG9uY2UgdGhlIHJhY2UgY29uZGl0aW9uIGlzIHNvbHZlZFxuICAgKi9cbiAgcHVibGljIGNvbmZpZ3VyZUxvZ2dpbmcoc2RrQ2FsbFBvbGljeTogY3VzdG9tcmVzb3VyY2VzLkF3c0N1c3RvbVJlc291cmNlUG9saWN5KSB7XG5cbiAgICAvLyBUaGlzIGNhbGwgZG9lc24ndCByZWFsbHkgbmVlZCBhbGwgdGhlIHBlcm1pc3Npb25zIGl0cyB1c2luZyBpbiB0aGVcbiAgICAvLyBwcm92aWRlZCBwb2xpY3ksIGJ1dCBzaW5jZSB0aGUgcG9saWN5IG11c3QgYmUgY29uc3RydWN0ZWQgYWxsIGF0IG9uY2VcbiAgICAvLyB0aGlzIGlzIHRoZSBvbmx5IHdheSB0byBkbyBpdCBlZmZlY3RpdmVseVxuICAgIGNvbnN0IGxvZ1B1Ymxpc2hpbmdDb25maWd1cmF0aW9uID0ge1xuICAgICAgRmFicmljOiB7XG4gICAgICAgIENoYWluY29kZUxvZ3M6IHtcbiAgICAgICAgICBDbG91ZHdhdGNoOiB7IEVuYWJsZWQ6IHRoaXMuZW5hYmxlQ2hhaW5jb2RlTG9nZ2luZyB9LFxuICAgICAgICB9LFxuICAgICAgICBQZWVyTG9nczoge1xuICAgICAgICAgIENsb3Vkd2F0Y2g6IHsgRW5hYmxlZDogdGhpcy5lbmFibGVOb2RlTG9nZ2luZyB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICAgIGNvbnN0IGNvbmZpZ3VyZU5vZGVMb2dTZGtDYWxsID0ge1xuICAgICAgc2VydmljZTogJ01hbmFnZWRCbG9ja2NoYWluJyxcbiAgICAgIGFjdGlvbjogJ3VwZGF0ZU5vZGUnLFxuICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICBOZXR3b3JrSWQ6IHRoaXMubmV0d29ya0lkLFxuICAgICAgICBNZW1iZXJJZDogdGhpcy5tZW1iZXJJZCxcbiAgICAgICAgTm9kZUlkOiB0aGlzLm5vZGVJZCxcbiAgICAgICAgTG9nUHVibGlzaGluZ0NvbmZpZ3VyYXRpb246IGxvZ1B1Ymxpc2hpbmdDb25maWd1cmF0aW9uLFxuICAgICAgfSxcbiAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3VzdG9tcmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5vZignSWQnKSxcbiAgICB9O1xuICAgIG5ldyBjdXN0b21yZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0NvbmZpZ3VyZU5vZGVMb2dSZXNvdXJjZScsIHtcbiAgICAgIHBvbGljeTogc2RrQ2FsbFBvbGljeSxcbiAgICAgIG9uQ3JlYXRlOiBjb25maWd1cmVOb2RlTG9nU2RrQ2FsbCxcbiAgICAgIG9uVXBkYXRlOiBjb25maWd1cmVOb2RlTG9nU2RrQ2FsbCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb3B1bGF0ZSB0aGUgb3V0cHV0IHByb3BlcnRpZXMgdGhhdCBtdXN0IGJlIGZldGNoZWQgdmlhIFNESyBjYWxsOyB0aGlzIGZ1bmN0aW9uXG4gICAqIHNob3VsZCBiZSBtZXJnZWQgYmFjayBpbnRvIHRoZSBjb25zdHJ1Y3RvciBvbmNlIHRoZSByYWNlIGNvbmRpdGlvbiBpcyBzb2x2ZWRcbiAgICovXG4gIHB1YmxpYyBmZXRjaERhdGEoZGF0YVNka0NhbGxQb2xpY3k6IGN1c3RvbXJlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeSkge1xuXG4gICAgLy8gVGhpcyBjYWxsIGRvZXNuJ3QgcmVhbGx5IG5lZWQgYWxsIHRoZSBwZXJtaXNzaW9ucyBpdHMgdXNpbmcgaW4gdGhlXG4gICAgLy8gcHJvdmlkZWQgcG9saWN5LCBidXQgc2luY2UgdGhlIHBvbGljeSBtdXN0IGJlIGNvbnN0cnVjdGVkIGFsbCBhdCBvbmNlXG4gICAgLy8gdGhpcyBpcyB0aGUgb25seSB3YXkgdG8gZG8gaXQgZWZmZWN0aXZlbHlcbiAgICBjb25zdCBub2RlRGF0YVNka0NhbGwgPSB7XG4gICAgICBzZXJ2aWNlOiAnTWFuYWdlZEJsb2NrY2hhaW4nLFxuICAgICAgYWN0aW9uOiAnZ2V0Tm9kZScsXG4gICAgICBwYXJhbWV0ZXJzOiB7IE5ldHdvcmtJZDogdGhpcy5uZXR3b3JrSWQsIE1lbWJlcklkOiB0aGlzLm1lbWJlcklkLCBOb2RlSWQ6IHRoaXMubm9kZUlkIH0sXG4gICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IGN1c3RvbXJlc291cmNlcy5QaHlzaWNhbFJlc291cmNlSWQub2YoJ0lkJyksXG4gICAgfTtcbiAgICBjb25zdCBub2RlRGF0YSA9IG5ldyBjdXN0b21yZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgJ05vZGVEYXRhUmVzb3VyY2UnLCB7XG4gICAgICBwb2xpY3k6IGRhdGFTZGtDYWxsUG9saWN5LFxuICAgICAgb25DcmVhdGU6IG5vZGVEYXRhU2RrQ2FsbCxcbiAgICAgIG9uVXBkYXRlOiBub2RlRGF0YVNka0NhbGwsXG4gICAgfSk7XG5cbiAgICAvLyBHcmFiIGl0ZW1zIG91dCBvZiB0aGUgYWJvdmUgcmV0dXJuIHZhbHVlcyBhbmQgc3RpY2sgdGhlbSBpbiBvdXRwdXQgcHJvcGVydGllc1xuICAgIHRoaXMuZW5kcG9pbnQgPSBub2RlRGF0YS5nZXRSZXNwb25zZUZpZWxkKCdOb2RlLkZyYW1ld29ya0F0dHJpYnV0ZXMuRmFicmljLlBlZXJFbmRwb2ludCcpO1xuICAgIHRoaXMuZXZlbnRFbmRwb2ludCA9IG5vZGVEYXRhLmdldFJlc3BvbnNlRmllbGQoJ05vZGUuRnJhbWV3b3JrQXR0cmlidXRlcy5GYWJyaWMuUGVlckV2ZW50RW5kcG9pbnQnKTtcblxuICB9XG5cbn1cbiJdfQ==