UNPKG

cdk-monitoring-constructs

Version:

[![NPM version](https://badge.fury.io/js/cdk-monitoring-constructs.svg)](https://badge.fury.io/js/cdk-monitoring-constructs) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.cdklabs/cdkmonitoringconstructs/badge.svg)](https://m

169 lines 29.7 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpenSearchServerlessMonitoring = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch"); const OpenSearchServerlessMetricFactory_1 = require("./OpenSearchServerlessMetricFactory"); const common_1 = require("../../common"); const dashboard_1 = require("../../dashboard"); /** * @experimental This is subject to change if an L2 construct becomes available. */ class OpenSearchServerlessMonitoring extends common_1.Monitoring { constructor(scope, props) { super(scope, props); const namingStrategy = new dashboard_1.MonitoringNamingStrategy({ ...props, fallbackConstructName: props.collection.name, }); this.title = namingStrategy.resolveHumanReadableName(); this.collectionUrl = scope .createAwsConsoleUrlFactory() .getOpenSearchServerlessCollectionUrl(props.collection.name); this.alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName()); this.latencyAlarmFactory = new common_1.LatencyAlarmFactory(this.alarmFactory); this.errorAlarmFactory = new common_1.ErrorAlarmFactory(this.alarmFactory); this.searchLatencyAnnotations = []; this.errorCountAnnotations = []; this.errorRateAnnotations = []; const metricFactory = new OpenSearchServerlessMetricFactory_1.OpenSearchServerlessMetricFactory(scope.createMetricFactory(), props); this.metricSearchRequestErrorsCount = metricFactory.metricSearchRequestErrors(); this.metricSearchRequestLatencyAvg = metricFactory.metricSearchRequestLatency(common_1.LatencyType.AVERAGE); this.metricSearchRequestLatencyMax = metricFactory.metricSearchRequestLatency(common_1.LatencyType.MAX); this.metricIngestionRequestSuccessCount = metricFactory.metricIngestionRequestSuccess(); this.metricIngestionRequestErrorsCount = metricFactory.metricIngestionRequestErrors(); this.metricIngestionRequestLatencyAvg = metricFactory.metricIngestionRequestLatency(common_1.LatencyType.AVERAGE); this.metricIngestionRequestLatencyMax = metricFactory.metricIngestionRequestLatency(common_1.LatencyType.MAX); this.metric4xxErrorCount = metricFactory.metric4xxCount(); this.metric4xxErrorRate = metricFactory.metric4xxRate(); this.metric5xxErrorCount = metricFactory.metric5xxCount(); this.metric5xxErrorRate = metricFactory.metric5xxRate(); for (const disambiguator in props.addSearchLatencyP100Alarm) { const alarmProps = props.addSearchLatencyP100Alarm[disambiguator]; const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.metricSearchRequestLatencyMax, common_1.LatencyType.P100, alarmProps, disambiguator); this.searchLatencyAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addSearchErrorCountAlarm) { const alarmProps = props.addSearchErrorCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.metricSearchRequestErrorsCount, common_1.ErrorType.ERROR, alarmProps, disambiguator); this.errorCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.add4xxCountAlarm) { const alarmProps = props.add4xxCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.metric4xxErrorCount, common_1.ErrorType.USER_ERROR, alarmProps, disambiguator); this.errorCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.add4xxRateAlarm) { const alarmProps = props.add4xxRateAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.metric4xxErrorRate, common_1.ErrorType.USER_ERROR, alarmProps, disambiguator); this.errorRateAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.add5xxCountAlarm) { const alarmProps = props.add5xxCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.metric5xxErrorCount, common_1.ErrorType.FAULT, alarmProps, disambiguator); this.errorCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.add5xxRateAlarm) { const alarmProps = props.add5xxRateAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.metric5xxErrorRate, common_1.ErrorType.FAULT, alarmProps, disambiguator); this.errorRateAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } props.useCreatedAlarms?.consume(this.createdAlarms()); } summaryWidgets() { return this.widgets(); } widgets() { return [ this.createTitleWidget(), new aws_cloudwatch_1.Row(this.createSearchRequestLatencyWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createErrorCountWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createErrorRateWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight)), new aws_cloudwatch_1.Row(this.createIngestionRequestsWidget(common_1.HalfWidth, common_1.DefaultGraphWidgetHeight), this.createIngestionLatencyWidget(common_1.HalfWidth, common_1.DefaultGraphWidgetHeight)), ]; } createTitleWidget() { return new dashboard_1.MonitoringHeaderWidget({ family: "OpenSearch Serverless Collection", title: this.title, goToLinkUrl: this.collectionUrl, }); } createSearchRequestLatencyWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Search request latency", left: [ this.metricSearchRequestLatencyAvg, this.metricSearchRequestLatencyMax, ], leftYAxis: common_1.TimeAxisMillisFromZero, leftAnnotations: this.searchLatencyAnnotations, }); } createErrorCountWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Errors", left: [ this.metric4xxErrorCount, this.metric5xxErrorCount, this.metricSearchRequestErrorsCount, ], leftYAxis: common_1.CountAxisFromZero, leftAnnotations: this.errorCountAnnotations, }); } createErrorRateWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Errors (rate)", left: [this.metric4xxErrorRate, this.metric5xxErrorRate], leftYAxis: common_1.RateAxisFromZero, leftAnnotations: this.errorRateAnnotations, }); } createIngestionRequestsWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Ingestion requests", left: [ this.metricIngestionRequestSuccessCount, this.metricIngestionRequestErrorsCount, ], leftYAxis: common_1.CountAxisFromZero, }); } createIngestionLatencyWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Ingestion latency", left: [ this.metricIngestionRequestLatencyAvg, this.metricIngestionRequestLatencyMax, ], leftYAxis: common_1.TimeAxisMillisFromZero, }); } } exports.OpenSearchServerlessMonitoring = OpenSearchServerlessMonitoring; _a = JSII_RTTI_SYMBOL_1; OpenSearchServerlessMonitoring[_a] = { fqn: "cdk-monitoring-constructs.OpenSearchServerlessMonitoring", version: "10.0.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3BlblNlYXJjaFNlcnZlcmxlc3NNb25pdG9yaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiT3BlblNlYXJjaFNlcnZlcmxlc3NNb25pdG9yaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0EsK0RBQThEO0FBRzlELDJGQUF3RjtBQUN4Rix5Q0FtQnNCO0FBQ3RCLCtDQUd5QjtBQWlCekI7O0dBRUc7QUFDSCxNQUFhLDhCQUErQixTQUFRLG1CQUFVO0lBMkI1RCxZQUNFLEtBQXNCLEVBQ3RCLEtBQTBDO1FBRTFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFcEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxvQ0FBd0IsQ0FBQztZQUNsRCxHQUFHLEtBQUs7WUFDUixxQkFBcUIsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUk7U0FDN0MsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUs7YUFDdkIsMEJBQTBCLEVBQUU7YUFDNUIsb0NBQW9DLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUvRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FDekMsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQzFDLENBQUM7UUFFRixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSw0QkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksMEJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWxFLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxFQUFFLENBQUM7UUFDbkMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsb0JBQW9CLEdB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QztJQUNMLENBQUM7SUFFUyw0QkFBNEIsQ0FDcEMsS0FBYSxFQUNiLE1BQWM7UUFFZCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxtQkFBbUI7WUFDMUIsSUFBSSxFQUFFO2dCQUNKLElBQUksQ0FBQyxnQ0FBZ0M7Z0JBQ3JDLElBQUksQ0FBQyxnQ0FBZ0M7YUFDdEM7WUFDRCxTQUFTLEVBQUUsK0JBQXNCO1NBQ2xDLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBbFFILHdFQW1RQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgSG9yaXpvbnRhbEFubm90YXRpb24sIElXaWRnZXQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcbmltcG9ydCB7IEdyYXBoV2lkZ2V0LCBSb3cgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcblxuaW1wb3J0IHR5cGUgeyBPcGVuU2VhcmNoU2VydmVybGVzc01ldHJpY0ZhY3RvcnlQcm9wcyB9IGZyb20gXCIuL09wZW5TZWFyY2hTZXJ2ZXJsZXNzTWV0cmljRmFjdG9yeVwiO1xuaW1wb3J0IHsgT3BlblNlYXJjaFNlcnZlcmxlc3NNZXRyaWNGYWN0b3J5IH0gZnJvbSBcIi4vT3BlblNlYXJjaFNlcnZlcmxlc3NNZXRyaWNGYWN0b3J5XCI7XG5pbXBvcnQge1xuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBNb25pdG9yaW5nLFxuICBMYXRlbmN5VGhyZXNob2xkLFxuICBFcnJvckNvdW50VGhyZXNob2xkLFxuICBFcnJvclJhdGVUaHJlc2hvbGQsXG4gIEFsYXJtRmFjdG9yeSxcbiAgTGF0ZW5jeUFsYXJtRmFjdG9yeSxcbiAgRXJyb3JBbGFybUZhY3RvcnksXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1vbml0b3JpbmdTY29wZSxcbiAgTGF0ZW5jeVR5cGUsXG4gIEVycm9yVHlwZSxcbiAgVGhpcmRXaWR0aCxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBIYWxmV2lkdGgsXG4gIFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBSYXRlQXhpc0Zyb21aZXJvLFxufSBmcm9tIFwiLi4vLi4vY29tbW9uXCI7XG5pbXBvcnQge1xuICBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3ksXG4gIE1vbml0b3JpbmdIZWFkZXJXaWRnZXQsXG59IGZyb20gXCIuLi8uLi9kYXNoYm9hcmRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBPcGVuU2VhcmNoU2VydmVybGVzc01vbml0b3JpbmdPcHRpb25zXG4gIGV4dGVuZHMgQmFzZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGFkZFNlYXJjaExhdGVuY3lQMTAwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkU2VhcmNoRXJyb3JDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JDb3VudFRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkNHh4Q291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yQ291bnRUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGQ0eHhSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGQ1eHhDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZDV4eFJhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yUmF0ZVRocmVzaG9sZD47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlblNlYXJjaFNlcnZlcmxlc3NNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBPcGVuU2VhcmNoU2VydmVybGVzc01ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBPcGVuU2VhcmNoU2VydmVybGVzc01vbml0b3JpbmdPcHRpb25zIHt9XG5cbi8qKlxuICogQGV4cGVyaW1lbnRhbCBUaGlzIGlzIHN1YmplY3QgdG8gY2hhbmdlIGlmIGFuIEwyIGNvbnN0cnVjdCBiZWNvbWVzIGF2YWlsYWJsZS5cbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5TZWFyY2hTZXJ2ZXJsZXNzTW9uaXRvcmluZyBleHRlbmRzIE1vbml0b3Jpbmcge1xuICByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuICByZWFkb25seSBjb2xsZWN0aW9uVXJsPzogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IGFsYXJtRmFjdG9yeTogQWxhcm1GYWN0b3J5O1xuICByZWFkb25seSBsYXRlbmN5QWxhcm1GYWN0b3J5OiBMYXRlbmN5QWxhcm1GYWN0b3J5O1xuICByZWFkb25seSBlcnJvckFsYXJtRmFjdG9yeTogRXJyb3JBbGFybUZhY3Rvcnk7XG5cbiAgcmVhZG9ubHkgc2VhcmNoTGF0ZW5jeUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBlcnJvckNvdW50QW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGVycm9yUmF0ZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuXG4gIHJlYWRvbmx5IG1ldHJpY1NlYXJjaFJlcXVlc3RFcnJvcnNDb3VudDogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljU2VhcmNoUmVxdWVzdExhdGVuY3lBdmc6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1ldHJpY1NlYXJjaFJlcXVlc3RMYXRlbmN5TWF4OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuXG4gIHJlYWRvbmx5IG1ldHJpY0luZ2VzdGlvblJlcXVlc3RTdWNjZXNzQ291bnQ6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1ldHJpY0luZ2VzdGlvblJlcXVlc3RFcnJvcnNDb3VudDogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljSW5nZXN0aW9uUmVxdWVzdExhdGVuY3lBdmc6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1ldHJpY0luZ2VzdGlvblJlcXVlc3RMYXRlbmN5TWF4OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuXG4gIHJlYWRvbmx5IG1ldHJpYzR4eEVycm9yQ291bnQ6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1ldHJpYzR4eEVycm9yUmF0ZTogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICByZWFkb25seSBtZXRyaWM1eHhFcnJvckNvdW50OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWM1eHhFcnJvclJhdGU6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IE1vbml0b3JpbmdTY29wZSxcbiAgICBwcm9wczogT3BlblNlYXJjaFNlcnZlcmxlc3NNb25pdG9yaW5nUHJvcHMsXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBwcm9wcyk7XG5cbiAgICBjb25zdCBuYW1pbmdTdHJhdGVneSA9IG5ldyBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3koe1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYWxsYmFja0NvbnN0cnVjdE5hbWU6IHByb3BzLmNvbGxlY3Rpb24ubmFtZSxcbiAgICB9KTtcbiAgICB0aGlzLnRpdGxlID0gbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUh1bWFuUmVhZGFibGVOYW1lKCk7XG4gICAgdGhpcy5jb2xsZWN0aW9uVXJsID0gc2NvcGVcbiAgICAgIC5jcmVhdGVBd3NDb25zb2xlVXJsRmFjdG9yeSgpXG4gICAgICAuZ2V0T3BlblNlYXJjaFNlcnZlcmxlc3NDb2xsZWN0aW9uVXJsKHByb3BzLmNvbGxlY3Rpb24ubmFtZSk7XG5cbiAgICB0aGlzLmFsYXJtRmFjdG9yeSA9IHRoaXMuY3JlYXRlQWxhcm1GYWN0b3J5KFxuICAgICAgbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUFsYXJtRnJpZW5kbHlOYW1lKCksXG4gICAgKTtcblxuICAgIHRoaXMubGF0ZW5jeUFsYXJtRmFjdG9yeSA9IG5ldyBMYXRlbmN5QWxhcm1GYWN0b3J5KHRoaXMuYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLmVycm9yQWxhcm1GYWN0b3J5ID0gbmV3IEVycm9yQWxhcm1GYWN0b3J5KHRoaXMuYWxhcm1GYWN0b3J5KTtcblxuICAgIHRoaXMuc2VhcmNoTGF0ZW5jeUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmVycm9yUmF0ZUFubm90YXRpb25zID0gW107XG5cbiAgICBjb25zdCBtZXRyaWNGYWN0b3J5ID0gbmV3IE9wZW5TZWFyY2hTZXJ2ZXJsZXNzTWV0cmljRmFjdG9yeShcbiAgICAgIHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKSxcbiAgICAgIHByb3BzLFxuICAgICk7XG5cbiAgICB0aGlzLm1ldHJpY1NlYXJjaFJlcXVlc3RFcnJvcnNDb3VudCA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlYXJjaFJlcXVlc3RFcnJvcnMoKTtcbiAgICB0aGlzLm1ldHJpY1NlYXJjaFJlcXVlc3RMYXRlbmN5QXZnID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljU2VhcmNoUmVxdWVzdExhdGVuY3koTGF0ZW5jeVR5cGUuQVZFUkFHRSk7XG4gICAgdGhpcy5tZXRyaWNTZWFyY2hSZXF1ZXN0TGF0ZW5jeU1heCA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlYXJjaFJlcXVlc3RMYXRlbmN5KExhdGVuY3lUeXBlLk1BWCk7XG5cbiAgICB0aGlzLm1ldHJpY0luZ2VzdGlvblJlcXVlc3RTdWNjZXNzQ291bnQgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNJbmdlc3Rpb25SZXF1ZXN0U3VjY2VzcygpO1xuICAgIHRoaXMubWV0cmljSW5nZXN0aW9uUmVxdWVzdEVycm9yc0NvdW50ID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljSW5nZXN0aW9uUmVxdWVzdEVycm9ycygpO1xuICAgIHRoaXMubWV0cmljSW5nZXN0aW9uUmVxdWVzdExhdGVuY3lBdmcgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNJbmdlc3Rpb25SZXF1ZXN0TGF0ZW5jeShMYXRlbmN5VHlwZS5BVkVSQUdFKTtcbiAgICB0aGlzLm1ldHJpY0luZ2VzdGlvblJlcXVlc3RMYXRlbmN5TWF4ID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljSW5nZXN0aW9uUmVxdWVzdExhdGVuY3koTGF0ZW5jeVR5cGUuTUFYKTtcblxuICAgIHRoaXMubWV0cmljNHh4RXJyb3JDb3VudCA9IG1ldHJpY0ZhY3RvcnkubWV0cmljNHh4Q291bnQoKTtcbiAgICB0aGlzLm1ldHJpYzR4eEVycm9yUmF0ZSA9IG1ldHJpY0ZhY3RvcnkubWV0cmljNHh4UmF0ZSgpO1xuXG4gICAgdGhpcy5tZXRyaWM1eHhFcnJvckNvdW50ID0gbWV0cmljRmFjdG9yeS5tZXRyaWM1eHhDb3VudCgpO1xuICAgIHRoaXMubWV0cmljNXh4RXJyb3JSYXRlID0gbWV0cmljRmFjdG9yeS5tZXRyaWM1eHhSYXRlKCk7XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkU2VhcmNoTGF0ZW5jeVAxMDBBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZFNlYXJjaExhdGVuY3lQMTAwQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmxhdGVuY3lBbGFybUZhY3RvcnkuYWRkTGF0ZW5jeUFsYXJtKFxuICAgICAgICB0aGlzLm1ldHJpY1NlYXJjaFJlcXVlc3RMYXRlbmN5TWF4LFxuICAgICAgICBMYXRlbmN5VHlwZS5QMTAwLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuc2VhcmNoTGF0ZW5jeUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRTZWFyY2hFcnJvckNvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRTZWFyY2hFcnJvckNvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yQ291bnRBbGFybShcbiAgICAgICAgdGhpcy5tZXRyaWNTZWFyY2hSZXF1ZXN0RXJyb3JzQ291bnQsXG4gICAgICAgIEVycm9yVHlwZS5FUlJPUixcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkNHh4Q291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZDR4eENvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yQ291bnRBbGFybShcbiAgICAgICAgdGhpcy5tZXRyaWM0eHhFcnJvckNvdW50LFxuICAgICAgICBFcnJvclR5cGUuVVNFUl9FUlJPUixcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkNHh4UmF0ZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkNHh4UmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lcnJvckFsYXJtRmFjdG9yeS5hZGRFcnJvclJhdGVBbGFybShcbiAgICAgICAgdGhpcy5tZXRyaWM0eHhFcnJvclJhdGUsXG4gICAgICAgIEVycm9yVHlwZS5VU0VSX0VSUk9SLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuZXJyb3JSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZDV4eENvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGQ1eHhDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lcnJvckFsYXJtRmFjdG9yeS5hZGRFcnJvckNvdW50QWxhcm0oXG4gICAgICAgIHRoaXMubWV0cmljNXh4RXJyb3JDb3VudCxcbiAgICAgICAgRXJyb3JUeXBlLkZBVUxULFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuZXJyb3JDb3VudEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGQ1eHhSYXRlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGQ1eHhSYXRlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yUmF0ZUFsYXJtKFxuICAgICAgICB0aGlzLm1ldHJpYzV4eEVycm9yUmF0ZSxcbiAgICAgICAgRXJyb3JUeXBlLkZBVUxULFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuZXJyb3JSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgcHJvcHMudXNlQ3JlYXRlZEFsYXJtcz8uY29uc3VtZSh0aGlzLmNyZWF0ZWRBbGFybXMoKSk7XG4gIH1cblxuICBzdW1tYXJ5V2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiB0aGlzLndpZGdldHMoKTtcbiAgfVxuXG4gIHdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgbmV3IFJvdyhcbiAgICAgICAgdGhpcy5jcmVhdGVTZWFyY2hSZXF1ZXN0TGF0ZW5jeVdpZGdldChcbiAgICAgICAgICBUaGlyZFdpZHRoLFxuICAgICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgICAgICAgKSxcbiAgICAgICAgdGhpcy5jcmVhdGVFcnJvckNvdW50V2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAgIHRoaXMuY3JlYXRlRXJyb3JSYXRlV2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICApLFxuICAgICAgbmV3IFJvdyhcbiAgICAgICAgdGhpcy5jcmVhdGVJbmdlc3Rpb25SZXF1ZXN0c1dpZGdldChIYWxmV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAgIHRoaXMuY3JlYXRlSW5nZXN0aW9uTGF0ZW5jeVdpZGdldChIYWxmV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICApLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlVGl0bGVXaWRnZXQoKTogSVdpZGdldCB7XG4gICAgcmV0dXJuIG5ldyBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0KHtcbiAgICAgIGZhbWlseTogXCJPcGVuU2VhcmNoIFNlcnZlcmxlc3MgQ29sbGVjdGlvblwiLFxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXG4gICAgICBnb1RvTGlua1VybDogdGhpcy5jb2xsZWN0aW9uVXJsLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVNlYXJjaFJlcXVlc3RMYXRlbmN5V2lkZ2V0KFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICk6IElXaWRnZXQge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJTZWFyY2ggcmVxdWVzdCBsYXRlbmN5XCIsXG4gICAgICBsZWZ0OiBbXG4gICAgICAgIHRoaXMubWV0cmljU2VhcmNoUmVxdWVzdExhdGVuY3lBdmcsXG4gICAgICAgIHRoaXMubWV0cmljU2VhcmNoUmVxdWVzdExhdGVuY3lNYXgsXG4gICAgICBdLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLnNlYXJjaExhdGVuY3lBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVFcnJvckNvdW50V2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogSVdpZGdldCB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkVycm9yc1wiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLm1ldHJpYzR4eEVycm9yQ291bnQsXG4gICAgICAgIHRoaXMubWV0cmljNXh4RXJyb3JDb3VudCxcbiAgICAgICAgdGhpcy5tZXRyaWNTZWFyY2hSZXF1ZXN0RXJyb3JzQ291bnQsXG4gICAgICBdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlRXJyb3JSYXRlV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogSVdpZGdldCB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkVycm9ycyAocmF0ZSlcIixcbiAgICAgIGxlZnQ6IFt0aGlzLm1ldHJpYzR4eEVycm9yUmF0ZSwgdGhpcy5tZXRyaWM1eHhFcnJvclJhdGVdLFxuICAgICAgbGVmdFlBeGlzOiBSYXRlQXhpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmVycm9yUmF0ZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUluZ2VzdGlvblJlcXVlc3RzV2lkZ2V0KFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICk6IElXaWRnZXQge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJJbmdlc3Rpb24gcmVxdWVzdHNcIixcbiAgICAgIGxlZnQ6IFtcbiAgICAgICAgdGhpcy5tZXRyaWNJbmdlc3Rpb25SZXF1ZXN0U3VjY2Vzc0NvdW50LFxuICAgICAgICB0aGlzLm1ldHJpY0luZ2VzdGlvblJlcXVlc3RFcnJvcnNDb3VudCxcbiAgICAgIF0sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUluZ2VzdGlvbkxhdGVuY3lXaWRnZXQoXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgKTogSVdpZGdldCB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkluZ2VzdGlvbiBsYXRlbmN5XCIsXG4gICAgICBsZWZ0OiBbXG4gICAgICAgIHRoaXMubWV0cmljSW5nZXN0aW9uUmVxdWVzdExhdGVuY3lBdmcsXG4gICAgICAgIHRoaXMubWV0cmljSW5nZXN0aW9uUmVxdWVzdExhdGVuY3lNYXgsXG4gICAgICBdLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG59XG4iXX0=