@aws-solutions-constructs/core
Version:
Core CDK Construct for patterns library
143 lines • 23.4 kB
JavaScript
"use strict";
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildWebSocketQueueApi = buildWebSocketQueueApi;
exports.buildWebSocketApiProps = buildWebSocketApiProps;
exports.buildWebSocketQueueRouteOptions = buildWebSocketQueueRouteOptions;
const cdk = require("aws-cdk-lib");
const apigateway = require("aws-cdk-lib/aws-apigateway");
const apigwv2 = require("aws-cdk-lib/aws-apigatewayv2");
const aws_apigatewayv2_integrations_1 = require("aws-cdk-lib/aws-apigatewayv2-integrations");
const iam = require("aws-cdk-lib/aws-iam");
const cloudwatch_log_group_helper_1 = require("./cloudwatch-log-group-helper");
const utils_1 = require("./utils");
const websocket_api_defaults_1 = require("./websocket-api-defaults");
/**
* Builds an AWS API Gateway WebSocket API integrated with an Amazon SQS queue.
*
* @param scope The construct scope where the resources will be created.
* @param id The unique ID for the resources.
* @param props The configuration properties for the WebSocket API and SQS queue integration.
* @returns
*/
function buildWebSocketQueueApi(scope, id, props) {
// Setup the API Gateway role
const apiGatewayRole = new iam.Role(scope, "LambdaRestApiCloudWatchRole", {
assumedBy: new iam.ServicePrincipal("apigateway.amazonaws.com"),
});
props.queue.grantSendMessages(apiGatewayRole);
const finalProps = (0, utils_1.consolidateProps)(buildWebSocketApiProps(apiGatewayRole, props.queue, props.createDefaultRoute, props.defaultRouteRequestTemplate, props.defaultIamAuthorization), props.webSocketApiProps);
const webSocketApi = buildApiGatewayV2WebSocket(scope, id, {
webSocketApiProps: finalProps,
existingWebSocketApi: props.existingWebSocketApi,
});
if (props.customRouteName) {
webSocketApi.addRoute(props.customRouteName, buildWebSocketQueueRouteOptions(apiGatewayRole, props.queue, props.customRouteName, props.defaultRouteRequestTemplate));
}
if (props.existingWebSocketApi === undefined &&
props.defaultIamAuthorization === false &&
finalProps.connectRouteOptions?.authorizer === undefined) {
(0, utils_1.printWarning)("This construct will create a WebSocket with NO Authorizer (defaultIamAuthorization is set to false).");
}
const webSocketStage = new apigwv2.WebSocketStage(scope, "Stage", {
stageName: "prod",
webSocketApi,
autoDeploy: true,
});
(0, utils_1.addCfnGuardSuppressRules)(webSocketStage, ["API_GW_CACHE_ENABLED_AND_ENCRYPTED"]);
const apiGatewayLogGroup = (0, cloudwatch_log_group_helper_1.buildLogGroup)(scope, "LogGroup", props.logGroupProps);
apiGatewayLogGroup.grant(apiGatewayRole, "logs:CreateLogGroup", "logs:CreateLogStream", "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:PutLogEvents", "logs:GetLogEvents", "logs:FilterLogEvents");
const cfnStage = webSocketStage.node.defaultChild;
cfnStage.addPropertyOverride("AccessLogSettings", {
DestinationArn: apiGatewayLogGroup.logGroupArn,
Format: apigateway.AccessLogFormat.clf().toString(),
});
cfnStage.addPropertyOverride("DefaultRouteSettings", {
DataTraceEnabled: false,
DetailedMetricsEnabled: true,
LoggingLevel: "ERROR",
});
(0, utils_1.addCfnSuppressRules)(webSocketStage, [
{
id: "AwsSolutions-APIG1",
reason: "Access logging configuration has been provided as per ApiGateway v2 requirements",
},
]);
(0, utils_1.addCfnSuppressRules)(apiGatewayRole.node.tryFindChild("DefaultPolicy")?.node.tryFindChild("Resource"), [
{
id: "AwsSolutions-IAM5",
reason: "The APIGateway requires permissions to KMS so that it can write to an encrypted SQS queue",
},
]);
return {
webSocketApi,
webSocketStage,
apiGatewayRole,
apiGatewayLogGroup,
};
}
/**
* build ApiGateway v2 WebSocket L2 construct. If existing WebSocketApi instance is provided, it returns that instance,
* if not, it creates a new WebSocketApi using the user provided props.
*
* @param scope
* @param props
* @returns
*/
function buildApiGatewayV2WebSocket(scope, id, props) {
if (props.existingWebSocketApi) {
return props.existingWebSocketApi;
}
else {
return new apigwv2.WebSocketApi(scope, `WebSocketApi${id}`, props.webSocketApiProps);
}
}
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function buildWebSocketApiProps(role, sqsQueue, createDefaultRoute, requestTemplate, defaultIamAuthorization) {
if (createDefaultRoute) {
if (!role || !sqsQueue) {
throw new Error("role and sqs must be provided to create a default route");
}
}
// prettier-ignore
// Sonar exception reason: - typescript:S6571 - required because we are not passing all values. Using partial may cause @jsii to not work.
const websocketApiProps = {
defaultRouteOptions: createDefaultRoute ? buildWebSocketQueueRouteOptions(role, sqsQueue, '$default', requestTemplate) : undefined,
connectRouteOptions: (defaultIamAuthorization === undefined || defaultIamAuthorization === true) ? websocket_api_defaults_1.connectRouteOptions : undefined
};
return websocketApiProps;
}
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function buildWebSocketQueueRouteOptions(role, sqsQueue, routeName, requestTemplate) {
return {
integration: new aws_apigatewayv2_integrations_1.WebSocketAwsIntegration(routeName, {
integrationMethod: apigwv2.HttpMethod.POST,
integrationUri: `arn:${cdk.Aws.PARTITION}:apigateway:${cdk.Aws.REGION}:sqs:path/${cdk.Aws.ACCOUNT_ID}/${sqsQueue.queueName}`,
requestTemplates: requestTemplate ?? {
[routeName === "$default" ? "$default" : routeName]: websocket_api_defaults_1.DEFAULT_ROUTE_QUEUE_VTL_CONFIG,
},
templateSelectionExpression: routeName === "$default" ? "\\$default" : routeName,
passthroughBehavior: apigwv2.PassthroughBehavior.NEVER,
credentialsRole: role,
requestParameters: {
"integration.request.header.Content-Type": "'application/x-www-form-urlencoded'",
},
}),
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LWFwaS1oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3ZWJzb2NrZXQtYXBpLWhlbHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7O0dBV0c7O0FBbURILHdEQWdHQztBQXFCRCx3REFvQkM7QUFLRCwwRUFxQkM7QUFwTkQsbUNBQW1DO0FBQ25DLHlEQUF5RDtBQUN6RCx3REFBd0Q7QUFDeEQsNkZBQW9GO0FBQ3BGLDJDQUEyQztBQUkzQywrRUFBOEQ7QUFDOUQsbUNBQXdHO0FBQ3hHLHFFQUErRjtBQStCL0Y7Ozs7Ozs7R0FPRztBQUNILFNBQWdCLHNCQUFzQixDQUNwQyxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBb0M7SUFFcEMsNkJBQTZCO0lBQzdCLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsNkJBQTZCLEVBQUU7UUFDeEUsU0FBUyxFQUFFLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLDBCQUEwQixDQUFDO0tBQ2hFLENBQUMsQ0FBQztJQUNILEtBQUssQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDOUMsTUFBTSxVQUFVLEdBQUcsSUFBQSx3QkFBZ0IsRUFDakMsc0JBQXNCLENBQ3BCLGNBQWMsRUFDZCxLQUFLLENBQUMsS0FBSyxFQUNYLEtBQUssQ0FBQyxrQkFBa0IsRUFDeEIsS0FBSyxDQUFDLDJCQUEyQixFQUNqQyxLQUFLLENBQUMsdUJBQXVCLENBQzlCLEVBQ0QsS0FBSyxDQUFDLGlCQUFpQixDQUNLLENBQUM7SUFDL0IsTUFBTSxZQUFZLEdBQUcsMEJBQTBCLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtRQUN6RCxpQkFBaUIsRUFBRSxVQUFVO1FBQzdCLG9CQUFvQixFQUFFLEtBQUssQ0FBQyxvQkFBb0I7S0FDakQsQ0FBQyxDQUFDO0lBRUgsSUFBSSxLQUFLLENBQUMsZUFBZSxFQUFF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QVksQ0FBQyxDQUFDLENBQUMsU0FBUztZQUNoRixtQkFBbUIsRUFBRSxPQUFPLENBQUMsbUJBQW1CLENBQUMsS0FBSztZQUN0RCxlQUFlLEVBQUUsSUFBSTtZQUNyQixpQkFBaUIsRUFBRTtnQkFDakIseUNBQXlDLEVBQUUscUNBQXFDO2FBQ2pGO1NBQ0YsQ0FBQztLQUNILENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIikuIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqICB3aXRoIHRoZSBMaWNlbnNlLiBBIGNvcHkgb2YgdGhlIExpY2Vuc2UgaXMgbG9jYXRlZCBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIG9yIGluIHRoZSAnbGljZW5zZScgZmlsZSBhY2NvbXBhbnlpbmcgdGhpcyBmaWxlLiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgb24gYW4gJ0FTIElTJyBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTXG4gKiAgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcbiAqICBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0ICogYXMgY2RrIGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgYXBpZ2F0ZXdheSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWFwaWdhdGV3YXlcIjtcbmltcG9ydCAqIGFzIGFwaWd3djIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5djJcIjtcbmltcG9ydCB7IFdlYlNvY2tldEF3c0ludGVncmF0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5djItaW50ZWdyYXRpb25zXCI7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSBcImF3cy1jZGstbGliL2F3cy1sb2dzXCI7XG5pbXBvcnQgKiBhcyBzcXMgZnJvbSBcImF3cy1jZGstbGliL2F3cy1zcXNcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBidWlsZExvZ0dyb3VwIH0gZnJvbSBcIi4vY2xvdWR3YXRjaC1sb2ctZ3JvdXAtaGVscGVyXCI7XG5pbXBvcnQgeyBhZGRDZm5HdWFyZFN1cHByZXNzUnVsZXMsIGFkZENmblN1cHByZXNzUnVsZXMsIGNvbnNvbGlkYXRlUHJvcHMsIHByaW50V2FybmluZyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBjb25uZWN0Um91dGVPcHRpb25zLCBERUZBVUxUX1JPVVRFX1FVRVVFX1ZUTF9DT05GSUcgfSBmcm9tIFwiLi93ZWJzb2NrZXQtYXBpLWRlZmF1bHRzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRXZWJTb2NrZXRRdWV1ZUFwaVJlc3BvbnNlIHtcbiAgcmVhZG9ubHkgd2ViU29ja2V0QXBpOiBhcGlnd3YyLldlYlNvY2tldEFwaTtcbiAgcmVhZG9ubHkgd2ViU29ja2V0U3RhZ2U6IGFwaWd3djIuV2ViU29ja2V0U3RhZ2U7XG4gIHJlYWRvbmx5IGFwaUdhdGV3YXlSb2xlOiBpYW0uUm9sZTtcbiAgcmVhZG9ubHkgYXBpR2F0ZXdheUxvZ0dyb3VwOiBsb2dzLkxvZ0dyb3VwO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkV2ViU29ja2V0QXBpUHJvcHMge1xuICAvKipcbiAgICogRXhpc3RpbmcgaW5zdGFuY2Ugb2YgQXBpR2F0ZXdheSB2MiBXZWJTb2NrZXRcbiAgICovXG4gIHJlYWRvbmx5IGV4aXN0aW5nV2ViU29ja2V0QXBpPzogYXBpZ3d2Mi5XZWJTb2NrZXRBcGk7XG5cbiAgLyoqXG4gICAqIFVzZXIgcHJvdmlkZWQgcHJvcGVydGllcyBvZiBBcGlnYXRld2F5IHYyIFdlYlNvY2tldFxuICAgKi9cbiAgcmVhZG9ubHkgd2ViU29ja2V0QXBpUHJvcHM/OiBhcGlnd3YyLldlYlNvY2tldEFwaVByb3BzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkV2ViU29ja2V0UXVldWVBcGlSZXF1ZXN0IHtcbiAgcmVhZG9ubHkgcXVldWU6IHNxcy5JUXVldWU7XG4gIHJlYWRvbmx5IGRlZmF1bHRSb3V0ZVJlcXVlc3RUZW1wbGF0ZT86IHsgW2NvbnRlbnRUeXBlOiBzdHJpbmddOiBzdHJpbmcgfTtcbiAgcmVhZG9ubHkgY3JlYXRlRGVmYXVsdFJvdXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgd2ViU29ja2V0QXBpUHJvcHM/OiBhcGlnd3YyLldlYlNvY2tldEFwaVByb3BzO1xuICByZWFkb25seSBleGlzdGluZ1dlYlNvY2tldEFwaT86IGFwaWd3djIuV2ViU29ja2V0QXBpO1xuICByZWFkb25seSBsb2dHcm91cFByb3BzPzogbG9ncy5Mb2dHcm91cFByb3BzO1xuICByZWFkb25seSBkZWZhdWx0SWFtQXV0aG9yaXphdGlvbj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGN1c3RvbVJvdXRlTmFtZT86IHN0cmluZztcbn1cbi8qKlxuICogQnVpbGRzIGFuIEFXUyBBUEkgR2F0ZXdheSBXZWJTb2NrZXQgQVBJIGludGVncmF0ZWQgd2l0aCBhbiBBbWF6b24gU1FTIHF1ZXVlLlxuICpcbiAqIEBwYXJhbSBzY29wZSBUaGUgY29uc3RydWN0IHNjb3BlIHdoZXJlIHRoZSByZXNvdXJjZXMgd2lsbCBiZSBjcmVhdGVkLlxuICogQHBhcmFtIGlkIFRoZSB1bmlxdWUgSUQgZm9yIHRoZSByZXNvdXJjZXMuXG4gKiBAcGFyYW0gcHJvcHMgVGhlIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcyBmb3IgdGhlIFdlYlNvY2tldCBBUEkgYW5kIFNRUyBxdWV1ZSBpbnRlZ3JhdGlvbi5cbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFdlYlNvY2tldFF1ZXVlQXBpKFxuICBzY29wZTogQ29uc3RydWN0LFxuICBpZDogc3RyaW5nLFxuICBwcm9wczogQnVpbGRXZWJTb2NrZXRRdWV1ZUFwaVJlcXVlc3Rcbik6IEJ1aWxkV2ViU29ja2V0UXVldWVBcGlSZXNwb25zZSB7XG4gIC8vIFNldHVwIHRoZSBBUEkgR2F0ZXdheSByb2xlXG4gIGNvbnN0IGFwaUdhdGV3YXlSb2xlID0gbmV3IGlhbS5Sb2xlKHNjb3BlLCBcIkxhbWJkYVJlc3RBcGlDbG91ZFdhdGNoUm9sZVwiLCB7XG4gICAgYXNzdW1lZEJ5OiBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoXCJhcGlnYXRld2F5LmFtYXpvbmF3cy5jb21cIiksXG4gIH0pO1xuICBwcm9wcy5xdWV1ZS5ncmFudFNlbmRNZXNzYWdlcyhhcGlHYXRld2F5Um9sZSk7XG4gIGNvbnN0IGZpbmFsUHJvcHMgPSBjb25zb2xpZGF0ZVByb3BzKFxuICAgIGJ1aWxkV2ViU29ja2V0QXBpUHJvcHMoXG4gICAgICBhcGlHYXRld2F5Um9sZSxcbiAgICAgIHByb3BzLnF1ZXVlLFxuICAgICAgcHJvcHMuY3JlYXRlRGVmYXVsdFJvdXRlLFxuICAgICAgcHJvcHMuZGVmYXVsdFJvdXRlUmVxdWVzdFRlbXBsYXRlLFxuICAgICAgcHJvcHMuZGVmYXVsdElhbUF1dGhvcml6YXRpb25cbiAgICApLFxuICAgIHByb3BzLndlYlNvY2tldEFwaVByb3BzXG4gICkgYXMgYXBpZ3d2Mi5XZWJTb2NrZXRBcGlQcm9wcztcbiAgY29uc3Qgd2ViU29ja2V0QXBpID0gYnVpbGRBcGlHYXRld2F5VjJXZWJTb2NrZXQoc2NvcGUsIGlkLCB7XG4gICAgd2ViU29ja2V0QXBpUHJvcHM6IGZpbmFsUHJvcHMsXG4gICAgZXhpc3RpbmdXZWJTb2NrZXRBcGk6IHByb3BzLmV4aXN0aW5nV2ViU29ja2V0QXBpLFxuICB9KTtcblxuICBpZiAocHJvcHMuY3VzdG9tUm91dGVOYW1lKSB7XG4gICAgd2ViU29ja2V0QXBpLmFkZFJvdXRlKFxuICAgICAgcHJvcHMuY3VzdG9tUm91dGVOYW1lLFxuICAgICAgYnVpbGRXZWJTb2NrZXRRdWV1ZVJvdXRlT3B0aW9ucyhhcGlHYXRld2F5Um9sZSwgcHJvcHMucXVldWUsIHByb3BzLmN1c3RvbVJvdXRlTmFtZSwgcHJvcHMuZGVmYXVsdFJvdXRlUmVxdWVzdFRlbXBsYXRlKVxuICAgICk7XG4gIH1cblxuICBpZiAoXG4gICAgcHJvcHMuZXhpc3RpbmdXZWJTb2NrZXRBcGkgPT09IHVuZGVmaW5lZCAmJlxuICAgIHByb3BzLmRlZmF1bHRJYW1BdXRob3JpemF0aW9uID09PSBmYWxzZSAmJlxuICAgIGZpbmFsUHJvcHMuY29ubmVjdFJvdXRlT3B0aW9ucz8uYXV0aG9yaXplciA9PT0gdW5kZWZpbmVkXG4gICkge1xuICAgIHByaW50V2FybmluZyhcbiAgICAgIFwiVGhpcyBjb25zdHJ1Y3Qgd2lsbCBjcmVhdGUgYSBXZWJTb2NrZXQgd2l0aCBOTyBBdXRob3JpemVyIChkZWZhdWx0SWFtQXV0aG9yaXphdGlvbiBpcyBzZXQgdG8gZmFsc2UpLlwiXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHdlYlNvY2tldFN0YWdlID0gbmV3IGFwaWd3djIuV2ViU29ja2V0U3RhZ2Uoc2NvcGUsIFwiU3RhZ2VcIiwge1xuICAgIHN0YWdlTmFtZTogXCJwcm9kXCIsXG4gICAgd2ViU29ja2V0QXBpLFxuICAgIGF1dG9EZXBsb3k6IHRydWUsXG4gIH0pO1xuXG4gIGFkZENmbkd1YXJkU3VwcHJlc3NSdWxlcyh3ZWJTb2NrZXRTdGFnZSwgW1wiQVBJX0dXX0NBQ0hFX0VOQUJMRURfQU5EX0VOQ1JZUFRFRFwiXSk7XG5cbiAgY29uc3QgYXBpR2F0ZXdheUxvZ0dyb3VwID0gYnVpbGRMb2dHcm91cChzY29wZSwgXCJMb2dHcm91cFwiLCBwcm9wcy5sb2dHcm91cFByb3BzKTtcbiAgYXBpR2F0ZXdheUxvZ0dyb3VwLmdyYW50KFxuICAgIGFwaUdhdGV3YXlSb2xlLFxuICAgIFwibG9nczpDcmVhdGVMb2dHcm91cFwiLFxuICAgIFwibG9nczpDcmVhdGVMb2dTdHJlYW1cIixcbiAgICBcImxvZ3M6RGVzY3JpYmVMb2dHcm91cHNcIixcbiAgICBcImxvZ3M6RGVzY3JpYmVMb2dTdHJlYW1zXCIsXG4gICAgXCJsb2dzOlB1dExvZ0V2ZW50c1wiLFxuICAgIFwibG9nczpHZXRMb2dFdmVudHNcIixcbiAgICBcImxvZ3M6RmlsdGVyTG9nRXZlbnRzXCJcbiAgKTtcblxuICBjb25zdCBjZm5TdGFnZTogYXBpZ3d2Mi5DZm5TdGFnZSA9IHdlYlNvY2tldFN0YWdlLm5vZGUuZGVmYXVsdENoaWxkIGFzIGFwaWd3djIuQ2ZuU3RhZ2U7XG4gIGNmblN0YWdlLmFkZFByb3BlcnR5T3ZlcnJpZGUoXCJBY2Nlc3NMb2dTZXR0aW5nc1wiLCB7XG4gICAgRGVzdGluYXRpb25Bcm46IGFwaUdhdGV3YXlMb2dHcm91cC5sb2dHcm91cEFybixcbiAgICBGb3JtYXQ6IGFwaWdhdGV3YXkuQWNjZXNzTG9nRm9ybWF0LmNsZigpLnRvU3RyaW5nKCksXG4gIH0pO1xuICBjZm5TdGFnZS5hZGRQcm9wZXJ0eU92ZXJyaWRlKFwiRGVmYXVsdFJvdXRlU2V0dGluZ3NcIiwge1xuICAgIERhdGFUcmFjZUVuYWJsZWQ6IGZhbHNlLFxuICAgIERldGFpbGVkTWV0cmljc0VuYWJsZWQ6IHRydWUsXG4gICAgTG9nZ2luZ0xldmVsOiBcIkVSUk9SXCIsXG4gIH0pO1xuXG4gIGFkZENmblN1cHByZXNzUnVsZXMod2ViU29ja2V0U3RhZ2UsIFtcbiAgICB7XG4gICAgICBpZDogXCJBd3NTb2x1dGlvbnMtQVBJRzFcIixcbiAgICAgIHJlYXNvbjogXCJBY2Nlc3MgbG9nZ2luZyBjb25maWd1cmF0aW9uIGhhcyBiZWVuIHByb3ZpZGVkIGFzIHBlciBBcGlHYXRld2F5IHYyIHJlcXVpcmVtZW50c1wiLFxuICAgIH0sXG4gIF0pO1xuXG4gIGFkZENmblN1cHByZXNzUnVsZXMoXG4gICAgYXBpR2F0ZXdheVJvbGUubm9kZS50cnlGaW5kQ2hpbGQoXCJEZWZhdWx0UG9saWN5XCIpPy5ub2RlLnRyeUZpbmRDaGlsZChcIlJlc291cmNlXCIpIGFzIGNkay5DZm5SZXNvdXJjZSxcbiAgICBbXG4gICAgICB7XG4gICAgICAgIGlkOiBcIkF3c1NvbHV0aW9ucy1JQU01XCIsXG4gICAgICAgIHJlYXNvbjogXCJUaGUgQVBJR2F0ZXdheSByZXF1aXJlcyBwZXJtaXNzaW9ucyB0byBLTVMgc28gdGhhdCBpdCBjYW4gd3JpdGUgdG8gYW4gZW5jcnlwdGVkIFNRUyBxdWV1ZVwiLFxuICAgICAgfSxcbiAgICBdXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICB3ZWJTb2NrZXRBcGksXG4gICAgd2ViU29ja2V0U3RhZ2UsXG4gICAgYXBpR2F0ZXdheVJvbGUsXG4gICAgYXBpR2F0ZXdheUxvZ0dyb3VwLFxuICB9O1xufVxuXG4vKipcbiAqIGJ1aWxkIEFwaUdhdGV3YXkgdjIgV2ViU29ja2V0IEwyIGNvbnN0cnVjdC4gSWYgZXhpc3RpbmcgV2ViU29ja2V0QXBpIGluc3RhbmNlIGlzIHByb3ZpZGVkLCBpdCByZXR1cm5zIHRoYXQgaW5zdGFuY2UsXG4gKiBpZiBub3QsIGl0IGNyZWF0ZXMgYSBuZXcgV2ViU29ja2V0QXBpIHVzaW5nIHRoZSB1c2VyIHByb3ZpZGVkIHByb3BzLlxuICpcbiAqIEBwYXJhbSBzY29wZVxuICogQHBhcmFtIHByb3BzXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBidWlsZEFwaUdhdGV3YXlWMldlYlNvY2tldChzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQnVpbGRXZWJTb2NrZXRBcGlQcm9wcyk6IGFwaWd3djIuV2ViU29ja2V0QXBpIHtcbiAgaWYgKHByb3BzLmV4aXN0aW5nV2ViU29ja2V0QXBpKSB7XG4gICAgcmV0dXJuIHByb3BzLmV4aXN0aW5nV2ViU29ja2V0QXBpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgYXBpZ3d2Mi5XZWJTb2NrZXRBcGkoc2NvcGUsIGBXZWJTb2NrZXRBcGkke2lkfWAsIHByb3BzLndlYlNvY2tldEFwaVByb3BzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBUaGlzIGlzIGFuIGludGVybmFsIGNvcmUgZnVuY3Rpb24gYW5kIHNob3VsZCBub3QgYmUgY2FsbGVkIGRpcmVjdGx5IGJ5IFNvbHV0aW9ucyBDb25zdHJ1Y3RzIGNsaWVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFdlYlNvY2tldEFwaVByb3BzKFxuICByb2xlPzogaWFtLlJvbGUsXG4gIHNxc1F1ZXVlPzogc3FzLklRdWV1ZSxcbiAgY3JlYXRlRGVmYXVsdFJvdXRlPzogYm9vbGVhbixcbiAgcmVxdWVzdFRlbXBsYXRlPzogeyBbY29udGVudFR5cGU6IHN0cmluZ106IHN0cmluZyB9LFxuICBkZWZhdWx0SWFtQXV0aG9yaXphdGlvbj86IGJvb2xlYW5cbik6IGFwaWd3djIuV2ViU29ja2V0QXBpUHJvcHMge1xuICBpZiAoY3JlYXRlRGVmYXVsdFJvdXRlKSB7XG4gICAgaWYgKCFyb2xlIHx8ICFzcXNRdWV1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwicm9sZSBhbmQgc3FzIG11c3QgYmUgcHJvdmlkZWQgdG8gY3JlYXRlIGEgZGVmYXVsdCByb3V0ZVwiKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcmV0dGllci1pZ25vcmVcbiAgLy8gU29uYXIgZXhjZXB0aW9uIHJlYXNvbjogLSB0eXBlc2NyaXB0OlM2NTcxIC0gcmVxdWlyZWQgYmVjYXVzZSB3ZSBhcmUgbm90IHBhc3NpbmcgYWxsIHZhbHVlcy4gVXNpbmcgcGFydGlhbCBtYXkgY2F1c2UgQGpzaWkgdG8gbm90IHdvcmsuXG4gIGNvbnN0IHdlYnNvY2tldEFwaVByb3BzOiBhcGlnd3YyLldlYlNvY2tldEFwaVByb3BzID0geyAvLyBOT1NPTkFSXG4gICAgZGVmYXVsdFJvdXRlT3B0aW9uczogY3JlYXRlRGVmYXVsdFJvdXRlID8gYnVpbGRXZWJTb2NrZXRRdWV1ZVJvdXRlT3B0aW9ucyhyb2xlISwgc3FzUXVldWUhLCAnJGRlZmF1bHQnLCByZXF1ZXN0VGVtcGxhdGUpIDogdW5kZWZpbmVkLFxuICAgIGNvbm5lY3RSb3V0ZU9wdGlvbnM6IChkZWZhdWx0SWFtQXV0aG9yaXphdGlvbiA9PT0gdW5kZWZpbmVkIHx8IGRlZmF1bHRJYW1BdXRob3JpemF0aW9uID09PSB0cnVlKSA/IGNvbm5lY3RSb3V0ZU9wdGlvbnMgOiB1bmRlZmluZWRcbiAgfTtcbiAgcmV0dXJuIHdlYnNvY2tldEFwaVByb3BzO1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBUaGlzIGlzIGFuIGludGVybmFsIGNvcmUgZnVuY3Rpb24gYW5kIHNob3VsZCBub3QgYmUgY2FsbGVkIGRpcmVjdGx5IGJ5IFNvbHV0aW9ucyBDb25zdHJ1Y3RzIGNsaWVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFdlYlNvY2tldFF1ZXVlUm91dGVPcHRpb25zKFxuICByb2xlOiBpYW0uUm9sZSxcbiAgc3FzUXVldWU6IHNxcy5JUXVldWUsXG4gIHJvdXRlTmFtZTogc3RyaW5nLFxuICByZXF1ZXN0VGVtcGxhdGU/OiB7IFtjb250ZW50VHlwZTogc3RyaW5nXTogc3RyaW5nIH1cbik6IGFwaWd3djIuV2ViU29ja2V0Um91dGVPcHRpb25zIHtcbiAgcmV0dXJuIHtcbiAgICBpbnRlZ3JhdGlvbjogbmV3IFdlYlNvY2tldEF3c0ludGVncmF0aW9uKHJvdXRlTmFtZSwge1xuICAgICAgaW50ZWdyYXRpb25NZXRob2Q6IGFwaWd3djIuSHR0cE1ldGhvZC5QT1NULFxuICAgICAgaW50ZWdyYXRpb25Vcmk6IGBhcm46JHtjZGsuQXdzLlBBUlRJVElPTn06YXBpZ2F0ZXdheToke2Nkay5Bd3MuUkVHSU9OfTpzcXM6cGF0aC8ke2Nkay5Bd3MuQUNDT1VOVF9JRH0vJHtzcXNRdWV1ZS5xdWV1ZU5hbWV9YCxcbiAgICAgIHJlcXVlc3RUZW1wbGF0ZXM6IHJlcXVlc3RUZW1wbGF0ZSA/PyB7XG4gICAgICAgIFtyb3V0ZU5hbWUgPT09IFwiJGRlZmF1bHRcIiA/IFwiJGRlZmF1bHRcIiA6IHJvdXRlTmFtZV06IERFRkFVTFRfUk9VVEVfUVVFVUVfVlRMX0NPTkZJRyxcbiAgICAgIH0sXG4gICAgICB0ZW1wbGF0ZVNlbGVjdGlvbkV4cHJlc3Npb246IHJvdXRlTmFtZSA9PT0gXCIkZGVmYXVsdFwiID8gXCJcXFxcJGRlZmF1bHRcIiA6IHJvdXRlTmFtZSxcbiAgICAgIHBhc3N0aHJvdWdoQmVoYXZpb3I6IGFwaWd3djIuUGFzc3Rocm91Z2hCZWhhdmlvci5ORVZFUixcbiAgICAgIGNyZWRlbnRpYWxzUm9sZTogcm9sZSxcbiAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzOiB7XG4gICAgICAgIFwiaW50ZWdyYXRpb24ucmVxdWVzdC5oZWFkZXIuQ29udGVudC1UeXBlXCI6IFwiJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcIixcbiAgICAgIH0sXG4gICAgfSksXG4gIH07XG59XG4iXX0=