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

197 lines 31.9 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.GlueJobMonitoring = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch"); const aws_events_1 = require("aws-cdk-lib/aws-events"); const GlueJobMetricFactory_1 = require("./GlueJobMetricFactory"); const common_1 = require("../../common"); const dashboard_1 = require("../../dashboard"); class GlueJobMonitoring extends common_1.Monitoring { constructor(scope, props) { super(scope, props); const fallbackConstructName = props.jobName; const namingStrategy = new dashboard_1.MonitoringNamingStrategy({ ...props, fallbackConstructName, }); this.title = namingStrategy.resolveHumanReadableName(); const metricFactory = new GlueJobMetricFactory_1.GlueJobMetricFactory(scope.createMetricFactory(), props); this.alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName()); this.errorAlarmFactory = new common_1.ErrorAlarmFactory(this.alarmFactory); this.errorCountAnnotations = []; this.errorRateAnnotations = []; this.bytesReadFromS3Metric = metricFactory.metricTotalReadBytesFromS3(); this.bytesWrittenToS3Metric = metricFactory.metricTotalWrittenBytesToS3(); this.cpuUsageMetric = metricFactory .metricAverageExecutorCpuUsagePercentage() .with({ label: "CPU" }); this.heapMemoryUsageMetric = metricFactory .metricAverageExecutorMemoryUsagePercentage() .with({ label: "Heap" }); this.activeExecutorsMetric = metricFactory.metricActiveExecutorsAverage(); this.completedStagesMetric = metricFactory.metricCompletedStagesSum(); this.neededExecutorsMetric = metricFactory.metricMaximumNeededExecutors(); this.failedTaskCountMetric = metricFactory .metricFailedTasksSum() .with({ label: "Failed" }); this.failedTaskRateMetric = metricFactory.metricFailedTasksRate(); this.killedTaskCountMetric = metricFactory .metricKilledTasksSum() .with({ label: "Killed" }); this.killedTaskRateMetric = metricFactory.metricKilledTasksRate(); for (const disambiguator in props.addFailedTaskCountAlarm) { const alarmProps = props.addFailedTaskCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.failedTaskCountMetric, common_1.ErrorType.FAULT, alarmProps, disambiguator); this.errorCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addFailedTaskRateAlarm) { const alarmProps = props.addFailedTaskRateAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.failedTaskRateMetric, common_1.ErrorType.FAULT, alarmProps, disambiguator); this.errorRateAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addKilledTaskCountAlarm) { const alarmProps = props.addKilledTaskCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.killedTaskCountMetric, common_1.ErrorType.KILLED, alarmProps, disambiguator); this.errorCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addKilledTaskRateAlarm) { const alarmProps = props.addKilledTaskRateAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.killedTaskRateMetric, common_1.ErrorType.KILLED, alarmProps, disambiguator); this.errorRateAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } this.jobFailedStateMetric = this.createStateChangeMetric(props.jobName, "FAILED"); this.jobTimeoutStateMetric = this.createStateChangeMetric(props.jobName, "TIMEOUT"); for (const disambiguator in props.addJobFailedStateCountAlarm) { const alarmProps = props.addJobFailedStateCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.jobFailedStateMetric, common_1.ErrorType.FAILURE, alarmProps, disambiguator); this.errorCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addJobTimeoutStateCountAlarm) { const alarmProps = props.addJobTimeoutStateCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.jobTimeoutStateMetric, common_1.ErrorType.TIMED_OUT, alarmProps, disambiguator); this.errorCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } props.useCreatedAlarms?.consume(this.createdAlarms()); } summaryWidgets() { return [ // Title this.createTitleWidget(), // Job Execution this.createJobExecutionWidget(common_1.HalfWidth, common_1.DefaultSummaryWidgetHeight), // Usages this.createUtilizationWidget(common_1.HalfWidth, common_1.DefaultSummaryWidgetHeight), ]; } widgets() { return [ // Title this.createTitleWidget(), // Job Execution this.createJobExecutionWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), // Data Movement this.createDataMovementWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), // Usages this.createUtilizationWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), // Errors this.createErrorCountWidget(common_1.HalfQuarterWidth, common_1.DefaultGraphWidgetHeight), this.createErrorRateWidget(common_1.HalfQuarterWidth, common_1.DefaultGraphWidgetHeight), ]; } createTitleWidget() { return new dashboard_1.MonitoringHeaderWidget({ family: "Glue Job", title: this.title, }); } createJobExecutionWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Job Execution", left: [ this.activeExecutorsMetric, this.neededExecutorsMetric, this.completedStagesMetric, ], leftYAxis: common_1.CountAxisFromZero, }); } createDataMovementWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Data Movement", left: [this.bytesReadFromS3Metric, this.bytesWrittenToS3Metric], leftYAxis: common_1.SizeAxisBytesFromZero, }); } createUtilizationWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "CPU/Memory Usage", left: [this.cpuUsageMetric, this.heapMemoryUsageMetric], leftYAxis: common_1.PercentageAxisFromZeroToHundred, }); } createErrorCountWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Errors", left: [ this.failedTaskCountMetric, this.killedTaskCountMetric, this.jobFailedStateMetric, this.jobTimeoutStateMetric, ], leftYAxis: common_1.CountAxisFromZero, leftAnnotations: this.errorCountAnnotations, }); } createErrorRateWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Errors (rate)", left: [this.failedTaskRateMetric, this.killedTaskRateMetric], leftYAxis: common_1.RateAxisFromZero, leftAnnotations: this.errorRateAnnotations, }); } createStateChangeMetric(jobName, state) { const rule = new aws_events_1.Rule(this.scope, `GlueJob-${state}-StateChangeRule`, { description: `Event rule for catching ${jobName} ${state}`, eventPattern: { source: ["aws.glue"], detailType: ["Glue Job State Change"], detail: { jobName: [jobName], state: [state], }, }, }); return new aws_cloudwatch_1.Metric({ namespace: "AWS/Events", metricName: "TriggeredRules", dimensionsMap: { RuleName: rule.ruleName, }, statistic: "Sum", label: `Job ${state}`, }); } } exports.GlueJobMonitoring = GlueJobMonitoring; _a = JSII_RTTI_SYMBOL_1; GlueJobMonitoring[_a] = { fqn: "cdk-monitoring-constructs.GlueJobMonitoring", version: "10.2.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiR2x1ZUpvYk1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJHbHVlSm9iTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUtvQztBQUNwQyx1REFBOEM7QUFFOUMsaUVBR2dDO0FBQ2hDLHlDQW1Cc0I7QUFDdEIsK0NBR3lCO0FBZXpCLE1BQWEsaUJBQWtCLFNBQVEsbUJBQVU7SUF1Qi9DLFlBQVksS0FBc0IsRUFBRSxLQUE2QjtRQUMvRCxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXBCLE1BQU0scUJBQXFCLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM1QyxNQUFNLGNBQWMsR0FBRyxJQUFJLG9DQUF3QixDQUFDO1lBQ2xELEdBQUcsS0FBSztZQUNSLHFCQUFxQjtTQUN0QixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBRXZELE1BQU0sYUFBYSxHQUFHLElBQUksMkNBQW9CLENBQzVDLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxFQUMzQixLQUFLLENBQ04sQ0FBQztRQUVGLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUN6QyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FDMUMsQ0FBQztRQUNGLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLDBCQUFpQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRSxJQUFJLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFFL0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLGFBQWEsQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ3hFLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxhQUFhLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUMxRSxJQUFJLENBQUMsY0FB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RSxLQUFLO1lBQ2hCLEtBQUssRUFBRSxPQUFPLEtBQUssRUFBRTtTQUN0QixDQUFDLENBQUM7SUFDTCxDQUFDOztBQTlRSCw4Q0ErUUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElXaWRnZXQsXG4gIE1ldHJpYyxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5pbXBvcnQgeyBSdWxlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1ldmVudHNcIjtcblxuaW1wb3J0IHtcbiAgR2x1ZUpvYk1ldHJpY0ZhY3RvcnksXG4gIEdsdWVKb2JNZXRyaWNGYWN0b3J5UHJvcHMsXG59IGZyb20gXCIuL0dsdWVKb2JNZXRyaWNGYWN0b3J5XCI7XG5pbXBvcnQge1xuICBBbGFybUZhY3RvcnksXG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBFcnJvckFsYXJtRmFjdG9yeSxcbiAgRXJyb3JDb3VudFRocmVzaG9sZCxcbiAgRXJyb3JSYXRlVGhyZXNob2xkLFxuICBFcnJvclR5cGUsXG4gIEhhbGZRdWFydGVyV2lkdGgsXG4gIEhhbGZXaWR0aCxcbiAgTWV0cmljV2l0aEFsYXJtU3VwcG9ydCxcbiAgTW9uaXRvcmluZyxcbiAgTW9uaXRvcmluZ1Njb3BlLFxuICBQZXJjZW50YWdlQXhpc0Zyb21aZXJvVG9IdW5kcmVkLFxuICBRdWFydGVyV2lkdGgsXG4gIFJhdGVBeGlzRnJvbVplcm8sXG4gIFNpemVBeGlzQnl0ZXNGcm9tWmVybyxcbn0gZnJvbSBcIi4uLy4uL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgTW9uaXRvcmluZ0hlYWRlcldpZGdldCxcbiAgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5LFxufSBmcm9tIFwiLi4vLi4vZGFzaGJvYXJkXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2x1ZUpvYk1vbml0b3JpbmdPcHRpb25zXG4gIGV4dGVuZHMgR2x1ZUpvYk1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBCYXNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkRmFpbGVkVGFza0NvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkRmFpbGVkVGFza1JhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yUmF0ZVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEtpbGxlZFRhc2tDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEtpbGxlZFRhc2tSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRKb2JGYWlsZWRTdGF0ZUNvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSm9iVGltZW91dFN0YXRlQ291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yQ291bnRUaHJlc2hvbGQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdsdWVKb2JNb25pdG9yaW5nUHJvcHMgZXh0ZW5kcyBHbHVlSm9iTW9uaXRvcmluZ09wdGlvbnMge31cblxuZXhwb3J0IGNsYXNzIEdsdWVKb2JNb25pdG9yaW5nIGV4dGVuZHMgTW9uaXRvcmluZyB7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgYWxhcm1GYWN0b3J5OiBBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IGVycm9yQWxhcm1GYWN0b3J5OiBFcnJvckFsYXJtRmFjdG9yeTtcblxuICByZWFkb25seSBlcnJvckNvdW50QW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGVycm9yUmF0ZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuXG4gIHJlYWRvbmx5IGJ5dGVzUmVhZEZyb21TM01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgYnl0ZXNXcml0dGVuVG9TM01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgY3B1VXNhZ2VNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGhlYXBNZW1vcnlVc2FnZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgYWN0aXZlRXhlY3V0b3JzTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBjb21wbGV0ZWRTdGFnZXNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG5lZWRlZEV4ZWN1dG9yc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgZmFpbGVkVGFza0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBmYWlsZWRUYXNrUmF0ZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkga2lsbGVkVGFza0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBraWxsZWRUYXNrUmF0ZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgam9iRmFpbGVkU3RhdGVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGpvYlRpbWVvdXRTdGF0ZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogTW9uaXRvcmluZ1Njb3BlLCBwcm9wczogR2x1ZUpvYk1vbml0b3JpbmdQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBwcm9wcyk7XG5cbiAgICBjb25zdCBmYWxsYmFja0NvbnN0cnVjdE5hbWUgPSBwcm9wcy5qb2JOYW1lO1xuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGZhbGxiYWNrQ29uc3RydWN0TmFtZSxcbiAgICB9KTtcbiAgICB0aGlzLnRpdGxlID0gbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUh1bWFuUmVhZGFibGVOYW1lKCk7XG5cbiAgICBjb25zdCBtZXRyaWNGYWN0b3J5ID0gbmV3IEdsdWVKb2JNZXRyaWNGYWN0b3J5KFxuICAgICAgc2NvcGUuY3JlYXRlTWV0cmljRmFjdG9yeSgpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcblxuICAgIHRoaXMuYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKSxcbiAgICApO1xuICAgIHRoaXMuZXJyb3JBbGFybUZhY3RvcnkgPSBuZXcgRXJyb3JBbGFybUZhY3RvcnkodGhpcy5hbGFybUZhY3RvcnkpO1xuXG4gICAgdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmVycm9yUmF0ZUFubm90YXRpb25zID0gW107XG5cbiAgICB0aGlzLmJ5dGVzUmVhZEZyb21TM01ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljVG90YWxSZWFkQnl0ZXNGcm9tUzMoKTtcbiAgICB0aGlzLmJ5dGVzV3JpdHRlblRvUzNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY1RvdGFsV3JpdHRlbkJ5dGVzVG9TMygpO1xuICAgIHRoaXMuY3B1VXNhZ2VNZXRyaWMgPSBtZXRyaWNGYWN0b3J5XG4gICAgICAubWV0cmljQXZlcmFnZUV4ZWN1dG9yQ3B1VXNhZ2VQZXJjZW50YWdlKClcbiAgICAgIC53aXRoKHsgbGFiZWw6IFwiQ1BVXCIgfSk7XG4gICAgdGhpcy5oZWFwTWVtb3J5VXNhZ2VNZXRyaWMgPSBtZXRyaWNGYWN0b3J5XG4gICAgICAubWV0cmljQXZlcmFnZUV4ZWN1dG9yTWVtb3J5VXNhZ2VQZXJjZW50YWdlKClcbiAgICAgIC53aXRoKHsgbGFiZWw6IFwiSGVhcFwiIH0pO1xuICAgIHRoaXMuYWN0aXZlRXhlY3V0b3JzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNBY3RpdmVFeGVjdXRvcnNBdmVyYWdlKCk7XG4gICAgdGhpcy5jb21wbGV0ZWRTdGFnZXNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0NvbXBsZXRlZFN0YWdlc1N1bSgpO1xuICAgIHRoaXMubmVlZGVkRXhlY3V0b3JzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNNYXhpbXVtTmVlZGVkRXhlY3V0b3JzKCk7XG4gICAgdGhpcy5mYWlsZWRUYXNrQ291bnRNZXRyaWMgPSBtZXRyaWNGYWN0b3J5XG4gICAgICAubWV0cmljRmFpbGVkVGFza3NTdW0oKVxuICAgICAgLndpdGgoeyBsYWJlbDogXCJGYWlsZWRcIiB9KTtcbiAgICB0aGlzLmZhaWxlZFRhc2tSYXRlTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNGYWlsZWRUYXNrc1JhdGUoKTtcbiAgICB0aGlzLmtpbGxlZFRhc2tDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnlcbiAgICAgIC5tZXRyaWNLaWxsZWRUYXNrc1N1bSgpXG4gICAgICAud2l0aCh7IGxhYmVsOiBcIktpbGxlZFwiIH0pO1xuICAgIHRoaXMua2lsbGVkVGFza1JhdGVNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0tpbGxlZFRhc2tzUmF0ZSgpO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEZhaWxlZFRhc2tDb3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkRmFpbGVkVGFza0NvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yQ291bnRBbGFybShcbiAgICAgICAgdGhpcy5mYWlsZWRUYXNrQ291bnRNZXRyaWMsXG4gICAgICAgIEVycm9yVHlwZS5GQVVMVCxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkRmFpbGVkVGFza1JhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEZhaWxlZFRhc2tSYXRlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yUmF0ZUFsYXJtKFxuICAgICAgICB0aGlzLmZhaWxlZFRhc2tSYXRlTWV0cmljLFxuICAgICAgICBFcnJvclR5cGUuRkFVTFQsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvclJhdGVBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkS2lsbGVkVGFza0NvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRLaWxsZWRUYXNrQ291bnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuZXJyb3JBbGFybUZhY3RvcnkuYWRkRXJyb3JDb3VudEFsYXJtKFxuICAgICAgICB0aGlzLmtpbGxlZFRhc2tDb3VudE1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLktJTExFRCxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkS2lsbGVkVGFza1JhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEtpbGxlZFRhc2tSYXRlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yUmF0ZUFsYXJtKFxuICAgICAgICB0aGlzLmtpbGxlZFRhc2tSYXRlTWV0cmljLFxuICAgICAgICBFcnJvclR5cGUuS0lMTEVELFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuZXJyb3JSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgdGhpcy5qb2JGYWlsZWRTdGF0ZU1ldHJpYyA9IHRoaXMuY3JlYXRlU3RhdGVDaGFuZ2VNZXRyaWMoXG4gICAgICBwcm9wcy5qb2JOYW1lLFxuICAgICAgXCJGQUlMRURcIixcbiAgICApO1xuICAgIHRoaXMuam9iVGltZW91dFN0YXRlTWV0cmljID0gdGhpcy5jcmVhdGVTdGF0ZUNoYW5nZU1ldHJpYyhcbiAgICAgIHByb3BzLmpvYk5hbWUsXG4gICAgICBcIlRJTUVPVVRcIixcbiAgICApO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEpvYkZhaWxlZFN0YXRlQ291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEpvYkZhaWxlZFN0YXRlQ291bnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuZXJyb3JBbGFybUZhY3RvcnkuYWRkRXJyb3JDb3VudEFsYXJtKFxuICAgICAgICB0aGlzLmpvYkZhaWxlZFN0YXRlTWV0cmljLFxuICAgICAgICBFcnJvclR5cGUuRkFJTFVSRSxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSm9iVGltZW91dFN0YXRlQ291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEpvYlRpbWVvdXRTdGF0ZUNvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yQ291bnRBbGFybShcbiAgICAgICAgdGhpcy5qb2JUaW1lb3V0U3RhdGVNZXRyaWMsXG4gICAgICAgIEVycm9yVHlwZS5USU1FRF9PVVQsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgcHJvcHMudXNlQ3JlYXRlZEFsYXJtcz8uY29uc3VtZSh0aGlzLmNyZWF0ZWRBbGFybXMoKSk7XG4gIH1cblxuICBzdW1tYXJ5V2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICAvLyBUaXRsZVxuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgLy8gSm9iIEV4ZWN1dGlvblxuICAgICAgdGhpcy5jcmVhdGVKb2JFeGVjdXRpb25XaWRnZXQoSGFsZldpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgICAvLyBVc2FnZXNcbiAgICAgIHRoaXMuY3JlYXRlVXRpbGl6YXRpb25XaWRnZXQoSGFsZldpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gVGl0bGVcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIC8vIEpvYiBFeGVjdXRpb25cbiAgICAgIHRoaXMuY3JlYXRlSm9iRXhlY3V0aW9uV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIC8vIERhdGEgTW92ZW1lbnRcbiAgICAgIHRoaXMuY3JlYXRlRGF0YU1vdmVtZW50V2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIC8vIFVzYWdlc1xuICAgICAgdGhpcy5jcmVhdGVVdGlsaXphdGlvbldpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAvLyBFcnJvcnNcbiAgICAgIHRoaXMuY3JlYXRlRXJyb3JDb3VudFdpZGdldChIYWxmUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgdGhpcy5jcmVhdGVFcnJvclJhdGVXaWRnZXQoSGFsZlF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICBdO1xuICB9XG5cbiAgY3JlYXRlVGl0bGVXaWRnZXQoKSB7XG4gICAgcmV0dXJuIG5ldyBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0KHtcbiAgICAgIGZhbWlseTogXCJHbHVlIEpvYlwiLFxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVKb2JFeGVjdXRpb25XaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiSm9iIEV4ZWN1dGlvblwiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLmFjdGl2ZUV4ZWN1dG9yc01ldHJpYyxcbiAgICAgICAgdGhpcy5uZWVkZWRFeGVjdXRvcnNNZXRyaWMsXG4gICAgICAgIHRoaXMuY29tcGxldGVkU3RhZ2VzTWV0cmljLFxuICAgICAgXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVEYXRhTW92ZW1lbnRXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiRGF0YSBNb3ZlbWVudFwiLFxuICAgICAgbGVmdDogW3RoaXMuYnl0ZXNSZWFkRnJvbVMzTWV0cmljLCB0aGlzLmJ5dGVzV3JpdHRlblRvUzNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVVdGlsaXphdGlvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDUFUvTWVtb3J5IFVzYWdlXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5jcHVVc2FnZU1ldHJpYywgdGhpcy5oZWFwTWVtb3J5VXNhZ2VNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBQZXJjZW50YWdlQXhpc0Zyb21aZXJvVG9IdW5kcmVkLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlRXJyb3JDb3VudFdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJFcnJvcnNcIixcbiAgICAgIGxlZnQ6IFtcbiAgICAgICAgdGhpcy5mYWlsZWRUYXNrQ291bnRNZXRyaWMsXG4gICAgICAgIHRoaXMua2lsbGVkVGFza0NvdW50TWV0cmljLFxuICAgICAgICB0aGlzLmpvYkZhaWxlZFN0YXRlTWV0cmljLFxuICAgICAgICB0aGlzLmpvYlRpbWVvdXRTdGF0ZU1ldHJpYyxcbiAgICAgIF0sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUVycm9yUmF0ZVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJFcnJvcnMgKHJhdGUpXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5mYWlsZWRUYXNrUmF0ZU1ldHJpYywgdGhpcy5raWxsZWRUYXNrUmF0ZU1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFJhdGVBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuZXJyb3JSYXRlQW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVN0YXRlQ2hhbmdlTWV0cmljKFxuICAgIGpvYk5hbWU6IHN0cmluZyxcbiAgICBzdGF0ZTogc3RyaW5nLFxuICApOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0IHtcbiAgICBjb25zdCBydWxlID0gbmV3IFJ1bGUodGhpcy5zY29wZSwgYEdsdWVKb2ItJHtzdGF0ZX0tU3RhdGVDaGFuZ2VSdWxlYCwge1xuICAgICAgZGVzY3JpcHRpb246IGBFdmVudCBydWxlIGZvciBjYXRjaGluZyAke2pvYk5hbWV9ICR7c3RhdGV9YCxcbiAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICBzb3VyY2U6IFtcImF3cy5nbHVlXCJdLFxuICAgICAgICBkZXRhaWxUeXBlOiBbXCJHbHVlIEpvYiBTdGF0ZSBDaGFuZ2VcIl0sXG4gICAgICAgIGRldGFpbDoge1xuICAgICAgICAgIGpvYk5hbWU6IFtqb2JOYW1lXSxcbiAgICAgICAgICBzdGF0ZTogW3N0YXRlXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3IE1ldHJpYyh7XG4gICAgICBuYW1lc3BhY2U6IFwiQVdTL0V2ZW50c1wiLFxuICAgICAgbWV0cmljTmFtZTogXCJUcmlnZ2VyZWRSdWxlc1wiLFxuICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICBSdWxlTmFtZTogcnVsZS5ydWxlTmFtZSxcbiAgICAgIH0sXG4gICAgICBzdGF0aXN0aWM6IFwiU3VtXCIsXG4gICAgICBsYWJlbDogYEpvYiAke3N0YXRlfWAsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==