alias.js
1 "use strict"; 2 var _a; 3 Object.defineProperty(exports, "__esModule", { value: true }); 4 exports.Alias = void 0; 5 const jsiiDeprecationWarnings = require("../.warnings.jsii.js"); 6 const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); 7 const appscaling = require("@aws-cdk/aws-applicationautoscaling"); 8 const iam = require("@aws-cdk/aws-iam"); 9 const core_1 = require("@aws-cdk/core"); 10 const function_base_1 = require("./function-base"); 11 const lambda_version_1 = require("./lambda-version"); 12 const lambda_generated_1 = require("./lambda.generated"); 13 const scalable_function_attribute_1 = require("./private/scalable-function-attribute"); 14 /** 15 * A new alias to a particular version of a Lambda function. 16 * 17 * @stability stable 18 */ 19 class Alias extends function_base_1.QualifiedFunctionBase { 20 /** 21 * @stability stable 22 */ 23 constructor(scope, id, props) { 24 super(scope, id, { 25 physicalName: props.aliasName, 26 }); 27 /** 28 * Whether the addPermission() call adds any permissions. 29 * 30 * True for new Lambdas, false for version $LATEST and imported Lambdas 31 * from different accounts. 32 * 33 * @stability stable 34 */ 35 this.canCreatePermissions = true; 36 jsiiDeprecationWarnings._aws_cdk_aws_lambda_AliasProps(props); 37 this.lambda = props.version.lambda; 38 this.aliasName = this.physicalName; 39 this.version = props.version; 40 const alias = new lambda_generated_1.CfnAlias(this, 'Resource', { 41 name: this.aliasName, 42 description: props.description, 43 functionName: this.version.lambda.functionName, 44 functionVersion: props.version.version, 45 routingConfig: this.determineRoutingConfig(props), 46 provisionedConcurrencyConfig: this.determineProvisionedConcurrency(props), 47 }); 48 // Use a Service Linked Role 49 // https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html 50 this.scalingRole = iam.Role.fromRoleArn(this, 'ScalingRole', this.stack.formatArn({ 51 service: 'iam', 52 region: '', 53 resource: 'role/aws-service-role/lambda.application-autoscaling.amazonaws.com', 54 resourceName: 'AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency', 55 })); 56 this.functionArn = this.getResourceArnAttribute(alias.ref, { 57 service: 'lambda', 58 resource: 'function', 59 resourceName: `${this.lambda.functionName}:${this.physicalName}`, 60 arnFormat: core_1.ArnFormat.COLON_RESOURCE_NAME, 61 }); 62 this.qualifier = lambda_version_1.extractQualifierFromArn(alias.ref); 63 if (props.onFailure || props.onSuccess || props.maxEventAge || props.retryAttempts !== undefined) { 64 this.configureAsyncInvoke({ 65 onFailure: props.onFailure, 66 onSuccess: props.onSuccess, 67 maxEventAge: props.maxEventAge, 68 retryAttempts: props.retryAttempts, 69 }); 70 } 71 // ARN parsing splits on `:`, so we can only get the function's name from the ARN as resourceName... 72 // And we're parsing it out (instead of using the underlying function directly) in order to have use of it incur 73 // an implicit dependency on the resource. 74 this.functionName = `${this.stack.splitArn(this.functionArn, core_1.ArnFormat.COLON_RESOURCE_NAME).resourceName}:${this.aliasName}`; 75 } 76 /** 77 * @stability stable 78 */ 79 static fromAliasAttributes(scope, id, attrs) { 80 jsiiDeprecationWarnings._aws_cdk_aws_lambda_AliasAttributes(attrs); 81 class Imported extends function_base_1.QualifiedFunctionBase { 82 constructor() { 83 super(...arguments); 84 this.aliasName = attrs.aliasName; 85 this.version = attrs.aliasVersion; 86 this.lambda = attrs.aliasVersion.lambda; 87 this.functionArn = `${attrs.aliasVersion.lambda.functionArn}:${attrs.aliasName}`; 88 this.functionName = `${attrs.aliasVersion.lambda.functionName}:${attrs.aliasName}`; 89 this.grantPrincipal = attrs.aliasVersion.grantPrincipal; 90 this.role = attrs.aliasVersion.role; 91 this.canCreatePermissions = this._isStackAccount(); 92 this.qualifier = attrs.aliasName; 93 } 94 } 95 return new Imported(scope, id); 96 } 97 /** 98 * The principal this Lambda Function is running as. 99 * 100 * @stability stable 101 */ 102 get grantPrincipal() { 103 return this.version.grantPrincipal; 104 } 105 /** 106 * The IAM role associated with this function. 107 * 108 * Undefined if the function was imported without a role. 109 * 110 * @stability stable 111 */ 112 get role() { 113 return this.version.role; 114 } 115 /** 116 * Return the given named metric for this Function. 117 * 118 * @stability stable 119 */ 120 metric(metricName, props = {}) { 121 // Metrics on Aliases need the "bare" function name, and the alias' ARN, this differs from the base behavior. 122 return super.metric(metricName, { 123 dimensionsMap: { 124 FunctionName: this.lambda.functionName, 125 // construct the name from the underlying lambda so that alarms on an alias 126 // don't cause a circular dependency with CodeDeploy 127 // see: https://github.com/aws/aws-cdk/issues/2231 128 Resource: `${this.lambda.functionName}:${this.aliasName}`, 129 }, 130 ...props, 131 }); 132 } 133 /** 134 * Configure provisioned concurrency autoscaling on a function alias. 135 * 136 * Returns a scalable attribute that can call 137 * `scaleOnUtilization()` and `scaleOnSchedule()`. 138 * 139 * @param options Autoscaling options. 140 * @stability stable 141 */ 142 addAutoScaling(options) { 143 var _b; 144 jsiiDeprecationWarnings._aws_cdk_aws_lambda_AutoScalingOptions(options); 145 if (this.scalableAlias) { 146 throw new Error('AutoScaling already enabled for this alias'); 147 } 148 return this.scalableAlias = new scalable_function_attribute_1.ScalableFunctionAttribute(this, 'AliasScaling', { 149 minCapacity: (_b = options.minCapacity) !== null && _b !== void 0 ? _b : 1, 150 maxCapacity: options.maxCapacity, 151 resourceId: `function:${this.functionName}`, 152 dimension: 'lambda:function:ProvisionedConcurrency', 153 serviceNamespace: appscaling.ServiceNamespace.LAMBDA, 154 role: this.scalingRole, 155 }); 156 } 157 /** 158 * Calculate the routingConfig parameter from the input props 159 */ 160 determineRoutingConfig(props) { 161 if (!props.additionalVersions || props.additionalVersions.length === 0) { 162 return undefined; 163 } 164 this.validateAdditionalWeights(props.additionalVersions); 165 return { 166 additionalVersionWeights: props.additionalVersions.map(vw => { 167 return { 168 functionVersion: vw.version.version, 169 functionWeight: vw.weight, 170 }; 171 }), 172 }; 173 } 174 /** 175 * Validate that the additional version weights make sense 176 * 177 * We validate that they are positive and add up to something <= 1. 178 */ 179 validateAdditionalWeights(weights) { 180 const total = weights.map(w => { 181 if (w.weight < 0 || w.weight > 1) { 182 throw new Error(`Additional version weight must be between 0 and 1, got: ${w.weight}`); 183 } 184 return w.weight; 185 }).reduce((a, x) => a + x); 186 if (total > 1) { 187 throw new Error(`Sum of additional version weights must not exceed 1, got: ${total}`); 188 } 189 } 190 /** 191 * Validate that the provisionedConcurrentExecutions makes sense 192 * 193 * Member must have value greater than or equal to 1 194 */ 195 determineProvisionedConcurrency(props) { 196 if (!props.provisionedConcurrentExecutions) { 197 return undefined; 198 } 199 if (props.provisionedConcurrentExecutions <= 0) { 200 throw new Error('provisionedConcurrentExecutions must have value greater than or equal to 1'); 201 } 202 return { provisionedConcurrentExecutions: props.provisionedConcurrentExecutions }; 203 } 204 } 205 exports.Alias = Alias; 206 _a = JSII_RTTI_SYMBOL_1; 207 Alias[_a] = { fqn: "@aws-cdk/aws-lambda.Alias", version: "1.134.0" }; 208 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxpYXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhbGlhcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxrRUFBa0U7QUFFbEUsd0NBQXdDO0FBQ3hDLHdDQUEwQztBQUcxQyxtREFBbUU7QUFDbkUscURBQXFFO0FBQ3JFLHlEQUE4QztBQUM5Qyx1RkFBa0Y7Ozs7OztBQXNDbEYsTUFBYSxLQUFNLFNBQVEscUNBQXFCOzs7O0lBb0M5QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQWlCO1FBQ3pELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsWUFBWSxFQUFFLEtBQUssQ0FBQyxTQUFTO1NBQzlCLENBQUMsQ0FBQzs7Ozs7Ozs7O1FBUmMseUJBQW9CLEdBQVksSUFBSSxDQUFDOztRQVV0RCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQ25DLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUNuQyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFFN0IsTUFBTSxLQUFLLEdBQUcsSUFBSSwyQkFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDM0MsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3BCLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztZQUM5QixZQUFZLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtZQUM5QyxlQUFlLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPO1lBQ3RDLGFBQWEsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDO1lBQ2pELDRCQUE0QixFQUFFLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLENBQUM7U0FDMUUsQ0FBQyxDQUFDO1FBRUgsNEJBQTRCO1FBQzVCLG1IQUFtSDtRQUNuSCxJQUFJLENBQUMsV0FB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IGZyb20gJ0Bhd3MtY2RrL2F3cy1hcHBsaWNhdGlvbmF1dG9zY2FsaW5nJztcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSAnQGF3cy1jZGsvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ0Bhd3MtY2RrL2F3cy1pYW0nO1xuaW1wb3J0IHsgQXJuRm9ybWF0IH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEV2ZW50SW52b2tlQ29uZmlnT3B0aW9ucyB9IGZyb20gJy4vZXZlbnQtaW52b2tlLWNvbmZpZyc7XG5pbXBvcnQgeyBJRnVuY3Rpb24sIFF1YWxpZmllZEZ1bmN0aW9uQmFzZSB9IGZyb20gJy4vZnVuY3Rpb24tYmFzZSc7XG5pbXBvcnQgeyBleHRyYWN0UXVhbGlmaWVyRnJvbUFybiwgSVZlcnNpb24gfSBmcm9tICcuL2xhbWJkYS12ZXJzaW9uJztcbmltcG9ydCB7IENmbkFsaWFzIH0gZnJvbSAnLi9sYW1iZGEuZ2VuZXJhdGVkJztcbmltcG9ydCB7IFNjYWxhYmxlRnVuY3Rpb25BdHRyaWJ1dGUgfSBmcm9tICcuL3ByaXZhdGUvc2NhbGFibGUtZnVuY3Rpb24tYXR0cmlidXRlJztcbmltcG9ydCB7IEF1dG9TY2FsaW5nT3B0aW9ucywgSVNjYWxhYmxlRnVuY3Rpb25BdHRyaWJ1dGUgfSBmcm9tICcuL3NjYWxhYmxlLWF0dHJpYnV0ZS1hcGknO1xuXG5leHBvcnQgaW50ZXJmYWNlIElBbGlhcyBleHRlbmRzIElGdW5jdGlvbiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYWxpYXNOYW1lOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHZlcnNpb246IElWZXJzaW9uO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBBbGlhc09wdGlvbnMgZXh0ZW5kcyBFdmVudEludm9rZUNvbmZpZ09wdGlvbnMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYWRkaXRpb25hbFZlcnNpb25zPzogVmVyc2lvbldlaWdodFtdO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHByb3Zpc2lvbmVkQ29uY3VycmVudEV4ZWN1dGlvbnM/OiBudW1iZXI7XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIEFsaWFzUHJvcHMgZXh0ZW5kcyBBbGlhc09wdGlvbnMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYWxpYXNOYW1lOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSB2ZXJzaW9uOiBJVmVyc2lvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBbGlhc0F0dHJpYnV0ZXMge1xuICByZWFkb25seSBhbGlhc05hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgYWxpYXNWZXJzaW9uOiBJVmVyc2lvbjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBjbGFzcyBBbGlhcyBleHRlbmRzIFF1YWxpZmllZEZ1bmN0aW9uQmFzZSBpbXBsZW1lbnRzIElBbGlhcyB7XG4gIHB1YmxpYyBzdGF0aWMgZnJvbUFsaWFzQXR0cmlidXRlcyhzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBhdHRyczogQWxpYXNBdHRyaWJ1dGVzKTogSUFsaWFzIHtcbiAgICBjbGFzcyBJbXBvcnRlZCBleHRlbmRzIFF1YWxpZmllZEZ1bmN0aW9uQmFzZSBpbXBsZW1lbnRzIElBbGlhcyB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgYWxpYXNOYW1lID0gYXR0cnMuYWxpYXNOYW1lO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHZlcnNpb24gPSBhdHRycy5hbGlhc1ZlcnNpb247XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgbGFtYmRhID0gYXR0cnMuYWxpYXNWZXJzaW9uLmxhbWJkYTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbkFybiA9IGAke2F0dHJzLmFsaWFzVmVyc2lvbi5sYW1iZGEuZnVuY3Rpb25Bcm59OiR7YXR0cnMuYWxpYXNOYW1lfWA7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZnVuY3Rpb25OYW1lID0gYCR7YXR0cnMuYWxpYXNWZXJzaW9uLmxhbWJkYS5mdW5jdGlvbk5hbWV9OiR7YXR0cnMuYWxpYXNOYW1lfWA7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWwgPSBhdHRycy5hbGlhc1ZlcnNpb24uZ3JhbnRQcmluY2lwYWw7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcm9sZSA9IGF0dHJzLmFsaWFzVmVyc2lvbi5yb2xlO1xuXG4gICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2FuQ3JlYXRlUGVybWlzc2lvbnMgPSB0aGlzLl9pc1N0YWNrQWNjb3VudCgpO1xuICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IHF1YWxpZmllciA9IGF0dHJzLmFsaWFzTmFtZTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJbXBvcnRlZChzY29wZSwgaWQpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgYWxpYXNOYW1lOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbk5hbWU6IHN0cmluZztcblxuICBwdWJsaWMgcmVhZG9ubHkgbGFtYmRhOiBJRnVuY3Rpb247XG5cbiAgcHVibGljIHJlYWRvbmx5IHZlcnNpb246IElWZXJzaW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbkFybjogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBxdWFsaWZpZXI6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2FuQ3JlYXRlUGVybWlzc2lvbnM6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIHByaXZhdGUgc2NhbGFibGVBbGlhcz86IFNjYWxhYmxlRnVuY3Rpb25BdHRyaWJ1dGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2NhbGluZ1JvbGU6IGlhbS5JUm9sZTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQWxpYXNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgcGh5c2ljYWxOYW1lOiBwcm9wcy5hbGlhc05hbWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmxhbWJkYSA9IHByb3BzLnZlcnNpb24ubGFtYmRhO1xuICAgIHRoaXMuYWxpYXNOYW1lID0gdGhpcy5waHlzaWNhbE5hbWU7XG4gICAgdGhpcy52ZXJzaW9uID0gcHJvcHMudmVyc2lvbjtcblxuICAgIGNvbnN0IGFsaWFzID0gbmV3IENmbkFsaWFzKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIG5hbWU6IHRoaXMuYWxpYXNOYW1lLFxuICAgICAgZGVzY3JpcHRpb246IHByb3BzLmRlc2NyaXB0aW9uLFxuICAgICAgZnVuY3Rpb25OYW1lOiB0aGlzLnZlcnNpb24ubGFtYmRhLmZ1bmN0aW9uTmFtZSxcbiAgICAgIGZ1bmN0aW9uVmVyc2lvbjogcHJvcHMudmVyc2lvbi52ZXJzaW9uLFxuICAgICAgcm91dGluZ0NvbmZpZzogdGhpcy5kZXRlcm1pbmVSb3V0aW5nQ29uZmlnKHByb3BzKSxcbiAgICAgIHByb3Zpc2lvbmVkQ29uY3VycmVuY3lDb25maWc6IHRoaXMuZGV0ZXJtaW5lUHJvdmlzaW9uZWRDb25jdXJyZW5jeShwcm9wcyksXG4gICAgfSk7XG5cbiAgICAvLyBVc2UgYSBTZXJ2aWNlIExpbmtlZCBSb2xlXG4gICAgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F1dG9zY2FsaW5nL2FwcGxpY2F0aW9uL3VzZXJndWlkZS9hcHBsaWNhdGlvbi1hdXRvLXNjYWxpbmctc2VydmljZS1saW5rZWQtcm9sZXMuaHRtbFxuICAgIHRoaXMuc2NhbGluZ1JvbGUgPSBpYW0uUm9sZS5mcm9tUm9sZUFybih0aGlzLCAnU2NhbGluZ1JvbGUnLCB0aGlzLnN0YWNrLmZvcm1hdEFybih7XG4gICAgICBzZXJ2aWNlOiAnaWFtJyxcbiAgICAgIHJlZ2lvbjogJycsXG4gICAgICByZXNvdXJjZTogJ3JvbGUvYXdzLXNlcnZpY2Utcm9sZS9sYW1iZGEuYXBwbGljYXRpb24tYXV0b3NjYWxpbmcuYW1hem9uYXdzLmNvbScsXG4gICAgICByZXNvdXJjZU5hbWU6ICdBV1NTZXJ2aWNlUm9sZUZvckFwcGxpY2F0aW9uQXV0b1NjYWxpbmdfTGFtYmRhQ29uY3VycmVuY3knLFxuICAgIH0pKTtcblxuICAgIHRoaXMuZnVuY3Rpb25Bcm4gPSB0aGlzLmdldFJlc291cmNlQXJuQXR0cmlidXRlKGFsaWFzLnJlZiwge1xuICAgICAgc2VydmljZTogJ2xhbWJkYScsXG4gICAgICByZXNvdXJjZTogJ2Z1bmN0aW9uJyxcbiAgICAgIHJlc291cmNlTmFtZTogYCR7dGhpcy5sYW1iZGEuZnVuY3Rpb25OYW1lfToke3RoaXMucGh5c2ljYWxOYW1lfWAsXG4gICAgICBhcm5Gb3JtYXQ6IEFybkZvcm1hdC5DT0xPTl9SRVNPVVJDRV9OQU1FLFxuICAgIH0pO1xuXG4gICAgdGhpcy5xdWFsaWZpZXIgPSBleHRyYWN0UXVhbGlmaWVyRnJvbUFybihhbGlhcy5yZWYpO1xuXG4gICAgaWYgKHByb3BzLm9uRmFpbHVyZSB8fCBwcm9wcy5vblN1Y2Nlc3MgfHwgcHJvcHMubWF4RXZlbnRBZ2UgfHwgcHJvcHMucmV0cnlBdHRlbXB0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmNvbmZpZ3VyZUFzeW5jSW52b2tlKHtcbiAgICAgICAgb25GYWlsdXJlOiBwcm9wcy5vbkZhaWx1cmUsXG4gICAgICAgIG9uU3VjY2VzczogcHJvcHMub25TdWNjZXNzLFxuICAgICAgICBtYXhFdmVudEFnZTogcHJvcHMubWF4RXZlbnRBZ2UsXG4gICAgICAgIHJldHJ5QXR0ZW1wdHM6IHByb3BzLnJldHJ5QXR0ZW1wdHMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBUk4gcGFyc2luZyBzcGxpdHMgb24gYDpgLCBzbyB3ZSBjYW4gb25seSBnZXQgdGhlIGZ1bmN0aW9uJ3MgbmFtZSBmcm9tIHRoZSBBUk4gYXMgcmVzb3VyY2VOYW1lLi4uXG4gICAgLy8gQW5kIHdlJ3JlIHBhcnNpbmcgaXQgb3V0IChpbnN0ZWFkIG9mIHVzaW5nIHRoZSB1bmRlcmx5aW5nIGZ1bmN0aW9uIGRpcmVjdGx5KSBpbiBvcmRlciB0byBoYXZlIHVzZSBvZiBpdCBpbmN1clxuICAgIC8vIGFuIGltcGxpY2l0IGRlcGVuZGVuY3kgb24gdGhlIHJlc291cmNlLlxuICAgIHRoaXMuZnVuY3Rpb25OYW1lID0gYCR7dGhpcy5zdGFjay5zcGxpdEFybih0aGlzLmZ1bmN0aW9uQXJuLCBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSkucmVzb3VyY2VOYW1lIX06JHt0aGlzLmFsaWFzTmFtZX1gO1xuICB9XG5cbiAgcHVibGljIGdldCBncmFudFByaW5jaXBhbCgpIHtcbiAgICByZXR1cm4gdGhpcy52ZXJzaW9uLmdyYW50UHJpbmNpcGFsO1xuICB9XG5cbiAgcHVibGljIGdldCByb2xlKCkge1xuICAgIHJldHVybiB0aGlzLnZlcnNpb24ucm9sZTtcbiAgfVxuXG4gIHB1YmxpYyBtZXRyaWMobWV0cmljTmFtZTogc3RyaW5nLCBwcm9wczogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zID0ge30pOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgLy8gTWV0cmljcyBvbiBBbGlhc2VzIG5lZWQgdGhlIFwiYmFyZVwiIGZ1bmN0aW9uIG5hbWUsIGFuZCB0aGUgYWxpYXMnIEFSTiwgdGhpcyBkaWZmZXJzIGZyb20gdGhlIGJhc2UgYmVoYXZpb3IuXG4gICAgcmV0dXJuIHN1cGVyLm1ldHJpYyhtZXRyaWNOYW1lLCB7XG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIEZ1bmN0aW9uTmFtZTogdGhpcy5sYW1iZGEuZnVuY3Rpb25OYW1lLFxuICAgICAgICAvLyBjb25zdHJ1Y3QgdGhlIG5hbWUgZnJvbSB0aGUgdW5kZXJseWluZyBsYW1iZGEgc28gdGhhdCBhbGFybXMgb24gYW4gYWxpYXNcbiAgICAgICAgLy8gZG9uJ3QgY2F1c2UgYSBjaXJjdWxhciBkZXBlbmRlbmN5IHdpdGggQ29kZURlcGxveVxuICAgICAgICAvLyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvMjIzMVxuICAgICAgICBSZXNvdXJjZTogYCR7dGhpcy5sYW1iZGEuZnVuY3Rpb25OYW1lfToke3RoaXMuYWxpYXNOYW1lfWAsXG4gICAgICB9LFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGFkZEF1dG9TY2FsaW5nKG9wdGlvbnM6IEF1dG9TY2FsaW5nT3B0aW9ucyk6IElTY2FsYWJsZUZ1bmN0aW9uQXR0cmlidXRlIHtcbiAgICBpZiAodGhpcy5zY2FsYWJsZUFsaWFzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1dG9TY2FsaW5nIGFscmVhZHkgZW5hYmxlZCBmb3IgdGhpcyBhbGlhcycpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zY2FsYWJsZUFsaWFzID0gbmV3IFNjYWxhYmxlRnVuY3Rpb25BdHRyaWJ1dGUodGhpcywgJ0FsaWFzU2NhbGluZycsIHtcbiAgICAgIG1pbkNhcGFjaXR5OiBvcHRpb25zLm1pbkNhcGFjaXR5ID8/IDEsXG4gICAgICBtYXhDYXBhY2l0eTogb3B0aW9ucy5tYXhDYXBhY2l0eSxcbiAgICAgIHJlc291cmNlSWQ6IGBmdW5jdGlvbjoke3RoaXMuZnVuY3Rpb25OYW1lfWAsXG4gICAgICBkaW1lbnNpb246ICdsYW1iZGE6ZnVuY3Rpb246UHJvdmlzaW9uZWRDb25jdXJyZW5jeScsXG4gICAgICBzZXJ2aWNlTmFtZXNwYWNlOiBhcHBzY2FsaW5nLlNlcnZpY2VOYW1lc3BhY2UuTEFNQkRBLFxuICAgICAgcm9sZTogdGhpcy5zY2FsaW5nUm9sZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIHJvdXRpbmdDb25maWcgcGFyYW1ldGVyIGZyb20gdGhlIGlucHV0IHByb3BzXG4gICAqL1xuICBwcml2YXRlIGRldGVybWluZVJvdXRpbmdDb25maWcocHJvcHM6IEFsaWFzUHJvcHMpIHtcbiAgICBpZiAoIXByb3BzLmFkZGl0aW9uYWxWZXJzaW9ucyB8fCBwcm9wcy5hZGRpdGlvbmFsVmVyc2lvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHRoaXMudmFsaWRhdGVBZGRpdGlvbmFsV2VpZ2h0cyhwcm9wcy5hZGRpdGlvbmFsVmVyc2lvbnMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFkZGl0aW9uYWxWZXJzaW9uV2VpZ2h0czogcHJvcHMuYWRkaXRpb25hbFZlcnNpb25zLm1hcCh2dyA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZnVuY3Rpb25WZXJzaW9uOiB2dy52ZXJzaW9uLnZlcnNpb24sXG4gICAgICAgICAgZnVuY3Rpb25XZWlnaHQ6IHZ3LndlaWdodCxcbiAgICAgICAgfTtcbiAgICAgIH0pLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhhdCB0aGUgYWRkaXRpb25hbCB2ZXJzaW9uIHdlaWdodHMgbWFrZSBzZW5zZVxuICAgKlxuICAgKiBXZSB2YWxpZGF0ZSB0aGF0IHRoZXkgYXJlIHBvc2l0aXZlIGFuZCBhZGQgdXAgdG8gc29tZXRoaW5nIDw9IDEuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlQWRkaXRpb25hbFdlaWdodHMod2VpZ2h0czogVmVyc2lvbldlaWdodFtdKSB7XG4gICAgY29uc3QgdG90YWwgPSB3ZWlnaHRzLm1hcCh3ID0+IHtcbiAgICAgIGlmICh3LndlaWdodCA8IDAgfHwgdy53ZWlnaHQgPiAxKSB7IHRocm93IG5ldyBFcnJvcihgQWRkaXRpb25hbCB2ZXJzaW9uIHdlaWdodCBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMSwgZ290OiAke3cud2VpZ2h0fWApOyB9XG4gICAgICByZXR1cm4gdy53ZWlnaHQ7XG4gICAgfSkucmVkdWNlKChhLCB4KSA9PiBhICsgeCk7XG5cbiAgICBpZiAodG90YWwgPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFN1bSBvZiBhZGRpdGlvbmFsIHZlcnNpb24gd2VpZ2h0cyBtdXN0IG5vdCBleGNlZWQgMSwgZ290OiAke3RvdGFsfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGF0IHRoZSBwcm92aXNpb25lZENvbmN1cnJlbnRFeGVjdXRpb25zIG1ha2VzIHNlbnNlXG4gICAqXG4gICAqIE1lbWJlciBtdXN0IGhhdmUgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDFcbiAgICovXG4gIHByaXZhdGUgZGV0ZXJtaW5lUHJvdmlzaW9uZWRDb25jdXJyZW5jeShwcm9wczogQWxpYXNQcm9wcyk6IENmbkFsaWFzLlByb3Zpc2lvbmVkQ29uY3VycmVuY3lDb25maWd1cmF0aW9uUHJvcGVydHkgfCB1bmRlZmluZWQge1xuICAgIGlmICghcHJvcHMucHJvdmlzaW9uZWRDb25jdXJyZW50RXhlY3V0aW9ucykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMucHJvdmlzaW9uZWRDb25jdXJyZW50RXhlY3V0aW9ucyA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb3Zpc2lvbmVkQ29uY3VycmVudEV4ZWN1dGlvbnMgbXVzdCBoYXZlIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcHJvdmlzaW9uZWRDb25jdXJyZW50RXhlY3V0aW9uczogcHJvcHMucHJvdmlzaW9uZWRDb25jdXJyZW50RXhlY3V0aW9ucyB9O1xuICB9XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBWZXJzaW9uV2VpZ2h0IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSB2ZXJzaW9uOiBJVmVyc2lvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgd2VpZ2h0OiBudW1iZXI7XG59XG4iXX0=