UNPKG

@cdklabs/cdk-amazonmq

Version:
160 lines 25.8 kB
"use strict"; var _a, _b; Object.defineProperty(exports, "__esModule", { value: true }); exports.RabbitMqCustomResource = exports.RabbitMqCustomResourcePolicy = exports.HttpMethods = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); /* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ const crypto_1 = require("crypto"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_ec2_1 = require("aws-cdk-lib/aws-ec2"); const custom_resources_1 = require("aws-cdk-lib/custom-resources"); const constructs_1 = require("constructs"); const rabbitmq_custom_resource_singleton_function_1 = require("./rabbitmq-custom-resource-singleton-function"); const HASH_LEN = 16; /** * All http request methods */ var HttpMethods; (function (HttpMethods) { HttpMethods["GET"] = "GET"; HttpMethods["POST"] = "POST"; HttpMethods["PUT"] = "PUT"; HttpMethods["DELETE"] = "DELETE"; })(HttpMethods || (exports.HttpMethods = HttpMethods = {})); /** * The IAM Policy that will be applied to the calls. */ class RabbitMqCustomResourcePolicy { /** * Explicit IAM Policy Statements. * * @param statements the statements to propagate to the SDK calls. */ static fromStatements(statements) { return new RabbitMqCustomResourcePolicy(statements); } /** * @param statements statements for explicit policy. * @param resources resources for auto-generated from SDK calls. */ constructor(statements) { this.statements = statements; } } exports.RabbitMqCustomResourcePolicy = RabbitMqCustomResourcePolicy; _a = JSII_RTTI_SYMBOL_1; RabbitMqCustomResourcePolicy[_a] = { fqn: "@cdklabs/cdk-amazonmq.RabbitMqCustomResourcePolicy", version: "0.1.8" }; /** * Use this constant to configure access to any resource. */ RabbitMqCustomResourcePolicy.ANY_RESOURCE = ["*"]; /** * @experimental * * Defines a custom resource that is materialized using specific RabbitMQ Management HTTP API calls. * * Use this to interact with the Amazon MQ for RabbitMQ broker. You can specify exactly which calls are invoked for the 'CREATE', 'UPDATE' and 'DELETE' life cycle events. */ class RabbitMqCustomResource extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); if (!props.onCreate && !props.onUpdate && !props.onDelete) { throw new Error("At least `onCreate`, `onUpdate` or `onDelete` must be specified."); } if (props.onCreate && !props.onCreate.physicalResourceId) { throw new Error("'physicalResourceId' must be specified for 'onCreate' call."); } if (!props.onCreate && props.onUpdate && !props.onUpdate.physicalResourceId) { throw new Error("'physicalResourceId' must be specified for 'onUpdate' call when 'onCreate' is omitted."); } let securityGroups = props.vpc ? props.securityGroups || [ new aws_ec2_1.SecurityGroup(this, "ProviderSG", { vpc: props.vpc }), ] : undefined; const uuid = this.renderUniqueId(props.broker, props.credentials, props.vpc, props.vpcSubnets, props.securityGroups); const provider = new rabbitmq_custom_resource_singleton_function_1.RabbitMqCustomResourceSingletonFunction(this, "Provider", { uuid, vpc: props.vpc, vpcSubnets: props.vpcSubnets, securityGroups: securityGroups, ...(props.logRetention ? { logRetention: props.logRetention } : {}), logGroup: props.logGroup, timeout: props.timeout || aws_cdk_lib_1.Duration.minutes(1), initialPolicy: props.policy?.statements, }); const onUpdate = props.onUpdate && this.formatSdkCall(props.onUpdate); const onCreate = (props.onCreate && this.formatSdkCall(props.onCreate)) || onUpdate; const onDelete = props.onDelete && this.formatSdkCall(props.onDelete); this.resource = new aws_cdk_lib_1.CustomResource(this, `Resource${uuid}`, { resourceType: "Custom::RMQAPI", serviceToken: provider.functionArn, pascalCaseProperties: true, properties: { url: props.broker.endpoints.console.url, credentials: props.credentials.secretArn, create: onCreate, update: onUpdate, delete: onDelete, }, }); this.connections = new aws_ec2_1.Connections({ securityGroups, }); props.credentials.grantRead(provider); this.grantPrincipal = provider.grantPrincipal; } getResponseField(key) { return this.resource.getAttString(key); } getResponseFieldReference(key) { return this.resource.getAtt(key); } formatSdkCall(sdkCall) { const { logging, ...call } = sdkCall; const renderedLogging = (logging ?? custom_resources_1.Logging.all())._render(this); return this.encodeJson({ ...call, ...renderedLogging, }); } encodeJson(obj) { return aws_cdk_lib_1.Lazy.uncachedString({ produce: () => aws_cdk_lib_1.Stack.of(this).toJsonString(obj), }); } renderUniqueId(broker, creds, vpc, subnets, securityGroups) { let hashContent = ""; const resourceBroker = broker; hashContent += aws_cdk_lib_1.Names.uniqueId(resourceBroker); hashContent += aws_cdk_lib_1.Names.uniqueId(creds); if (vpc) { hashContent += aws_cdk_lib_1.Names.uniqueId(vpc); if (subnets) { hashContent += vpc .selectSubnets(subnets) .subnets.map((s) => aws_cdk_lib_1.Names.uniqueId(s)) .join(""); } if (securityGroups) { hashContent += securityGroups.map((sg) => aws_cdk_lib_1.Names.uniqueId(sg)).join(""); } } // INFO: run this through the CDK team as in the S3 Bucket Deployment implementation there is no hashing, just verbatim value addition // see: https://github.com/aws/aws-cdk/blob/318eae6c9eca456e0c34ed21855dad9d2bfa2a0f/packages/aws-cdk-lib/aws-s3-deployment/lib/bucket-deployment.ts#L556 return (0, crypto_1.createHash)("sha256") .update(hashContent) .digest("hex") .slice(0, HASH_LEN) .toUpperCase(); } } exports.RabbitMqCustomResource = RabbitMqCustomResource; _b = JSII_RTTI_SYMBOL_1; RabbitMqCustomResource[_b] = { fqn: "@cdklabs/cdk-amazonmq.RabbitMqCustomResource", version: "0.1.8" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFiYml0bXEtY3VzdG9tLXJlc291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3JhYmJpdG1xL2N1c3RvbS1yZXNvdXJjZS9yYWJiaXRtcS1jdXN0b20tcmVzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7O0VBR0U7QUFFRixtQ0FBb0M7QUFDcEMsNkNBUXFCO0FBQ3JCLGlEQU82QjtBQVM3QixtRUFBMkU7QUFDM0UsMkNBQXVDO0FBRXZDLCtHQUF3RztBQUV4RyxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFFcEI7O0dBRUc7QUFDSCxJQUFZLFdBS1g7QUFMRCxXQUFZLFdBQVc7SUFDckIsMEJBQVcsQ0FBQTtJQUNYLDRCQUFhLENBQUE7SUFDYiwwQkFBVyxDQUFBO0lBQ1gsZ0NBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQUxXLFdBQVcsMkJBQVgsV0FBVyxRQUt0QjtBQW9ERDs7R0FFRztBQUNILE1BQWEsNEJBQTRCO0lBTXZDOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQTZCO1FBQ3hELE9BQU8sSUFBSSw0QkFBNEIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsWUFBb0MsVUFBNkI7UUFBN0IsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7SUFBRyxDQUFDOztBQW5CdkUsb0VBb0JDOzs7QUFuQkM7O0dBRUc7QUFDb0IseUNBQVksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBcUc5Qzs7Ozs7O0dBTUc7QUFDSCxNQUFhLHNCQUNYLFNBQVEsc0JBQVM7SUFTakIsWUFDRSxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBa0M7UUFFbEMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMs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QUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ1IsV0FBVyxJQUFJLG1CQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ25DLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1osV0FBVyxJQUFJLEdBQUc7cUJBQ2YsYUFBYSxDQUFDLE9BQU8sQ0FBQztxQkFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsbUJBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7cUJBQ3JDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNkLENBQUM7WUFDRCxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNuQixXQUFXLElBQUksY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsbUJBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDekUsQ0FBQztRQUNILENBQUM7UUFFRCxzSUFBc0k7UUFDdEkseUpBQXlKO1FBRXpKLE9BQU8sSUFBQSxtQkFBVSxFQUFDLFFBQVEsQ0FBQzthQUN4QixNQUFNLENBQUMsV0FBVyxDQUFDO2FBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUM7YUFDYixLQUFLLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQzthQUNsQixXQUFXLEVBQUUsQ0FBQztJQUNuQixDQUFDOztBQXRKSCx3REF1SkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuKi9cblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCB7XG4gIEN1c3RvbVJlc291cmNlLFxuICBEdXJhdGlvbixcbiAgSVJlc291cmNlLFxuICBMYXp5LFxuICBOYW1lcyxcbiAgUmVmZXJlbmNlLFxuICBTdGFjayxcbn0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBDb25uZWN0aW9ucyxcbiAgSUNvbm5lY3RhYmxlLFxuICBJU2VjdXJpdHlHcm91cCxcbiAgSVZwYyxcbiAgU2VjdXJpdHlHcm91cCxcbiAgU3VibmV0U2VsZWN0aW9uLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiO1xuaW1wb3J0IHtcbiAgSUdyYW50YWJsZSxcbiAgSVByaW5jaXBhbCxcbiAgSVJvbGUsXG4gIFBvbGljeVN0YXRlbWVudCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IExvZ0dyb3VwLCBSZXRlbnRpb25EYXlzIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sb2dzXCI7XG5pbXBvcnQgeyBJU2VjcmV0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zZWNyZXRzbWFuYWdlclwiO1xuaW1wb3J0IHsgTG9nZ2luZywgUGh5c2ljYWxSZXNvdXJjZUlkIH0gZnJvbSBcImF3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXNcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBJUmFiYml0TXFCcm9rZXIgfSBmcm9tIFwiLi4vcmFiYml0bXEtYnJva2VyXCI7XG5pbXBvcnQgeyBSYWJiaXRNcUN1c3RvbVJlc291cmNlU2luZ2xldG9uRnVuY3Rpb24gfSBmcm9tIFwiLi9yYWJiaXRtcS1jdXN0b20tcmVzb3VyY2Utc2luZ2xldG9uLWZ1bmN0aW9uXCI7XG5cbmNvbnN0IEhBU0hfTEVOID0gMTY7XG5cbi8qKlxuICogQWxsIGh0dHAgcmVxdWVzdCBtZXRob2RzXG4gKi9cbmV4cG9ydCBlbnVtIEh0dHBNZXRob2RzIHtcbiAgR0VUID0gXCJHRVRcIixcbiAgUE9TVCA9IFwiUE9TVFwiLFxuICBQVVQgPSBcIlBVVFwiLFxuICBERUxFVEUgPSBcIkRFTEVURVwiLFxufVxuXG4vKipcbiAqIEEgUmFiYml0TVEgTWFuYWdlbWVudCBIVFRQIEFQSSBjYWxsXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmFiYml0TXFBcGlDYWxsIHtcbiAgLyoqXG4gICAqIFRoZSBSYWJiaXRNUSBNYW5hZ2VtZW50IEhUVFAgQVBJIGNhbGwgcGF0aC5cbiAgICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEhUVFAgTWV0aG9kIHVzZWQgd2hlbiBpbnZva2luZyB0aGUgUmFiYml0TVEgTWFuYWdlbWVudCBIVFRQIEFQSSBjYWxsLlxuICAgKiBAZGVmYXVsdCBHRVRcbiAgICovXG4gIHJlYWRvbmx5IG1ldGhvZD86IEh0dHBNZXRob2RzO1xuXG4gIC8qKlxuICAgKiBUaGUgcGF5bG9hZCBleHBlY3RlZCBieSB0aGUgUmFiYml0TVEgTWFuYWdlbWVudCBIVFRQIEFQSSBjYWxsLlxuICAgKi9cbiAgcmVhZG9ubHkgcGF5bG9hZD86IHsgW2tleTogc3RyaW5nXTogYW55IH07XG4gIC8qKlxuICAgKiBUaGUgcGh5c2ljYWwgcmVzb3VyY2UgaWQgb2YgdGhlIGN1c3RvbSByZXNvdXJjZSBmb3IgdGhpcyBjYWxsLlxuICAgKiBNYW5kYXRvcnkgZm9yIG9uQ3JlYXRlIGNhbGwuXG4gICAqIEluIG9uVXBkYXRlLCB5b3UgY2FuIG9taXQgdGhpcyB0byBwYXNzdGhyb3VnaCBpdCBmcm9tIHJlcXVlc3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcGh5c2ljYWwgcmVzb3VyY2UgaWRcbiAgICovXG4gIHJlYWRvbmx5IHBoeXNpY2FsUmVzb3VyY2VJZD86IFBoeXNpY2FsUmVzb3VyY2VJZDtcblxuICAvKipcbiAgICogUmVzdHJpY3QgdGhlIGRhdGEgcmV0dXJuZWQgYnkgdGhlIGN1c3RvbSByZXNvdXJjZSB0byBzcGVjaWZpYyBwYXRocyBpbiB0aGUgQVBJIHJlc3BvbnNlLlxuICAgKlxuICAgKiBVc2UgdGhpcyB0byBsaW1pdCB0aGUgZGF0YSByZXR1cm5lZCBieSB0aGUgY3VzdG9tIHJlc291cmNlIGlmIHdvcmtpbmcgd2l0aCBBUEkgY2FsbHMgdGhhdCBjb3VsZCBwb3RlbnRpYWxseSByZXN1bHQgaW4gY3VzdG9tIHJlc3BvbnNlIG9iamVjdHMgZXhjZWVkaW5nIHRoZSBoYXJkIGxpbWl0IG9mIDQwOTYgYnl0ZXMuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRQYXRocz86IHN0cmluZ1tdO1xuICAvKipcbiAgICogQSBwcm9wZXJ0eSB1c2VkIHRvIGNvbmZpZ3VyZSBsb2dnaW5nIGR1cmluZyBsYW1iZGEgZnVuY3Rpb24gZXhlY3V0aW9uLlxuICAgKlxuICAgKiBOb3RlOiBUaGUgZGVmYXVsdCBMb2dnaW5nIGNvbmZpZ3VyYXRpb24gaXMgYWxsLiBUaGlzIGNvbmZpZ3VyYXRpb24gd2lsbCBlbmFibGUgbG9nZ2luZyBvbiBhbGwgbG9nZ2VkIGRhdGFcbiAgICogaW4gdGhlIGxhbWJkYSBoYW5kbGVyLiBUaGlzIGluY2x1ZGVzOlxuICAgKiAgLSBUaGUgZXZlbnQgb2JqZWN0IHRoYXQgaXMgcmVjZWl2ZWQgYnkgdGhlIGxhbWJkYSBoYW5kbGVyXG4gICAqICAtIFRoZSByZXNwb25zZSByZWNlaXZlZCBhZnRlciBtYWtpbmcgYSBBUEkgY2FsbFxuICAgKiAgLSBUaGUgcmVzcG9uc2Ugb2JqZWN0IHRoYXQgdGhlIGxhbWJkYSBoYW5kbGVyIHdpbGwgcmV0dXJuXG4gICAqICAtIFNESyB2ZXJzaW9uaW5nIGluZm9ybWF0aW9uXG4gICAqICAtIENhdWdodCBhbmQgdW5jYXVnaHQgZXJyb3JzXG4gICAqXG4gICAqIEBkZWZhdWx0IExvZ2dpbmcuYWxsKClcbiAgICovXG4gIHJlYWRvbmx5IGxvZ2dpbmc/OiBMb2dnaW5nO1xufVxuXG4vKipcbiAqIFRoZSBJQU0gUG9saWN5IHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBjYWxscy5cbiAqL1xuZXhwb3J0IGNsYXNzIFJhYmJpdE1xQ3VzdG9tUmVzb3VyY2VQb2xpY3kge1xuICAvKipcbiAgICogVXNlIHRoaXMgY29uc3RhbnQgdG8gY29uZmlndXJlIGFjY2VzcyB0byBhbnkgcmVzb3VyY2UuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEFOWV9SRVNPVVJDRSA9IFtcIipcIl07XG5cbiAgLyoqXG4gICAqIEV4cGxpY2l0IElBTSBQb2xpY3kgU3RhdGVtZW50cy5cbiAgICpcbiAgICogQHBhcmFtIHN0YXRlbWVudHMgdGhlIHN0YXRlbWVudHMgdG8gcHJvcGFnYXRlIHRvIHRoZSBTREsgY2FsbHMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21TdGF0ZW1lbnRzKHN0YXRlbWVudHM6IFBvbGljeVN0YXRlbWVudFtdKSB7XG4gICAgcmV0dXJuIG5ldyBSYWJiaXRNcUN1c3RvbVJlc291cmNlUG9saWN5KHN0YXRlbWVudHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBzdGF0ZW1lbnRzIHN0YXRlbWVudHMgZm9yIGV4cGxpY2l0IHBvbGljeS5cbiAgICogQHBhcmFtIHJlc291cmNlcyByZXNvdXJjZXMgZm9yIGF1dG8tZ2VuZXJhdGVkIGZyb20gU0RLIGNhbGxzLlxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgc3RhdGVtZW50czogUG9saWN5U3RhdGVtZW50W10pIHt9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgUmFiYml0TXFDdXN0b21SZXNvdXJjZS5cbiAqXG4gKiBOb3RlIHRoYXQgYXQgbGVhc3Qgb25DcmVhdGUsIG9uVXBkYXRlIG9yIG9uRGVsZXRlIG11c3QgYmUgc3BlY2lmaWVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJhYmJpdE1xQ3VzdG9tUmVzb3VyY2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgYnJva2VyIHRvIHNlbmQgcmVxdWVzdHMgdG8uXG4gICAqL1xuICByZWFkb25seSBicm9rZXI6IElSYWJiaXRNcUJyb2tlcjtcblxuICAvKipcbiAgICogVGhlIHNlY3JldCBjb250YWluaW5nIHRoZSBicm9rZXIgbG9naW4gY3JlZGVudGlhbHMuXG4gICAqL1xuICByZWFkb25seSBjcmVkZW50aWFsczogSVNlY3JldDtcblxuICAvKipcbiAgICogVGhlIFJhYmJpdE1RIE1hbmFnZW1lbnQgSFRUUCBBUEkgY2FsbCB0byBtYWtlIHdoZW4gdGhlIHJlc291cmNlIGlzIGNyZWF0ZWRcbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgY2FsbCB3aGVuIHRoZSByZXNvdXJjZSBpcyB1cGRhdGVkXG4gICAqL1xuICByZWFkb25seSBvbkNyZWF0ZT86IFJhYmJpdE1xQXBpQ2FsbDtcblxuICAvKipcbiAgICogVGhlIFJhYmJpdE1RIE1hbmFnZW1lbnQgSFRUUCBBUEkgY2FsbCB0byBtYWtlIHdoZW4gdGhlIHJlc291cmNlIGlzIHVwZGF0ZWRcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBjYWxsXG4gICAqL1xuICByZWFkb25seSBvblVwZGF0ZT86IFJhYmJpdE1xQXBpQ2FsbDtcblxuICAvKipcbiAgICogVGhlIFJhYmJpdE1RIE1hbmFnZW1lbnQgSFRUUCBBUEkgY2FsbCB0byBtYWtlIHdoZW4gdGhlIHJlc291cmNlIGlzIHVwZGF0ZWRcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBjYWxsXG4gICAqL1xuICByZWFkb25seSBvbkRlbGV0ZT86IFJhYmJpdE1xQXBpQ2FsbDtcblxuICAvKipcbiAgICogVGhlIHZwYyB0byBjb25uZWN0IHRvLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjPzogSVZwYztcblxuICAvKipcbiAgICogVGhlIHZwYyBzdWJuZXRzIHRvIGNvbm5lY3QgdG8uXG4gICAqL1xuICByZWFkb25seSB2cGNTdWJuZXRzPzogU3VibmV0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VjdXJpdHkgZ3JvdXBzIHRvIGFzc2lnbiB0byB0aGUgZnVuY3Rpb24uXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IFNlY3VyaXR5R3JvdXBbXTtcblxuICAvKipcbiAgICogTG9nR3JvdXAgcmV0ZW50aW9uIHRvIHVzZSBmb3IgdGhlIGZ1bmN0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IFJldGVudGlvbkRheXMuSU5GSU5JVEVcbiAgICogQGRlcHJlY2F0ZWQgdXNlIGxvZ0dyb3VwIGluc3RlYWRcbiAgICovXG4gIHJlYWRvbmx5IGxvZ1JldGVudGlvbj86IFJldGVudGlvbkRheXM7XG5cbiAgLyoqXG4gICAqIFRoZSBsb2dHcm91cCB0byB1c2UgZm9yIHRoZSBmdW5jdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgbG9nR3JvdXA/OiBMb2dHcm91cDtcblxuICAvKipcbiAgICogVGhlIHRpbWVvdXQgZm9yIHRoZSBjdXN0b20gcmVzb3VyY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IER1cmF0aW9uLm1pbnV0ZXMoMSlcbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBEdXJhdGlvbjtcblxuICAvKipcbiAgICogVGhlIGV4ZWN1dGlvbiByb2xlIGZvciB0aGUgZnVuY3Rpb24uXG4gICAqL1xuICByZWFkb25seSByb2xlPzogSVJvbGU7XG5cbiAgLyoqXG4gICAqIFRoZSBwb2xpY2llcyB0byBhdHRhY2ggdG8gdGhlIGZ1bmN0aW9uJ3Mgcm9sZVxuICAgKi9cbiAgcmVhZG9ubHkgcG9saWN5PzogUmFiYml0TXFDdXN0b21SZXNvdXJjZVBvbGljeTtcbn1cblxuLyoqXG4gKiBAZXhwZXJpbWVudGFsXG4gKlxuICogRGVmaW5lcyBhIGN1c3RvbSByZXNvdXJjZSB0aGF0IGlzIG1hdGVyaWFsaXplZCB1c2luZyBzcGVjaWZpYyBSYWJiaXRNUSBNYW5hZ2VtZW50IEhUVFAgQVBJIGNhbGxzLlxuICpcbiAqIFVzZSB0aGlzIHRvIGludGVyYWN0IHdpdGggdGhlIEFtYXpvbiBNUSBmb3IgUmFiYml0TVEgYnJva2VyLiBZb3UgY2FuIHNwZWNpZnkgZXhhY3RseSB3aGljaCBjYWxscyBhcmUgaW52b2tlZCBmb3IgdGhlICdDUkVBVEUnLCAnVVBEQVRFJyBhbmQgJ0RFTEVURScgbGlmZSBjeWNsZSBldmVudHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBSYWJiaXRNcUN1c3RvbVJlc291cmNlXG4gIGV4dGVuZHMgQ29uc3RydWN0XG4gIGltcGxlbWVudHMgSUNvbm5lY3RhYmxlLCBJR3JhbnRhYmxlXG57XG4gIHB1YmxpYyByZWFkb25seSBjb25uZWN0aW9uczogQ29ubmVjdGlvbnM7XG5cbiAgcHVibGljIHJlYWRvbmx5IGdyYW50UHJpbmNpcGFsOiBJUHJpbmNpcGFsO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2U6IEN1c3RvbVJlc291cmNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogUmFiYml0TXFDdXN0b21SZXNvdXJjZVByb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgaWYgKCFwcm9wcy5vbkNyZWF0ZSAmJiAhcHJvcHMub25VcGRhdGUgJiYgIXByb3BzLm9uRGVsZXRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiQXQgbGVhc3QgYG9uQ3JlYXRlYCwgYG9uVXBkYXRlYCBvciBgb25EZWxldGVgIG11c3QgYmUgc3BlY2lmaWVkLlwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMub25DcmVhdGUgJiYgIXByb3BzLm9uQ3JlYXRlLnBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIidwaHlzaWNhbFJlc291cmNlSWQnIG11c3QgYmUgc3BlY2lmaWVkIGZvciAnb25DcmVhdGUnIGNhbGwuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICFwcm9wcy5vbkNyZWF0ZSAmJlxuICAgICAgcHJvcHMub25VcGRhdGUgJiZcbiAgICAgICFwcm9wcy5vblVwZGF0ZS5waHlzaWNhbFJlc291cmNlSWRcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCIncGh5c2ljYWxSZXNvdXJjZUlkJyBtdXN0IGJlIHNwZWNpZmllZCBmb3IgJ29uVXBkYXRlJyBjYWxsIHdoZW4gJ29uQ3JlYXRlJyBpcyBvbWl0dGVkLlwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgc2VjdXJpdHlHcm91cHMgPSBwcm9wcy52cGNcbiAgICAgID8gcHJvcHMuc2VjdXJpdHlHcm91cHMgfHwgW1xuICAgICAgICAgIG5ldyBTZWN1cml0eUdyb3VwKHRoaXMsIFwiUHJvdmlkZXJTR1wiLCB7IHZwYzogcHJvcHMudnBjIH0pLFxuICAgICAgICBdXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHV1aWQgPSB0aGlzLnJlbmRlclVuaXF1ZUlkKFxuICAgICAgcHJvcHMuYnJva2VyLFxuICAgICAgcHJvcHMuY3JlZGVudGlhbHMsXG4gICAgICBwcm9wcy52cGMsXG4gICAgICBwcm9wcy52cGNTdWJuZXRzLFxuICAgICAgcHJvcHMuc2VjdXJpdHlHcm91cHMsXG4gICAgKTtcblxuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IFJhYmJpdE1xQ3VzdG9tUmVzb3VyY2VTaW5nbGV0b25GdW5jdGlvbihcbiAgICAgIHRoaXMsXG4gICAgICBcIlByb3ZpZGVyXCIsXG4gICAgICB7XG4gICAgICAgIHV1aWQsXG4gICAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgICB2cGNTdWJuZXRzOiBwcm9wcy52cGNTdWJuZXRzLFxuICAgICAgICBzZWN1cml0eUdyb3Vwczogc2VjdXJpdHlHcm91cHMsXG4gICAgICAgIC4uLihwcm9wcy5sb2dSZXRlbnRpb24gPyB7IGxvZ1JldGVudGlvbjogcHJvcHMubG9nUmV0ZW50aW9uIH0gOiB7fSksXG4gICAgICAgIGxvZ0dyb3VwOiBwcm9wcy5sb2dHcm91cCxcbiAgICAgICAgdGltZW91dDogcHJvcHMudGltZW91dCB8fCBEdXJhdGlvbi5taW51dGVzKDEpLFxuICAgICAgICBpbml0aWFsUG9saWN5OiBwcm9wcy5wb2xpY3k/LnN0YXRlbWVudHMsXG4gICAgICB9LFxuICAgICk7XG5cbiAgICBjb25zdCBvblVwZGF0ZSA9IHByb3BzLm9uVXBkYXRlICYmIHRoaXMuZm9ybWF0U2RrQ2FsbChwcm9wcy5vblVwZGF0ZSk7XG4gICAgY29uc3Qgb25DcmVhdGUgPVxuICAgICAgKHByb3BzLm9uQ3JlYXRlICYmIHRoaXMuZm9ybWF0U2RrQ2FsbChwcm9wcy5vbkNyZWF0ZSkpIHx8IG9uVXBkYXRlO1xuICAgIGNvbnN0IG9uRGVsZXRlID0gcHJvcHMub25EZWxldGUgJiYgdGhpcy5mb3JtYXRTZGtDYWxsKHByb3BzLm9uRGVsZXRlKTtcblxuICAgIHRoaXMucmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgYFJlc291cmNlJHt1dWlkfWAsIHtcbiAgICAgIHJlc291cmNlVHlwZTogXCJDdXN0b206OlJNUUFQSVwiLFxuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5mdW5jdGlvbkFybixcbiAgICAgIHBhc2NhbENhc2VQcm9wZXJ0aWVzOiB0cnVlLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICB1cmw6IHByb3BzLmJyb2tlci5lbmRwb2ludHMuY29uc29sZS51cmwsXG4gICAgICAgIGNyZWRlbnRpYWxzOiBwcm9wcy5jcmVkZW50aWFscy5zZWNyZXRBcm4sXG4gICAgICAgIGNyZWF0ZTogb25DcmVhdGUsXG4gICAgICAgIHVwZGF0ZTogb25VcGRhdGUsXG4gICAgICAgIGRlbGV0ZTogb25EZWxldGUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IG5ldyBDb25uZWN0aW9ucyh7XG4gICAgICBzZWN1cml0eUdyb3VwcyxcbiAgICB9KTtcblxuICAgIHByb3BzLmNyZWRlbnRpYWxzLmdyYW50UmVhZChwcm92aWRlcik7XG5cbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gcHJvdmlkZXIuZ3JhbnRQcmluY2lwYWw7XG4gIH1cblxuICBwdWJsaWMgZ2V0UmVzcG9uc2VGaWVsZChrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2UuZ2V0QXR0U3RyaW5nKGtleSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UmVzcG9uc2VGaWVsZFJlZmVyZW5jZShrZXk6IHN0cmluZyk6IFJlZmVyZW5jZSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2UuZ2V0QXR0KGtleSk7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdFNka0NhbGwoc2RrQ2FsbDogUmFiYml0TXFBcGlDYWxsKSB7XG4gICAgY29uc3QgeyBsb2dnaW5nLCAuLi5jYWxsIH0gPSBzZGtDYWxsO1xuICAgIGNvbnN0IHJlbmRlcmVkTG9nZ2luZyA9IChsb2dnaW5nID8/IExvZ2dpbmcuYWxsKCkpLl9yZW5kZXIodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMuZW5jb2RlSnNvbih7XG4gICAgICAuLi5jYWxsLFxuICAgICAgLi4ucmVuZGVyZWRMb2dnaW5nLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBlbmNvZGVKc29uKG9iajogYW55KSB7XG4gICAgcmV0dXJuIExhenkudW5jYWNoZWRTdHJpbmcoe1xuICAgICAgcHJvZHVjZTogKCkgPT4gU3RhY2sub2YodGhpcykudG9Kc29uU3RyaW5nKG9iaiksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclVuaXF1ZUlkKFxuICAgIGJyb2tlcjogSVJhYmJpdE1xQnJva2VyLFxuICAgIGNyZWRzOiBJU2VjcmV0LFxuICAgIHZwYz86IElWcGMsXG4gICAgc3VibmV0cz86IFN1Ym5ldFNlbGVjdGlvbixcbiAgICBzZWN1cml0eUdyb3Vwcz86IElTZWN1cml0eUdyb3VwW10sXG4gICkge1xuICAgIGxldCBoYXNoQ29udGVudCA9IFwiXCI7XG4gICAgY29uc3QgcmVzb3VyY2VCcm9rZXIgPSBicm9rZXIgYXMgSVJlc291cmNlO1xuICAgIGhhc2hDb250ZW50ICs9IE5hbWVzLnVuaXF1ZUlkKHJlc291cmNlQnJva2VyKTtcbiAgICBoYXNoQ29udGVudCArPSBOYW1lcy51bmlxdWVJZChjcmVkcyk7XG4gICAgaWYgKHZwYykge1xuICAgICAgaGFzaENvbnRlbnQgKz0gTmFtZXMudW5pcXVlSWQodnBjKTtcbiAgICAgIGlmIChzdWJuZXRzKSB7XG4gICAgICAgIGhhc2hDb250ZW50ICs9IHZwY1xuICAgICAgICAgIC5zZWxlY3RTdWJuZXRzKHN1Ym5ldHMpXG4gICAgICAgICAgLnN1Ym5ldHMubWFwKChzKSA9PiBOYW1lcy51bmlxdWVJZChzKSlcbiAgICAgICAgICAuam9pbihcIlwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChzZWN1cml0eUdyb3Vwcykge1xuICAgICAgICBoYXNoQ29udGVudCArPSBzZWN1cml0eUdyb3Vwcy5tYXAoKHNnKSA9PiBOYW1lcy51bmlxdWVJZChzZykpLmpvaW4oXCJcIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSU5GTzogcnVuIHRoaXMgdGhyb3VnaCB0aGUgQ0RLIHRlYW0gYXMgaW4gdGhlIFMzIEJ1Y2tldCBEZXBsb3ltZW50IGltcGxlbWVudGF0aW9uIHRoZXJlIGlzIG5vIGhhc2hpbmcsIGp1c3QgdmVyYmF0aW0gdmFsdWUgYWRkaXRpb25cbiAgICAvLyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9ibG9iLzMxOGVhZTZjOWVjYTQ1NmUwYzM0ZWQyMTg1NWRhZDlkMmJmYTJhMGYvcGFja2FnZXMvYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnQvbGliL2J1Y2tldC1kZXBsb3ltZW50LnRzI0w1NTZcblxuICAgIHJldHVybiBjcmVhdGVIYXNoKFwic2hhMjU2XCIpXG4gICAgICAudXBkYXRlKGhhc2hDb250ZW50KVxuICAgICAgLmRpZ2VzdChcImhleFwiKVxuICAgICAgLnNsaWNlKDAsIEhBU0hfTEVOKVxuICAgICAgLnRvVXBwZXJDYXNlKCk7XG4gIH1cbn1cbiJdfQ==