cdk-monitoring-constructs
Version:
[](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs) [](https://badge
155 lines • 25.1 kB
JavaScript
"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 common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
const GlueJobMetricFactory_1 = require("./GlueJobMetricFactory");
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);
}
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],
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,
});
}
}
exports.GlueJobMonitoring = GlueJobMonitoring;
_a = JSII_RTTI_SYMBOL_1;
GlueJobMonitoring[_a] = { fqn: "cdk-monitoring-constructs.GlueJobMonitoring", version: "1.21.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiR2x1ZUpvYk1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJHbHVlSm9iTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUlvQztBQUVwQyx5Q0FtQnNCO0FBQ3RCLCtDQUd5QjtBQUN6QixpRUFHZ0M7QUFhaEMsTUFBYSxpQkFBa0IsU0FBUSxtQkFBVTtJQXFCL0MsWUFBWSxLQUFzQixFQUFFLEtBQTZCO1FBQy9ELEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFcEIsTUFBTSxxQkFBcUIsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQzVDLE1BQU0sY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDbEQsR0FBRyxLQUFLO1lBQ1IscUJBQXFCO1NBQ3RCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFFdkQsTUFBTSxhQUFhLEdBQUcsSUFBSSwyQ0FBb0IsQ0FDNUMsS0FBSyxDQUFDLG1CQUFtQixFQUFFLEVBQzNCLEtBQUssQ0FDTixDQUFDO1FBRUYsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQ3pDLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUMxQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksMEJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWxFLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztRQUUvQixJQUFJLENBQUMscUJBQXFCLEdBQUcsYUFBYSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDeEUsSUFBSSxDQUFDLHNCQUFzQixHQUFHLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1FBQzFFLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYTthQUNoQyx1Q0FBdUMsRUFBRTthQUN6QyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMscUJBQXFCLEdBQUcsYUFBYTthQUN2QywwQ0FBMEMsRUFBRTthQUM1QyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMscUJBQXFCLEdBQUcsYUFBYSxDQUFDLDRCQUE0QixFQUFFLENBQUM7UUFDMUUsSUFBSSxDQUFDLHFCQUFxQixHQUFHLGFBQWEsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ3RFLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxhQUFhLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztRQUMxRSxJQUFJLENBQUMscUJBQXFCLEdBQUcsYUFBYTthQUN2QyxvQkFBb0IsRUFBRTthQUN0QixJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsb0JBQW9CLEdBQUcsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDbEUsSUFBSSxDQUFDLHFCQUFxQixHQUFHLGFBQWE7YUFDdkMsb0JBQW9CLEVBQUU7YUFDdEIsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLG9CQUFvQixHQUFHLGFBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBRWxFLEtBQUssTUFBTSxhQUFhLElBQUksS0FBSyxDQUFDLHVCQUF1QixFQUFFO1lBQ3pELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoRSxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsa0JBQWtCLENBQzVELElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsa0JBQVMsQ0FBQyxLQUFLLEVBQ2YsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUM3QjtRQUVELEtBQUssTUFBTSxhQUFhLElBQUksS0FBSyxDQUFDLHNCQUFzQixFQUFFO1lBQ3hELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUMvRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLENBQzNELElBQUksQ0FBQyxvQkFBb0IsRUFDekIsa0JBQVMsQ0FBQyxLQUFLLEVBQ2YsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUM3QjtRQUVELEtBQUssTUFBTSxhQUFhLElBQUksS0FBSyxDQUFDLHVCQUF1QixFQUFFO1lBQ3pELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoRSxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsa0JBQWtCLENBQzVELElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsa0JBQVMsQ0FBQyxNQUFNLEVBQ2hCLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDN0I7UUFFRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsRUFBRTtZQUN4RCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDL0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGlCQUFpQixDQUMzRCxJQUFJLENBQUMsb0JBQW9CLEVBQ3pCLGtCQUFTLENBQUMsTUFBTSxFQUNoQixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQzdCO1FBRUQsS0FBSyxDQUFDLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU87WUFDTCxRQUFRO1lBQ1IsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3hCLGdCQUFnQjtZQUNoQixJQUFJLENBQUMsd0JBQXdCLENBQUMsa0JBQVMsRUFBRSxtQ0FBMEIsQ0FBQztZQUNwRSxTQUFTO1lBQ1QsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGtCQUFTLEVBQUUsbUNBQTBCLENBQUM7U0FDcEUsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ0wsT0FBTztZQUNMLFFBQVE7WUFDUixJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDeEIsZ0JBQWdCO1lBQ2hCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxxQkFBWSxFQUFFLGlDQUF3QixDQUFDO1lBQ3JFLGdCQUFnQjtZQUNoQixJQUFJLENBQUMsd0JBQXdCLENBQUMscUJBQVksRUFBRSxpQ0FBd0IsQ0FBQztZQUNyRSxTQUFTO1lBQ1QsSUFBSSxDQUFDLHVCQUF1QixDQUFDLHFCQUFZLEVBQUUsaUNBQXdCLENBQUM7WUFDcEUsU0FBUztZQUNULElBQUksQ0FBQyxzQkFBc0IsQ0FBQyx5QkFBZ0IsRUFBRSxpQ0FBd0IsQ0FBQztZQUN2RSxJQUFJLENBQUMscUJBQXFCLENBQUMseUJBQWdCLEVBQUUsaUNBQXdCLENBQUM7U0FDdkUsQ0FBQztJQUNKLENBQUM7SUFFUyxpQkFBaUI7UUFDekIsT0FBTyxJQUFJLGtDQUFzQixDQUFDO1lBQ2hDLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztTQUNsQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMsd0JBQXdCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDOUQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsZUFBZTtZQUN0QixJQUFJLEVBQUU7Z0JBQ0osSUFBSSxDQUFDLHFCQUFxQjtnQkFDMUIsSUFBSSxDQUFDLHFCQUFxQjtnQkFDMUIsSUFBSSxDQUFDLHFCQUFxQjthQUMzQjtZQUNELFNBQVMsRUFBRSwwQkFBaUI7U0FDN0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLHdCQUF3QixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQzlELE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLGVBQWU7WUFDdEIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQztZQUMvRCxTQUFTLEVBQUUsOEJBQXFCO1NBQ2pDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyx1QkFBdUIsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUM3RCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxrQkFBa0I7WUFDekIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUM7WUFDdkQsU0FBUyxFQUFFLHdDQUErQjtTQUMzQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMsc0JBQXNCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDNUQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsUUFBUTtZQUNmLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUM7WUFDOUQsU0FBUyxFQUFFLDBCQUFpQjtZQUM1QixlQUFlLEVBQUUsSUFBSSxDQUFDLHFCQUFxQjtTQUM1QyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMscUJBQXFCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDM0QsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsZUFBZTtZQUN0QixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDO1lBQzVELFNBQVMsRUFBRSx5QkFBZ0I7WUFDM0IsZUFBZSxFQUFFLElBQUksQ0FBQyxvQkFBb0I7U0FDM0MsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUEzTUgsOENBNE1DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhXaWRnZXQsXG4gIEhvcml6b250YWxBbm5vdGF0aW9uLFxuICBJV2lkZ2V0LFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcblxuaW1wb3J0IHtcbiAgQWxhcm1GYWN0b3J5LFxuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBDb3VudEF4aXNGcm9tWmVybyxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgRXJyb3JBbGFybUZhY3RvcnksXG4gIEVycm9yQ291bnRUaHJlc2hvbGQsXG4gIEVycm9yUmF0ZVRocmVzaG9sZCxcbiAgRXJyb3JUeXBlLFxuICBIYWxmUXVhcnRlcldpZHRoLFxuICBIYWxmV2lkdGgsXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1vbml0b3JpbmcsXG4gIE1vbml0b3JpbmdTY29wZSxcbiAgUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgUXVhcnRlcldpZHRoLFxuICBSYXRlQXhpc0Zyb21aZXJvLFxuICBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG59IGZyb20gXCIuLi8uLi9jb21tb25cIjtcbmltcG9ydCB7XG4gIE1vbml0b3JpbmdIZWFkZXJXaWRnZXQsXG4gIE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSxcbn0gZnJvbSBcIi4uLy4uL2Rhc2hib2FyZFwiO1xuaW1wb3J0IHtcbiAgR2x1ZUpvYk1ldHJpY0ZhY3RvcnksXG4gIEdsdWVKb2JNZXRyaWNGYWN0b3J5UHJvcHMsXG59IGZyb20gXCIuL0dsdWVKb2JNZXRyaWNGYWN0b3J5XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2x1ZUpvYk1vbml0b3JpbmdPcHRpb25zXG4gIGV4dGVuZHMgR2x1ZUpvYk1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBCYXNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkRmFpbGVkVGFza0NvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkRmFpbGVkVGFza1JhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yUmF0ZVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEtpbGxlZFRhc2tDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEtpbGxlZFRhc2tSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvbGQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdsdWVKb2JNb25pdG9yaW5nUHJvcHMgZXh0ZW5kcyBHbHVlSm9iTW9uaXRvcmluZ09wdGlvbnMge31cblxuZXhwb3J0IGNsYXNzIEdsdWVKb2JNb25pdG9yaW5nIGV4dGVuZHMgTW9uaXRvcmluZyB7XG4gIHByb3RlY3RlZCByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBhbGFybUZhY3Rvcnk6IEFsYXJtRmFjdG9yeTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGVycm9yQWxhcm1GYWN0b3J5OiBFcnJvckFsYXJtRmFjdG9yeTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3JDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3JSYXRlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGJ5dGVzUmVhZEZyb21TM01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGJ5dGVzV3JpdHRlblRvUzNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHByb3RlY3RlZCByZWFkb25seSBjcHVVc2FnZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGhlYXBNZW1vcnlVc2FnZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFjdGl2ZUV4ZWN1dG9yc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbXBsZXRlZFN0YWdlc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG5lZWRlZEV4ZWN1dG9yc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGZhaWxlZFRhc2tDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGZhaWxlZFRhc2tSYXRlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkga2lsbGVkVGFza0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkga2lsbGVkVGFza1JhdGVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IE1vbml0b3JpbmdTY29wZSwgcHJvcHM6IEdsdWVKb2JNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgcHJvcHMpO1xuXG4gICAgY29uc3QgZmFsbGJhY2tDb25zdHJ1Y3ROYW1lID0gcHJvcHMuam9iTmFtZTtcbiAgICBjb25zdCBuYW1pbmdTdHJhdGVneSA9IG5ldyBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3koe1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYWxsYmFja0NvbnN0cnVjdE5hbWUsXG4gICAgfSk7XG4gICAgdGhpcy50aXRsZSA9IG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVIdW1hblJlYWRhYmxlTmFtZSgpO1xuXG4gICAgY29uc3QgbWV0cmljRmFjdG9yeSA9IG5ldyBHbHVlSm9iTWV0cmljRmFjdG9yeShcbiAgICAgIHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKSxcbiAgICAgIHByb3BzXG4gICAgKTtcblxuICAgIHRoaXMuYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKVxuICAgICk7XG4gICAgdGhpcy5lcnJvckFsYXJtRmFjdG9yeSA9IG5ldyBFcnJvckFsYXJtRmFjdG9yeSh0aGlzLmFsYXJtRmFjdG9yeSk7XG5cbiAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuZXJyb3JSYXRlQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIHRoaXMuYnl0ZXNSZWFkRnJvbVMzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNUb3RhbFJlYWRCeXRlc0Zyb21TMygpO1xuICAgIHRoaXMuYnl0ZXNXcml0dGVuVG9TM01ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljVG90YWxXcml0dGVuQnl0ZXNUb1MzKCk7XG4gICAgdGhpcy5jcHVVc2FnZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnlcbiAgICAgIC5tZXRyaWNBdmVyYWdlRXhlY3V0b3JDcHVVc2FnZVBlcmNlbnRhZ2UoKVxuICAgICAgLndpdGgoeyBsYWJlbDogXCJDUFVcIiB9KTtcbiAgICB0aGlzLmhlYXBNZW1vcnlVc2FnZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnlcbiAgICAgIC5tZXRyaWNBdmVyYWdlRXhlY3V0b3JNZW1vcnlVc2FnZVBlcmNlbnRhZ2UoKVxuICAgICAgLndpdGgoeyBsYWJlbDogXCJIZWFwXCIgfSk7XG4gICAgdGhpcy5hY3RpdmVFeGVjdXRvcnNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0FjdGl2ZUV4ZWN1dG9yc0F2ZXJhZ2UoKTtcbiAgICB0aGlzLmNvbXBsZXRlZFN0YWdlc01ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljQ29tcGxldGVkU3RhZ2VzU3VtKCk7XG4gICAgdGhpcy5uZWVkZWRFeGVjdXRvcnNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY01heGltdW1OZWVkZWRFeGVjdXRvcnMoKTtcbiAgICB0aGlzLmZhaWxlZFRhc2tDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnlcbiAgICAgIC5tZXRyaWNGYWlsZWRUYXNrc1N1bSgpXG4gICAgICAud2l0aCh7IGxhYmVsOiBcIkZhaWxlZFwiIH0pO1xuICAgIHRoaXMuZmFpbGVkVGFza1JhdGVNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0ZhaWxlZFRhc2tzUmF0ZSgpO1xuICAgIHRoaXMua2lsbGVkVGFza0NvdW50TWV0cmljID0gbWV0cmljRmFjdG9yeVxuICAgICAgLm1ldHJpY0tpbGxlZFRhc2tzU3VtKClcbiAgICAgIC53aXRoKHsgbGFiZWw6IFwiS2lsbGVkXCIgfSk7XG4gICAgdGhpcy5raWxsZWRUYXNrUmF0ZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljS2lsbGVkVGFza3NSYXRlKCk7XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkRmFpbGVkVGFza0NvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRGYWlsZWRUYXNrQ291bnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuZXJyb3JBbGFybUZhY3RvcnkuYWRkRXJyb3JDb3VudEFsYXJtKFxuICAgICAgICB0aGlzLmZhaWxlZFRhc2tDb3VudE1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLkZBVUxULFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEZhaWxlZFRhc2tSYXRlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRGYWlsZWRUYXNrUmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lcnJvckFsYXJtRmFjdG9yeS5hZGRFcnJvclJhdGVBbGFybShcbiAgICAgICAgdGhpcy5mYWlsZWRUYXNrUmF0ZU1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLkZBVUxULFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvclJhdGVBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkS2lsbGVkVGFza0NvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRLaWxsZWRUYXNrQ291bnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuZXJyb3JBbGFybUZhY3RvcnkuYWRkRXJyb3JDb3VudEFsYXJtKFxuICAgICAgICB0aGlzLmtpbGxlZFRhc2tDb3VudE1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLktJTExFRCxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvclxuICAgICAgKTtcbiAgICAgIHRoaXMuZXJyb3JDb3VudEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRLaWxsZWRUYXNrUmF0ZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkS2lsbGVkVGFza1JhdGVBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuZXJyb3JBbGFybUZhY3RvcnkuYWRkRXJyb3JSYXRlQWxhcm0oXG4gICAgICAgIHRoaXMua2lsbGVkVGFza1JhdGVNZXRyaWMsXG4gICAgICAgIEVycm9yVHlwZS5LSUxMRUQsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yUmF0ZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIHByb3BzLnVzZUNyZWF0ZWRBbGFybXM/LmNvbnN1bWUodGhpcy5jcmVhdGVkQWxhcm1zKCkpO1xuICB9XG5cbiAgc3VtbWFyeVdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gVGl0bGVcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIC8vIEpvYiBFeGVjdXRpb25cbiAgICAgIHRoaXMuY3JlYXRlSm9iRXhlY3V0aW9uV2lkZ2V0KEhhbGZXaWR0aCwgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgICAgLy8gVXNhZ2VzXG4gICAgICB0aGlzLmNyZWF0ZVV0aWxpemF0aW9uV2lkZ2V0KEhhbGZXaWR0aCwgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgIF07XG4gIH1cblxuICB3aWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC8vIFRpdGxlXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICAvLyBKb2IgRXhlY3V0aW9uXG4gICAgICB0aGlzLmNyZWF0ZUpvYkV4ZWN1dGlvbldpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAvLyBEYXRhIE1vdmVtZW50XG4gICAgICB0aGlzLmNyZWF0ZURhdGFNb3ZlbWVudFdpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAvLyBVc2FnZXNcbiAgICAgIHRoaXMuY3JlYXRlVXRpbGl6YXRpb25XaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgLy8gRXJyb3JzXG4gICAgICB0aGlzLmNyZWF0ZUVycm9yQ291bnRXaWRnZXQoSGFsZlF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlRXJyb3JSYXRlV2lkZ2V0KEhhbGZRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVUaXRsZVdpZGdldCgpIHtcbiAgICByZXR1cm4gbmV3IE1vbml0b3JpbmdIZWFkZXJXaWRnZXQoe1xuICAgICAgZmFtaWx5OiBcIkdsdWUgSm9iXCIsXG4gICAgICB0aXRsZTogdGhpcy50aXRsZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVKb2JFeGVjdXRpb25XaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiSm9iIEV4ZWN1dGlvblwiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLmFjdGl2ZUV4ZWN1dG9yc01ldHJpYyxcbiAgICAgICAgdGhpcy5uZWVkZWRFeGVjdXRvcnNNZXRyaWMsXG4gICAgICAgIHRoaXMuY29tcGxldGVkU3RhZ2VzTWV0cmljLFxuICAgICAgXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlRGF0YU1vdmVtZW50V2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkRhdGEgTW92ZW1lbnRcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmJ5dGVzUmVhZEZyb21TM01ldHJpYywgdGhpcy5ieXRlc1dyaXR0ZW5Ub1MzTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVV0aWxpemF0aW9uV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkNQVS9NZW1vcnkgVXNhZ2VcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmNwdVVzYWdlTWV0cmljLCB0aGlzLmhlYXBNZW1vcnlVc2FnZU1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlRXJyb3JDb3VudFdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJFcnJvcnNcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmZhaWxlZFRhc2tDb3VudE1ldHJpYywgdGhpcy5raWxsZWRUYXNrQ291bnRNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlRXJyb3JSYXRlV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkVycm9ycyAocmF0ZSlcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmZhaWxlZFRhc2tSYXRlTWV0cmljLCB0aGlzLmtpbGxlZFRhc2tSYXRlTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogUmF0ZUF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5lcnJvclJhdGVBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxufVxuIl19