cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
215 lines • 33.4 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.KinesisDataAnalyticsMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const KinesisDataAnalyticsMetricFactory_1 = require("./KinesisDataAnalyticsMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
class KinesisDataAnalyticsMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
fallbackConstructName: props.application,
});
this.title = namingStrategy.resolveHumanReadableName();
this.kinesisDataAnalyticsUrl = scope
.createAwsConsoleUrlFactory()
.getKinesisAnalyticsUrl(props.application);
const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.kdaAlarmFactory = new common_1.KinesisDataAnalyticsAlarmFactory(alarmFactory);
this.downtimeAnnotations = [];
this.fullRestartAnnotations = [];
this.fullRestartRateAnnotations = [];
this.checkpointFailureCountAnnotations = [];
this.checkpointFailureRateAnnotations = [];
const metricFactory = new KinesisDataAnalyticsMetricFactory_1.KinesisDataAnalyticsMetricFactory(scope.createMetricFactory(), props);
this.cpuUtilizationPercentMetric =
metricFactory.metricCpuUtilizationPercent();
this.downtimeMsMetric = metricFactory.metricDowntimeMs();
this.fullRestartsCountMetric = metricFactory.metricFullRestartsCount();
this.heapMemoryUtilizationPercentMetric =
metricFactory.metricHeapMemoryUtilizationPercent();
this.kpusCountMetric = metricFactory.metricKPUsCount();
this.lastCheckpointDurationMsMetric =
metricFactory.metricLastCheckpointDurationMs();
this.lastCheckpointSizeBytesMetric =
metricFactory.metricLastCheckpointSizeBytes();
this.numberOfFailedCheckpointsCountMetric =
metricFactory.metricNumberOfFailedCheckpointsCount();
this.oldGenerationGCCountMetric =
metricFactory.metricOldGenerationGCCount();
this.oldGenerationGCTimeMsMetric =
metricFactory.metricOldGenerationGCTimeMs();
this.checkpointFailureRateMetric =
metricFactory.metricCheckpointFailureRate();
this.fullRestartRateMetric = metricFactory.metricFullRestartRate();
for (const disambiguator in props.addDowntimeAlarm) {
const alarmProps = props.addDowntimeAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addDowntimeAlarm(this.downtimeMsMetric, alarmProps, disambiguator);
this.downtimeAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addFullRestartCountAlarm) {
const alarmProps = props.addFullRestartCountAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addFullRestartAlarm(this.fullRestartsCountMetric, alarmProps, disambiguator);
this.fullRestartAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addFullRestartRateAlarm) {
const alarmProps = props.addFullRestartRateAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addFullRestartRateAlarm(this.fullRestartRateMetric, alarmProps, disambiguator);
this.fullRestartRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addCheckpointFailureCountAlarm) {
const alarmProps = props.addCheckpointFailureCountAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addCheckpointFailureCountAlarm(this.numberOfFailedCheckpointsCountMetric, alarmProps, disambiguator);
this.checkpointFailureCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addCheckpointFailureRateAlarm) {
const alarmProps = props.addCheckpointFailureRateAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addCheckpointFailureRateAlarm(this.checkpointFailureRateMetric, alarmProps, disambiguator);
this.checkpointFailureRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
...this.createSummaryWidgetRow(common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
return [
this.createTitleWidget(),
...this.createSummaryWidgetRow(common_1.DefaultGraphWidgetHeight),
...this.createCheckpointAndGcWidgets(),
];
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "Kinesis Data Analytics",
title: this.title,
goToLinkUrl: this.kinesisDataAnalyticsUrl,
});
}
createKPUWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "KPU Usage",
left: [this.kpusCountMetric],
leftYAxis: common_1.CountAxisFromZero,
});
}
createResourceUtilizationWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Resource Utilization",
left: [
this.cpuUtilizationPercentMetric,
this.heapMemoryUtilizationPercentMetric,
],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
});
}
createDownTimeWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Down Time",
left: [this.downtimeMsMetric],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.downtimeAnnotations,
});
}
createFullRestartsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Full Restarts",
left: [this.fullRestartsCountMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.fullRestartAnnotations,
right: [this.fullRestartRateMetric],
rightYAxis: common_1.RateAxisFromZero,
rightAnnotations: this.fullRestartRateAnnotations,
});
}
createNumberOfFailedCheckpointsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Checkpoint Failures",
left: [this.numberOfFailedCheckpointsCountMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.checkpointFailureCountAnnotations,
right: [this.checkpointFailureRateMetric],
rightYAxis: common_1.RateAxisFromZero,
rightAnnotations: this.checkpointFailureRateAnnotations,
});
}
createLastCheckpointDurationWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Checkpoint Duration",
left: [this.lastCheckpointDurationMsMetric],
leftYAxis: common_1.TimeAxisMillisFromZero,
});
}
createLastCheckpointSizeWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Checkpoint Size",
left: [this.lastCheckpointSizeBytesMetric],
leftYAxis: common_1.SizeAxisBytesFromZero,
});
}
createGarbageCollectionWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Garbage Collection",
left: [this.oldGenerationGCCountMetric],
leftYAxis: common_1.CountAxisFromZero,
right: [this.oldGenerationGCTimeMsMetric],
rightYAxis: common_1.TimeAxisMillisFromZero,
});
}
createSummaryWidgetRow(height) {
return [
// KPUs
this.createKPUWidget(common_1.QuarterWidth, height),
// CPU And Heap Usage
this.createResourceUtilizationWidget(common_1.QuarterWidth, height),
// Down Time and Up Time
this.createDownTimeWidget(common_1.QuarterWidth, height),
// Full Restarts
this.createFullRestartsWidget(common_1.QuarterWidth, height),
];
}
createCheckpointAndGcWidgets() {
return [
// Checkpointing
this.createNumberOfFailedCheckpointsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
// Checkpoint Duration
this.createLastCheckpointDurationWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
// Checkpoint Size
this.createLastCheckpointSizeWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
// Garbage Collection
this.createGarbageCollectionWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
];
}
}
exports.KinesisDataAnalyticsMonitoring = KinesisDataAnalyticsMonitoring;
_a = JSII_RTTI_SYMBOL_1;
KinesisDataAnalyticsMonitoring[_a] = { fqn: "cdk-monitoring-constructs.KinesisDataAnalyticsMonitoring", version: "9.19.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0RBSW9DO0FBRXBDLDJGQUc2QztBQUM3Qyx5Q0FrQnNCO0FBQ3RCLCtDQUd5QjtBQW1CekIsTUFBYSw4QkFBK0IsU0FBUSxtQkFBVTtJQXdCNUQsWUFDRSxLQUFzQixFQUN0QixLQUEwQztRQUUxQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXBCLE1BQU0sY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDbEQsR0FBRyxLQUFLO1lBQ1IscUJBQXFCLEVBQUUsS0FBSyxDQUFDLFdBQVc7U0FDekMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsS0FBSzthQUNqQywwQkFBMEIsRUFBRTthQUM1QixzQkFBc0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFN0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUMxQyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FDMUMsQ0FBQztRQUNGLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSx5Q0FBZ0MsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsRUFBRSxDQUFDO1FBQzVDLElBQUksQ0FBQyxnQ0FBZ0MsR0FBRyxFQUFFLENBQUM7UUFFM0MsTUFBTSxhQUFhLEdBQUcsSUFBSSxx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aW9uLFxuICBJV2lkZ2V0LFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcblxuaW1wb3J0IHtcbiAgS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5LFxuICBLaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnlQcm9wcyxcbn0gZnJvbSBcIi4vS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5XCI7XG5pbXBvcnQge1xuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBDb3VudEF4aXNGcm9tWmVybyxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgRXJyb3JDb3VudFRocmVzaG9sZCxcbiAgRXJyb3JSYXRlVGhyZXNob2xkLFxuICBGdWxsUmVzdGFydENvdW50VGhyZXNob2xkLFxuICBLaW5lc2lzRGF0YUFuYWx5dGljc0FsYXJtRmFjdG9yeSxcbiAgTWF4RG93bnRpbWVUaHJlc2hvbGQsXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1vbml0b3JpbmcsXG4gIE1vbml0b3JpbmdTY29wZSxcbiAgUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgUXVhcnRlcldpZHRoLFxuICBSYXRlQXhpc0Zyb21aZXJvLFxuICBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gIFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG59IGZyb20gXCIuLi8uLi9jb21tb25cIjtcbmltcG9ydCB7XG4gIE1vbml0b3JpbmdIZWFkZXJXaWRnZXQsXG4gIE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSxcbn0gZnJvbSBcIi4uLy4uL2Rhc2hib2FyZFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEtpbmVzaXNEYXRhQW5hbHl0aWNzTW9uaXRvcmluZ09wdGlvbnNcbiAgZXh0ZW5kcyBCYXNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkRG93bnRpbWVBbGFybT86IFJlY29yZDxzdHJpbmcsIE1heERvd250aW1lVGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRGdWxsUmVzdGFydENvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBGdWxsUmVzdGFydENvdW50VGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRGdWxsUmVzdGFydFJhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yUmF0ZVRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkQ2hlY2twb2ludEZhaWx1cmVDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JDb3VudFRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkQ2hlY2twb2ludEZhaWx1cmVSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvbGQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEtpbmVzaXNEYXRhQW5hbHl0aWNzTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5UHJvcHMsXG4gICAgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nT3B0aW9ucyB7fVxuXG5leHBvcnQgY2xhc3MgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nIGV4dGVuZHMgTW9uaXRvcmluZyB7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGtpbmVzaXNEYXRhQW5hbHl0aWNzVXJsPzogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IGtkYUFsYXJtRmFjdG9yeTogS2luZXNpc0RhdGFBbmFseXRpY3NBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IGRvd250aW1lQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGZ1bGxSZXN0YXJ0QW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGZ1bGxSZXN0YXJ0UmF0ZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBjaGVja3BvaW50RmFpbHVyZUNvdW50QW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGNoZWNrcG9pbnRGYWlsdXJlUmF0ZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuXG4gIHJlYWRvbmx5IGNwdVV0aWxpemF0aW9uUGVyY2VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgZG93bnRpbWVNc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgZnVsbFJlc3RhcnRzQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGhlYXBNZW1vcnlVdGlsaXphdGlvblBlcmNlbnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGtwdXNDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbGFzdENoZWNrcG9pbnREdXJhdGlvbk1zTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBsYXN0Q2hlY2twb2ludFNpemVCeXRlc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBvbGRHZW5lcmF0aW9uR0NDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgb2xkR2VuZXJhdGlvbkdDVGltZU1zTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBjaGVja3BvaW50RmFpbHVyZVJhdGVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGZ1bGxSZXN0YXJ0UmF0ZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogTW9uaXRvcmluZ1Njb3BlLFxuICAgIHByb3BzOiBLaW5lc2lzRGF0YUFuYWx5dGljc01vbml0b3JpbmdQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGZhbGxiYWNrQ29uc3RydWN0TmFtZTogcHJvcHMuYXBwbGljYXRpb24sXG4gICAgfSk7XG4gICAgdGhpcy50aXRsZSA9IG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVIdW1hblJlYWRhYmxlTmFtZSgpO1xuICAgIHRoaXMua2luZXNpc0RhdGFBbmFseXRpY3NVcmwgPSBzY29wZVxuICAgICAgLmNyZWF0ZUF3c0NvbnNvbGVVcmxGYWN0b3J5KClcbiAgICAgIC5nZXRLaW5lc2lzQW5hbHl0aWNzVXJsKHByb3BzLmFwcGxpY2F0aW9uKTtcblxuICAgIGNvbnN0IGFsYXJtRmFjdG9yeSA9IHRoaXMuY3JlYXRlQWxhcm1GYWN0b3J5KFxuICAgICAgbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUFsYXJtRnJpZW5kbHlOYW1lKCksXG4gICAgKTtcbiAgICB0aGlzLmtkYUFsYXJtRmFjdG9yeSA9IG5ldyBLaW5lc2lzRGF0YUFuYWx5dGljc0FsYXJtRmFjdG9yeShhbGFybUZhY3RvcnkpO1xuICAgIHRoaXMuZG93bnRpbWVBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuZnVsbFJlc3RhcnRBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuZnVsbFJlc3RhcnRSYXRlQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlQ291bnRBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIGNvbnN0IG1ldHJpY0ZhY3RvcnkgPSBuZXcgS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5KFxuICAgICAgc2NvcGUuY3JlYXRlTWV0cmljRmFjdG9yeSgpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcblxuICAgIHRoaXMuY3B1VXRpbGl6YXRpb25QZXJjZW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ3B1VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5kb3dudGltZU1zTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNEb3dudGltZU1zKCk7XG4gICAgdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljRnVsbFJlc3RhcnRzQ291bnQoKTtcbiAgICB0aGlzLmhlYXBNZW1vcnlVdGlsaXphdGlvblBlcmNlbnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNIZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5rcHVzQ291bnRNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0tQVXNDb3VudCgpO1xuICAgIHRoaXMubGFzdENoZWNrcG9pbnREdXJhdGlvbk1zTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljTGFzdENoZWNrcG9pbnREdXJhdGlvbk1zKCk7XG4gICAgdGhpcy5sYXN0Q2hlY2twb2ludFNpemVCeXRlc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0xhc3RDaGVja3BvaW50U2l6ZUJ5dGVzKCk7XG4gICAgdGhpcy5udW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNOdW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ0NvdW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljT2xkR2VuZXJhdGlvbkdDQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY09sZEdlbmVyYXRpb25HQ1RpbWVNcygpO1xuICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ2hlY2twb2ludEZhaWx1cmVSYXRlKCk7XG4gICAgdGhpcy5mdWxsUmVzdGFydFJhdGVNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0Z1bGxSZXN0YXJ0UmF0ZSgpO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZERvd250aW1lQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGREb3dudGltZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkRG93bnRpbWVBbGFybShcbiAgICAgICAgdGhpcy5kb3dudGltZU1zTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuZG93bnRpbWVBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkRnVsbFJlc3RhcnRDb3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkRnVsbFJlc3RhcnRDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkRnVsbFJlc3RhcnRBbGFybShcbiAgICAgICAgdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmZ1bGxSZXN0YXJ0QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEZ1bGxSZXN0YXJ0UmF0ZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkRnVsbFJlc3RhcnRSYXRlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmtkYUFsYXJtRmFjdG9yeS5hZGRGdWxsUmVzdGFydFJhdGVBbGFybShcbiAgICAgICAgdGhpcy5mdWxsUmVzdGFydFJhdGVNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5mdWxsUmVzdGFydFJhdGVBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkQ2hlY2twb2ludEZhaWx1cmVDb3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkQ2hlY2twb2ludEZhaWx1cmVDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkQ2hlY2twb2ludEZhaWx1cmVDb3VudEFsYXJtKFxuICAgICAgICB0aGlzLm51bWJlck9mRmFpbGVkQ2hlY2twb2ludHNDb3VudE1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkQ2hlY2twb2ludEZhaWx1cmVSYXRlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRDaGVja3BvaW50RmFpbHVyZVJhdGVBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMua2RhQWxhcm1GYWN0b3J5LmFkZENoZWNrcG9pbnRGYWlsdXJlUmF0ZUFsYXJtKFxuICAgICAgICB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlUmF0ZU1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlUmF0ZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIHByb3BzLnVzZUNyZWF0ZWRBbGFybXM/LmNvbnN1bWUodGhpcy5jcmVhdGVkQWxhcm1zKCkpO1xuICB9XG5cbiAgc3VtbWFyeVdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgLi4udGhpcy5jcmVhdGVTdW1tYXJ5V2lkZ2V0Um93KERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICBdO1xuICB9XG5cbiAgd2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICAuLi50aGlzLmNyZWF0ZVN1bW1hcnlXaWRnZXRSb3coRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIC4uLnRoaXMuY3JlYXRlQ2hlY2twb2ludEFuZEdjV2lkZ2V0cygpLFxuICAgIF07XG4gIH1cblxuICBjcmVhdGVUaXRsZVdpZGdldCgpIHtcbiAgICByZXR1cm4gbmV3IE1vbml0b3JpbmdIZWFkZXJXaWRnZXQoe1xuICAgICAgZmFtaWx5OiBcIktpbmVzaXMgRGF0YSBBbmFseXRpY3NcIixcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgICAgZ29Ub0xpbmtVcmw6IHRoaXMua2luZXNpc0RhdGFBbmFseXRpY3NVcmwsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVLUFVXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiS1BVIFVzYWdlXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5rcHVzQ291bnRNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZVJlc291cmNlVXRpbGl6YXRpb25XaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiUmVzb3VyY2UgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFtcbiAgICAgICAgdGhpcy5jcHVVdGlsaXphdGlvblBlcmNlbnRNZXRyaWMsXG4gICAgICAgIHRoaXMuaGVhcE1lbW9yeVV0aWxpemF0aW9uUGVyY2VudE1ldHJpYyxcbiAgICAgIF0sXG4gICAgICBsZWZ0WUF4aXM6IFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVEb3duVGltZVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJEb3duIFRpbWVcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmRvd250aW1lTXNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmRvd250aW1lQW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVGdWxsUmVzdGFydHNXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiRnVsbCBSZXN0YXJ0c1wiLFxuICAgICAgbGVmdDogW3RoaXMuZnVsbFJlc3RhcnRzQ291bnRNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5mdWxsUmVzdGFydEFubm90YXRpb25zLFxuICAgICAgcmlnaHQ6IFt0aGlzLmZ1bGxSZXN0YXJ0UmF0ZU1ldHJpY10sXG4gICAgICByaWdodFlBeGlzOiBSYXRlQXhpc0Zyb21aZXJvLFxuICAgICAgcmlnaHRBbm5vdGF0aW9uczogdGhpcy5mdWxsUmVzdGFydFJhdGVBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZU51bWJlck9mRmFpbGVkQ2hlY2twb2ludHNXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiQ2hlY2twb2ludCBGYWlsdXJlc1wiLFxuICAgICAgbGVmdDogW3RoaXMubnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c0NvdW50TWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuY2hlY2twb2ludEZhaWx1cmVDb3VudEFubm90YXRpb25zLFxuICAgICAgcmlnaHQ6IFt0aGlzLmNoZWNrcG9pbnRGYWlsdXJlUmF0ZU1ldHJpY10sXG4gICAgICByaWdodFlBeGlzOiBSYXRlQXhpc0Zyb21aZXJvLFxuICAgICAgcmlnaHRBbm5vdGF0aW9uczogdGhpcy5jaGVja3BvaW50RmFpbHVyZVJhdGVBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUxhc3RDaGVja3BvaW50RHVyYXRpb25XaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiQ2hlY2twb2ludCBEdXJhdGlvblwiLFxuICAgICAgbGVmdDogW3RoaXMubGFzdENoZWNrcG9pbnREdXJhdGlvbk1zTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUxhc3RDaGVja3BvaW50U2l6ZVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDaGVja3BvaW50IFNpemVcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmxhc3RDaGVja3BvaW50U2l6ZUJ5dGVzTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlR2FyYmFnZUNvbGxlY3Rpb25XaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiR2FyYmFnZSBDb2xsZWN0aW9uXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5vbGRHZW5lcmF0aW9uR0NDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgcmlnaHQ6IFt0aGlzLm9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpY10sXG4gICAgICByaWdodFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTdW1tYXJ5V2lkZ2V0Um93KGhlaWdodDogbnVtYmVyKTogR3JhcGhXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC8vIEtQVXNcbiAgICAgIHRoaXMuY3JlYXRlS1BVV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICAgIC8vIENQVSBBbmQgSGVhcCBVc2FnZVxuICAgICAgdGhpcy5jcmVhdGVSZXNvdXJjZVV0aWxpemF0aW9uV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICAgIC8vIERvd24gVGltZSBhbmQgVXAgVGltZVxuICAgICAgdGhpcy5jcmVhdGVEb3duVGltZVdpZGdldChRdWFydGVyV2lkdGgsIGhlaWdodCksXG4gICAgICAvLyBGdWxsIFJlc3RhcnRzXG4gICAgICB0aGlzLmNyZWF0ZUZ1bGxSZXN0YXJ0c1dpZGdldChRdWFydGVyV2lkdGgsIGhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ2hlY2twb2ludEFuZEdjV2lkZ2V0cygpOiBHcmFwaFdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gQ2hlY2twb2ludGluZ1xuICAgICAgdGhpcy5jcmVhdGVOdW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzV2lkZ2V0KFxuICAgICAgICBRdWFydGVyV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgICAgICksXG4gICAgICAvLyBDaGVja3BvaW50IER1cmF0aW9uXG4gICAgICB0aGlzLmNyZWF0ZUxhc3RDaGVja3BvaW50RHVyYXRpb25XaWRnZXQoXG4gICAgICAgIFF1YXJ0ZXJXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgKSxcbiAgICAgIC8vIENoZWNrcG9pbnQgU2l6ZVxuICAgICAgdGhpcy5jcmVhdGVMYXN0Q2hlY2twb2ludFNpemVXaWRnZXQoXG4gICAgICAgIFF1YXJ0ZXJXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgKSxcbiAgICAgIC8vIEdhcmJhZ2UgQ29sbGVjdGlvblxuICAgICAgdGhpcy5jcmVhdGVHYXJiYWdlQ29sbGVjdGlvbldpZGdldChcbiAgICAgICAgUXVhcnRlcldpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gICAgICApLFxuICAgIF07XG4gIH1cbn1cbiJdfQ==