@cdklabs/multi-az-observability 0.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/.jsii +10177 -0
  2. package/API.md +5119 -0
  3. package/LICENSE +202 -0
  4. package/README.md +175 -0
  5. package/cdk.json +68 -0
  6. package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.d.ts +214 -0
  7. package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.js +763 -0
  8. package/lib/alarmsandrules/BaseOperationRegionalAlarmsAndRules.d.ts +22 -0
  9. package/lib/alarmsandrules/BaseOperationRegionalAlarmsAndRules.js +21 -0
  10. package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.d.ts +34 -0
  11. package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.js +39 -0
  12. package/lib/alarmsandrules/CanaryOperationRegionalAlarmsAndRules.d.ts +7 -0
  13. package/lib/alarmsandrules/CanaryOperationRegionalAlarmsAndRules.js +11 -0
  14. package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.d.ts +16 -0
  15. package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.js +17 -0
  16. package/lib/alarmsandrules/IBaseOperationRegionalAlarmsAndRules.d.ts +18 -0
  17. package/lib/alarmsandrules/IBaseOperationRegionalAlarmsAndRules.js +3 -0
  18. package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.d.ts +30 -0
  19. package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.js +3 -0
  20. package/lib/alarmsandrules/ICanaryOperationRegionalAlarmsAndRules.d.ts +6 -0
  21. package/lib/alarmsandrules/ICanaryOperationRegionalAlarmsAndRules.js +3 -0
  22. package/lib/alarmsandrules/ICanaryOperationZonalAlarmsAndRules.d.ts +12 -0
  23. package/lib/alarmsandrules/ICanaryOperationZonalAlarmsAndRules.js +3 -0
  24. package/lib/alarmsandrules/IOperationAlarmsAndRules.d.ts +55 -0
  25. package/lib/alarmsandrules/IOperationAlarmsAndRules.js +3 -0
  26. package/lib/alarmsandrules/IServerSideOperationRegionalAlarmsAndRules.d.ts +15 -0
  27. package/lib/alarmsandrules/IServerSideOperationRegionalAlarmsAndRules.js +3 -0
  28. package/lib/alarmsandrules/IServerSideOperationZonalAlarmsAndRules.d.ts +36 -0
  29. package/lib/alarmsandrules/IServerSideOperationZonalAlarmsAndRules.js +3 -0
  30. package/lib/alarmsandrules/IServiceAlarmsAndRules.d.ts +44 -0
  31. package/lib/alarmsandrules/IServiceAlarmsAndRules.js +3 -0
  32. package/lib/alarmsandrules/InsightRuleBody.d.ts +67 -0
  33. package/lib/alarmsandrules/InsightRuleBody.js +46 -0
  34. package/lib/alarmsandrules/OperationAlarmsAndRules.d.ts +59 -0
  35. package/lib/alarmsandrules/OperationAlarmsAndRules.js +135 -0
  36. package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.d.ts +19 -0
  37. package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.js +22 -0
  38. package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.d.ts +40 -0
  39. package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.js +46 -0
  40. package/lib/alarmsandrules/ServiceAlarmsAndRules.d.ts +48 -0
  41. package/lib/alarmsandrules/ServiceAlarmsAndRules.js +166 -0
  42. package/lib/alarmsandrules/props/BaseOperationRegionalAlarmsAndRulesProps.d.ts +24 -0
  43. package/lib/alarmsandrules/props/BaseOperationRegionalAlarmsAndRulesProps.js +3 -0
  44. package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.d.ts +62 -0
  45. package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.js +3 -0
  46. package/lib/alarmsandrules/props/CanaryOperationRegionalAlarmsAndRulesProps.d.ts +6 -0
  47. package/lib/alarmsandrules/props/CanaryOperationRegionalAlarmsAndRulesProps.js +3 -0
  48. package/lib/alarmsandrules/props/CanaryOperationZonalAlarmsAndRulesProps.d.ts +6 -0
  49. package/lib/alarmsandrules/props/CanaryOperationZonalAlarmsAndRulesProps.js +3 -0
  50. package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.d.ts +45 -0
  51. package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.js +3 -0
  52. package/lib/alarmsandrules/props/ServerSideOperationRegionalAlarmsAndRulesProps.d.ts +6 -0
  53. package/lib/alarmsandrules/props/ServerSideOperationRegionalAlarmsAndRulesProps.js +3 -0
  54. package/lib/alarmsandrules/props/ServerSideOperationZonalAlarmsAndRulesProps.d.ts +6 -0
  55. package/lib/alarmsandrules/props/ServerSideOperationZonalAlarmsAndRulesProps.js +3 -0
  56. package/lib/alarmsandrules/props/ServiceAlarmsAndRulesProps.d.ts +13 -0
  57. package/lib/alarmsandrules/props/ServiceAlarmsAndRulesProps.js +3 -0
  58. package/lib/azmapper/AvailabilityZoneMapper.d.ts +86 -0
  59. package/lib/azmapper/AvailabilityZoneMapper.js +200 -0
  60. package/lib/azmapper/IAvailabilityZoneMapper.d.ts +86 -0
  61. package/lib/azmapper/IAvailabilityZoneMapper.js +3 -0
  62. package/lib/azmapper/props/AvailabilityZoneMapperProps.d.ts +13 -0
  63. package/lib/azmapper/props/AvailabilityZoneMapperProps.js +3 -0
  64. package/lib/azmapper/src/index.py +107 -0
  65. package/lib/canaries/CanaryFunction.d.ts +16 -0
  66. package/lib/canaries/CanaryFunction.js +152 -0
  67. package/lib/canaries/CanaryTest.d.ts +10 -0
  68. package/lib/canaries/CanaryTest.js +84 -0
  69. package/lib/canaries/ICanaryFunction.d.ts +6 -0
  70. package/lib/canaries/ICanaryFunction.js +3 -0
  71. package/lib/canaries/props/AddCanaryTestProps.d.ts +66 -0
  72. package/lib/canaries/props/AddCanaryTestProps.js +3 -0
  73. package/lib/canaries/props/CanaryFunctionProps.d.ts +29 -0
  74. package/lib/canaries/props/CanaryFunctionProps.js +3 -0
  75. package/lib/canaries/props/CanaryTestProps.d.ts +21 -0
  76. package/lib/canaries/props/CanaryTestProps.js +3 -0
  77. package/lib/canaries/props/NetworkConfigurationProps.d.ts +16 -0
  78. package/lib/canaries/props/NetworkConfigurationProps.js +3 -0
  79. package/lib/canaries/src/canary.zip +0 -0
  80. package/lib/dashboards/BasicServiceDashboard.d.ts +10 -0
  81. package/lib/dashboards/BasicServiceDashboard.js +130 -0
  82. package/lib/dashboards/ContributorInsightsWidget.d.ts +22 -0
  83. package/lib/dashboards/ContributorInsightsWidget.js +55 -0
  84. package/lib/dashboards/IOperationAvailabilityAndLatencyDashboard.d.ts +10 -0
  85. package/lib/dashboards/IOperationAvailabilityAndLatencyDashboard.js +3 -0
  86. package/lib/dashboards/IServiceAvailabilityAndLatencyDashboard.d.ts +10 -0
  87. package/lib/dashboards/IServiceAvailabilityAndLatencyDashboard.js +3 -0
  88. package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.d.ts +20 -0
  89. package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.js +588 -0
  90. package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.d.ts +24 -0
  91. package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.js +475 -0
  92. package/lib/dashboards/props/BasicServiceDashboardProps.d.ts +23 -0
  93. package/lib/dashboards/props/BasicServiceDashboardProps.js +3 -0
  94. package/lib/dashboards/props/ContributorInsightWidgetProps.d.ts +31 -0
  95. package/lib/dashboards/props/ContributorInsightWidgetProps.js +3 -0
  96. package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.d.ts +84 -0
  97. package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.js +3 -0
  98. package/lib/dashboards/props/OperationAvailabilityWidgetProps.d.ts +37 -0
  99. package/lib/dashboards/props/OperationAvailabilityWidgetProps.js +3 -0
  100. package/lib/dashboards/props/OperationLatencyWidgetProps.d.ts +37 -0
  101. package/lib/dashboards/props/OperationLatencyWidgetProps.js +3 -0
  102. package/lib/dashboards/props/ServiceAvailabilityAndLatencyDashboardProps.d.ts +30 -0
  103. package/lib/dashboards/props/ServiceAvailabilityAndLatencyDashboardProps.js +3 -0
  104. package/lib/index.d.ts +35 -0
  105. package/lib/index.js +30 -0
  106. package/lib/metrics/ApplicationLoadBalancerMetrics.d.ts +36 -0
  107. package/lib/metrics/ApplicationLoadBalancerMetrics.js +150 -0
  108. package/lib/metrics/AvailabilityAndLatencyMetrics.d.ts +61 -0
  109. package/lib/metrics/AvailabilityAndLatencyMetrics.js +212 -0
  110. package/lib/metrics/NetworkLoadBalancerMetrics.d.ts +19 -0
  111. package/lib/metrics/NetworkLoadBalancerMetrics.js +48 -0
  112. package/lib/metrics/RegionalAvailabilityMetrics.d.ts +19 -0
  113. package/lib/metrics/RegionalAvailabilityMetrics.js +71 -0
  114. package/lib/metrics/RegionalLatencyMetrics.d.ts +33 -0
  115. package/lib/metrics/RegionalLatencyMetrics.js +69 -0
  116. package/lib/metrics/ZonalAvailabilityMetrics.d.ts +19 -0
  117. package/lib/metrics/ZonalAvailabilityMetrics.js +71 -0
  118. package/lib/metrics/ZonalLatencyMetrics.d.ts +29 -0
  119. package/lib/metrics/ZonalLatencyMetrics.js +65 -0
  120. package/lib/metrics/props/AvailabilityAndLatencyMetricProps.d.ts +23 -0
  121. package/lib/metrics/props/AvailabilityAndLatencyMetricProps.js +3 -0
  122. package/lib/metrics/props/AvailabilityMetricProps.d.ts +11 -0
  123. package/lib/metrics/props/AvailabilityMetricProps.js +3 -0
  124. package/lib/metrics/props/LatencyMetricProps.d.ts +15 -0
  125. package/lib/metrics/props/LatencyMetricProps.js +3 -0
  126. package/lib/metrics/props/RegionalAvailabilityMetricProps.d.ts +6 -0
  127. package/lib/metrics/props/RegionalAvailabilityMetricProps.js +3 -0
  128. package/lib/metrics/props/RegionalLatencyMetricProps.d.ts +6 -0
  129. package/lib/metrics/props/RegionalLatencyMetricProps.js +3 -0
  130. package/lib/metrics/props/ServiceAvailabilityMetricProps.d.ts +23 -0
  131. package/lib/metrics/props/ServiceAvailabilityMetricProps.js +3 -0
  132. package/lib/metrics/props/ServiceLatencyMericProps.d.ts +23 -0
  133. package/lib/metrics/props/ServiceLatencyMericProps.js +3 -0
  134. package/lib/metrics/props/ZonalAvailabilityMetricProps.d.ts +10 -0
  135. package/lib/metrics/props/ZonalAvailabilityMetricProps.js +3 -0
  136. package/lib/metrics/props/ZonalLatencyMetricProps.d.ts +10 -0
  137. package/lib/metrics/props/ZonalLatencyMetricProps.js +3 -0
  138. package/lib/monitoring/src/monitoring-layer.zip +0 -0
  139. package/lib/outlier-detection/IOutlierDetectionFunction.d.ts +12 -0
  140. package/lib/outlier-detection/IOutlierDetectionFunction.js +3 -0
  141. package/lib/outlier-detection/OutlierDetectionFunction.d.ts +16 -0
  142. package/lib/outlier-detection/OutlierDetectionFunction.js +126 -0
  143. package/lib/outlier-detection/props/OutlierDetectionFunctionProps.d.ts +12 -0
  144. package/lib/outlier-detection/props/OutlierDetectionFunctionProps.js +3 -0
  145. package/lib/outlier-detection/src/outlier-detection.zip +0 -0
  146. package/lib/outlier-detection/src/scipy-layer.zip +0 -0
  147. package/lib/services/BasicServiceMultiAZObservability.d.ts +64 -0
  148. package/lib/services/BasicServiceMultiAZObservability.js +504 -0
  149. package/lib/services/CanaryMetrics.d.ts +17 -0
  150. package/lib/services/CanaryMetrics.js +19 -0
  151. package/lib/services/CanaryTestMetricsOverride.d.ts +39 -0
  152. package/lib/services/CanaryTestMetricsOverride.js +23 -0
  153. package/lib/services/ContributorInsightRuleDetails.d.ts +42 -0
  154. package/lib/services/ContributorInsightRuleDetails.js +23 -0
  155. package/lib/services/IBasicServiceMultiAZObservability.d.ts +45 -0
  156. package/lib/services/IBasicServiceMultiAZObservability.js +3 -0
  157. package/lib/services/ICanaryMetrics.d.ts +14 -0
  158. package/lib/services/ICanaryMetrics.js +3 -0
  159. package/lib/services/ICanaryTestMetricsOverride.d.ts +36 -0
  160. package/lib/services/ICanaryTestMetricsOverride.js +3 -0
  161. package/lib/services/IContributorInsightRuleDetails.d.ts +38 -0
  162. package/lib/services/IContributorInsightRuleDetails.js +3 -0
  163. package/lib/services/IInstrumentedServiceMultiAZObservability.d.ts +39 -0
  164. package/lib/services/IInstrumentedServiceMultiAZObservability.js +3 -0
  165. package/lib/services/IOperation.d.ts +75 -0
  166. package/lib/services/IOperation.js +3 -0
  167. package/lib/services/IOperationMetricDetails.d.ts +78 -0
  168. package/lib/services/IOperationMetricDetails.js +3 -0
  169. package/lib/services/IService.d.ts +76 -0
  170. package/lib/services/IService.js +3 -0
  171. package/lib/services/IServiceMetricDetails.d.ts +68 -0
  172. package/lib/services/IServiceMetricDetails.js +3 -0
  173. package/lib/services/InstrumentedServiceMultiAZObservability.d.ts +55 -0
  174. package/lib/services/InstrumentedServiceMultiAZObservability.js +310 -0
  175. package/lib/services/Operation.d.ts +78 -0
  176. package/lib/services/Operation.js +34 -0
  177. package/lib/services/OperationMetricDetails.d.ts +82 -0
  178. package/lib/services/OperationMetricDetails.js +50 -0
  179. package/lib/services/Service.d.ts +80 -0
  180. package/lib/services/Service.js +36 -0
  181. package/lib/services/ServiceMetricDetails.d.ts +71 -0
  182. package/lib/services/ServiceMetricDetails.js +28 -0
  183. package/lib/services/props/BasicServiceMultiAZObservabilityProps.d.ts +126 -0
  184. package/lib/services/props/BasicServiceMultiAZObservabilityProps.js +3 -0
  185. package/lib/services/props/CanaryMetricProps.d.ts +14 -0
  186. package/lib/services/props/CanaryMetricProps.js +3 -0
  187. package/lib/services/props/CanaryTestMetricsOverrideProps.d.ts +47 -0
  188. package/lib/services/props/CanaryTestMetricsOverrideProps.js +3 -0
  189. package/lib/services/props/ContributorInsightRuleDetailsProps.d.ts +38 -0
  190. package/lib/services/props/ContributorInsightRuleDetailsProps.js +3 -0
  191. package/lib/services/props/InstrumentedServiceMultiAZObservabilityProps.d.ts +88 -0
  192. package/lib/services/props/InstrumentedServiceMultiAZObservabilityProps.js +3 -0
  193. package/lib/services/props/MetricDimensions.d.ts +61 -0
  194. package/lib/services/props/MetricDimensions.js +63 -0
  195. package/lib/services/props/OperationMetricDetailsProps.d.ts +97 -0
  196. package/lib/services/props/OperationMetricDetailsProps.js +3 -0
  197. package/lib/services/props/OperationProps.d.ts +93 -0
  198. package/lib/services/props/OperationProps.js +3 -0
  199. package/lib/services/props/ServiceMetricDetailsProps.d.ts +68 -0
  200. package/lib/services/props/ServiceMetricDetailsProps.js +3 -0
  201. package/lib/services/props/ServiceProps.d.ts +69 -0
  202. package/lib/services/props/ServiceProps.js +3 -0
  203. package/lib/utilities/AvailabilityMetricType.d.ts +26 -0
  204. package/lib/utilities/AvailabilityMetricType.js +33 -0
  205. package/lib/utilities/LatencyMetricType.d.ts +13 -0
  206. package/lib/utilities/LatencyMetricType.js +20 -0
  207. package/lib/utilities/OutlierDetectionAlgorithm.d.ts +42 -0
  208. package/lib/utilities/OutlierDetectionAlgorithm.js +49 -0
  209. package/lib/utilities/StackWithDynamicSource.d.ts +14 -0
  210. package/lib/utilities/StackWithDynamicSource.js +82 -0
  211. package/package.json +176 -0
  212. package/rosetta/default.ts-fixture +13 -0
@@ -0,0 +1,76 @@
1
+ import { Duration } from 'aws-cdk-lib';
2
+ import { ILoadBalancerV2 } from 'aws-cdk-lib/aws-elasticloadbalancingv2';
3
+ import { IContributorInsightRuleDetails } from './IContributorInsightRuleDetails';
4
+ import { IOperation } from './IOperation';
5
+ import { IServiceMetricDetails } from './IServiceMetricDetails';
6
+ import { AddCanaryTestProps } from '../canaries/props/AddCanaryTestProps';
7
+ /**
8
+ * Represents a complete service composed of one or more operations
9
+ */
10
+ export interface IService {
11
+ /**
12
+ * The name of your service
13
+ */
14
+ readonly serviceName: string;
15
+ /**
16
+ * The base endpoint for this service, like "https://www.example.com". Operation paths will be appended to this endpoint for canary testing the service.
17
+ */
18
+ readonly baseUrl: string;
19
+ /**
20
+ * The fault count threshold that indicates the service is unhealthy. This is an absolute value of faults
21
+ * being produced by all critical operations in aggregate.
22
+ */
23
+ readonly faultCountThreshold: number;
24
+ /**
25
+ * A list of the Availability Zone names used by this application
26
+ */
27
+ readonly availabilityZoneNames: string[];
28
+ /**
29
+ * The period for which metrics for the service should be aggregated
30
+ */
31
+ readonly period: Duration;
32
+ /**
33
+ * The operations that are part of this service
34
+ */
35
+ readonly operations: IOperation[];
36
+ /**
37
+ * The load balancer this service sits behind
38
+ *
39
+ * @default - No load balancer metrics are included in
40
+ * dashboards and its ARN is not added to top level AZ
41
+ * alarm descriptions.
42
+ */
43
+ readonly loadBalancer?: ILoadBalancerV2;
44
+ /**
45
+ * Define these settings if you want to automatically add canary
46
+ * tests to your operations. Operations can individually opt out
47
+ * of canary test creation if you define this setting.
48
+ *
49
+ * @default - Automatic canary tests will not be created for
50
+ * operations in this service.
51
+ */
52
+ readonly canaryTestProps?: AddCanaryTestProps;
53
+ /**
54
+ * The default settings that are used for availability metrics
55
+ * for all operations unless specifically overridden in an
56
+ * operation definition.
57
+ */
58
+ readonly defaultAvailabilityMetricDetails: IServiceMetricDetails;
59
+ /**
60
+ * The default settings that are used for availability metrics
61
+ * for all operations unless specifically overridden in an
62
+ * operation definition.
63
+ */
64
+ readonly defaultLatencyMetricDetails: IServiceMetricDetails;
65
+ /**
66
+ * The default settings that are used for contributor insight
67
+ * rules.
68
+ *
69
+ * @default - No defaults are provided and must be specified per operation
70
+ */
71
+ readonly defaultContributorInsightRuleDetails?: IContributorInsightRuleDetails;
72
+ /**
73
+ * Adds an operation to this service
74
+ */
75
+ addOperation(operation: IOperation): void;
76
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSVNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvSVNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbmltcG9ydCB7IER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgSUxvYWRCYWxhbmNlclYyIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjInO1xuaW1wb3J0IHsgSUNvbnRyaWJ1dG9ySW5zaWdodFJ1bGVEZXRhaWxzIH0gZnJvbSAnLi9JQ29udHJpYnV0b3JJbnNpZ2h0UnVsZURldGFpbHMnO1xuaW1wb3J0IHsgSU9wZXJhdGlvbiB9IGZyb20gJy4vSU9wZXJhdGlvbic7XG5pbXBvcnQgeyBJU2VydmljZU1ldHJpY0RldGFpbHMgfSBmcm9tICcuL0lTZXJ2aWNlTWV0cmljRGV0YWlscyc7XG5pbXBvcnQgeyBBZGRDYW5hcnlUZXN0UHJvcHMgfSBmcm9tICcuLi9jYW5hcmllcy9wcm9wcy9BZGRDYW5hcnlUZXN0UHJvcHMnO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBjb21wbGV0ZSBzZXJ2aWNlIGNvbXBvc2VkIG9mIG9uZSBvciBtb3JlIG9wZXJhdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJU2VydmljZSB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB5b3VyIHNlcnZpY2VcbiAgICovXG4gIHJlYWRvbmx5IHNlcnZpY2VOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGVuZHBvaW50IGZvciB0aGlzIHNlcnZpY2UsIGxpa2UgXCJodHRwczovL3d3dy5leGFtcGxlLmNvbVwiLiBPcGVyYXRpb24gcGF0aHMgd2lsbCBiZSBhcHBlbmRlZCB0byB0aGlzIGVuZHBvaW50IGZvciBjYW5hcnkgdGVzdGluZyB0aGUgc2VydmljZS5cbiAgICovXG4gIHJlYWRvbmx5IGJhc2VVcmw6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGZhdWx0IGNvdW50IHRocmVzaG9sZCB0aGF0IGluZGljYXRlcyB0aGUgc2VydmljZSBpcyB1bmhlYWx0aHkuIFRoaXMgaXMgYW4gYWJzb2x1dGUgdmFsdWUgb2YgZmF1bHRzXG4gICAqIGJlaW5nIHByb2R1Y2VkIGJ5IGFsbCBjcml0aWNhbCBvcGVyYXRpb25zIGluIGFnZ3JlZ2F0ZS5cbiAgICovXG4gIHJlYWRvbmx5IGZhdWx0Q291bnRUaHJlc2hvbGQ6IG51bWJlcjtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIHRoZSBBdmFpbGFiaWxpdHkgWm9uZSBuYW1lcyB1c2VkIGJ5IHRoaXMgYXBwbGljYXRpb25cbiAgICovXG4gIHJlYWRvbmx5IGF2YWlsYWJpbGl0eVpvbmVOYW1lczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFRoZSBwZXJpb2QgZm9yIHdoaWNoIG1ldHJpY3MgZm9yIHRoZSBzZXJ2aWNlIHNob3VsZCBiZSBhZ2dyZWdhdGVkXG4gICAqL1xuICByZWFkb25seSBwZXJpb2Q6IER1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlcmF0aW9ucyB0aGF0IGFyZSBwYXJ0IG9mIHRoaXMgc2VydmljZVxuICAgKi9cbiAgcmVhZG9ubHkgb3BlcmF0aW9uczogSU9wZXJhdGlvbltdO1xuXG4gIC8qKlxuICAgKiBUaGUgbG9hZCBiYWxhbmNlciB0aGlzIHNlcnZpY2Ugc2l0cyBiZWhpbmRcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBsb2FkIGJhbGFuY2VyIG1ldHJpY3MgYXJlIGluY2x1ZGVkIGluXG4gICAqIGRhc2hib2FyZHMgYW5kIGl0cyBBUk4gaXMgbm90IGFkZGVkIHRvIHRvcCBsZXZlbCBBWlxuICAgKiBhbGFybSBkZXNjcmlwdGlvbnMuXG4gICAqL1xuICByZWFkb25seSBsb2FkQmFsYW5jZXI/OiBJTG9hZEJhbGFuY2VyVjI7XG5cbiAgLyoqXG4gICAqIERlZmluZSB0aGVzZSBzZXR0aW5ncyBpZiB5b3Ugd2FudCB0byBhdXRvbWF0aWNhbGx5IGFkZCBjYW5hcnlcbiAgICogdGVzdHMgdG8geW91ciBvcGVyYXRpb25zLiBPcGVyYXRpb25zIGNhbiBpbmRpdmlkdWFsbHkgb3B0IG91dFxuICAgKiBvZiBjYW5hcnkgdGVzdCBjcmVhdGlvbiBpZiB5b3UgZGVmaW5lIHRoaXMgc2V0dGluZy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBdXRvbWF0aWMgY2FuYXJ5IHRlc3RzIHdpbGwgbm90IGJlIGNyZWF0ZWQgZm9yXG4gICAqIG9wZXJhdGlvbnMgaW4gdGhpcyBzZXJ2aWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgY2FuYXJ5VGVzdFByb3BzPzogQWRkQ2FuYXJ5VGVzdFByb3BzO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBzZXR0aW5ncyB0aGF0IGFyZSB1c2VkIGZvciBhdmFpbGFiaWxpdHkgbWV0cmljc1xuICAgKiBmb3IgYWxsIG9wZXJhdGlvbnMgdW5sZXNzIHNwZWNpZmljYWxseSBvdmVycmlkZGVuIGluIGFuXG4gICAqIG9wZXJhdGlvbiBkZWZpbml0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdEF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHM6IElTZXJ2aWNlTWV0cmljRGV0YWlscztcblxuICAvKipcbiAgICogVGhlIGRlZmF1bHQgc2V0dGluZ3MgdGhhdCBhcmUgdXNlZCBmb3IgYXZhaWxhYmlsaXR5IG1ldHJpY3NcbiAgICogZm9yIGFsbCBvcGVyYXRpb25zIHVubGVzcyBzcGVjaWZpY2FsbHkgb3ZlcnJpZGRlbiBpbiBhblxuICAgKiBvcGVyYXRpb24gZGVmaW5pdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRMYXRlbmN5TWV0cmljRGV0YWlsczogSVNlcnZpY2VNZXRyaWNEZXRhaWxzO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBzZXR0aW5ncyB0aGF0IGFyZSB1c2VkIGZvciBjb250cmlidXRvciBpbnNpZ2h0XG4gICAqIHJ1bGVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGRlZmF1bHRzIGFyZSBwcm92aWRlZCBhbmQgbXVzdCBiZSBzcGVjaWZpZWQgcGVyIG9wZXJhdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdENvbnRyaWJ1dG9ySW5zaWdodFJ1bGVEZXRhaWxzPzogSUNvbnRyaWJ1dG9ySW5zaWdodFJ1bGVEZXRhaWxzO1xuXG4gIC8qKlxuICAgKiBBZGRzIGFuIG9wZXJhdGlvbiB0byB0aGlzIHNlcnZpY2VcbiAgICovXG4gIGFkZE9wZXJhdGlvbihvcGVyYXRpb246IElPcGVyYXRpb24pOiB2b2lkO1xufVxuIl19
@@ -0,0 +1,68 @@
1
+ import { Duration } from 'aws-cdk-lib';
2
+ import { Unit } from 'aws-cdk-lib/aws-cloudwatch';
3
+ /**
4
+ * Details for the defaults used in a service for metrics in one perspective, such as server side latency
5
+ */
6
+ export interface IServiceMetricDetails {
7
+ /**
8
+ * The CloudWatch metric namespace for these metrics
9
+ */
10
+ readonly metricNamespace: string;
11
+ /**
12
+ * The names of success indicating metrics
13
+ */
14
+ readonly successMetricNames: string[];
15
+ /**
16
+ * The names of fault indicating metrics
17
+ */
18
+ readonly faultMetricNames: string[];
19
+ /**
20
+ * The statistic used for alarms, for availability metrics this should
21
+ * be "Sum", for latency metrics it could something like "p99" or "p99.9"
22
+ */
23
+ readonly alarmStatistic: string;
24
+ /**
25
+ * The statistics for successes you want to appear on dashboards, for example, with
26
+ * latency metrics, you might want p50, p99, and tm99. For availability
27
+ * metrics this will typically just be "Sum".
28
+ *
29
+ * @default - For availability metrics, this will be "Sum", for latency metrics it will be just "p99"
30
+ */
31
+ readonly graphedSuccessStatistics?: string[];
32
+ /**
33
+ * The statistics for faults you want to appear on dashboards, for example, with
34
+ * latency metrics, you might want p50, p99, and tm99. For availability
35
+ * metrics this will typically just be "Sum".
36
+ *
37
+ * @default - For availability metrics, this will be "Sum", for latency metrics it will be just "p99"
38
+ */
39
+ readonly graphedFaultStatistics?: string[];
40
+ /**
41
+ * The unit used for these metrics
42
+ */
43
+ readonly unit: Unit;
44
+ /**
45
+ * The period for the metrics
46
+ */
47
+ readonly period: Duration;
48
+ /**
49
+ * The number of evaluation periods for latency and availabiltiy alarms
50
+ */
51
+ readonly evaluationPeriods: number;
52
+ /**
53
+ * The number of datapoints to alarm on for latency and availability alarms
54
+ */
55
+ readonly datapointsToAlarm: number;
56
+ /**
57
+ * The threshold for alarms associated with success metrics, for example if measuring
58
+ * success rate, the threshold may be 99, meaning you would want an alarm that triggers
59
+ * if success drops below 99%.
60
+ */
61
+ readonly successAlarmThreshold: number;
62
+ /**
63
+ * The threshold for alarms associated with fault metrics, for example if measuring
64
+ * fault rate, the threshold may be 1, meaning you would want an alarm that triggers
65
+ * if the fault rate goes above 1%.
66
+ */
67
+ readonly faultAlarmThreshold: number;
68
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSVNlcnZpY2VNZXRyaWNEZXRhaWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL0lTZXJ2aWNlTWV0cmljRGV0YWlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuaW1wb3J0IHsgRHVyYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBVbml0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gnO1xuXG4vKipcbiAqIERldGFpbHMgZm9yIHRoZSBkZWZhdWx0cyB1c2VkIGluIGEgc2VydmljZSBmb3IgbWV0cmljcyBpbiBvbmUgcGVyc3BlY3RpdmUsIHN1Y2ggYXMgc2VydmVyIHNpZGUgbGF0ZW5jeVxuICovXG5leHBvcnQgaW50ZXJmYWNlIElTZXJ2aWNlTWV0cmljRGV0YWlscyB7XG4gIC8qKlxuICAgKiBUaGUgQ2xvdWRXYXRjaCBtZXRyaWMgbmFtZXNwYWNlIGZvciB0aGVzZSBtZXRyaWNzXG4gICAqL1xuICByZWFkb25seSBtZXRyaWNOYW1lc3BhY2U6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWVzIG9mIHN1Y2Nlc3MgaW5kaWNhdGluZyBtZXRyaWNzXG4gICAqL1xuICByZWFkb25seSBzdWNjZXNzTWV0cmljTmFtZXM6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZXMgb2YgZmF1bHQgaW5kaWNhdGluZyBtZXRyaWNzXG4gICAqL1xuICByZWFkb25seSBmYXVsdE1ldHJpY05hbWVzOiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIHN0YXRpc3RpYyB1c2VkIGZvciBhbGFybXMsIGZvciBhdmFpbGFiaWxpdHkgbWV0cmljcyB0aGlzIHNob3VsZFxuICAgKiBiZSBcIlN1bVwiLCBmb3IgbGF0ZW5jeSBtZXRyaWNzIGl0IGNvdWxkIHNvbWV0aGluZyBsaWtlIFwicDk5XCIgb3IgXCJwOTkuOVwiXG4gICAqL1xuICByZWFkb25seSBhbGFybVN0YXRpc3RpYzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgc3RhdGlzdGljcyBmb3Igc3VjY2Vzc2VzIHlvdSB3YW50IHRvIGFwcGVhciBvbiBkYXNoYm9hcmRzLCBmb3IgZXhhbXBsZSwgd2l0aFxuICAgKiBsYXRlbmN5IG1ldHJpY3MsIHlvdSBtaWdodCB3YW50IHA1MCwgcDk5LCBhbmQgdG05OS4gRm9yIGF2YWlsYWJpbGl0eVxuICAgKiBtZXRyaWNzIHRoaXMgd2lsbCB0eXBpY2FsbHkganVzdCBiZSBcIlN1bVwiLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEZvciBhdmFpbGFiaWxpdHkgbWV0cmljcywgdGhpcyB3aWxsIGJlIFwiU3VtXCIsIGZvciBsYXRlbmN5IG1ldHJpY3MgaXQgd2lsbCBiZSBqdXN0IFwicDk5XCJcbiAgICovXG4gIHJlYWRvbmx5IGdyYXBoZWRTdWNjZXNzU3RhdGlzdGljcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgc3RhdGlzdGljcyBmb3IgZmF1bHRzIHlvdSB3YW50IHRvIGFwcGVhciBvbiBkYXNoYm9hcmRzLCBmb3IgZXhhbXBsZSwgd2l0aFxuICAgKiBsYXRlbmN5IG1ldHJpY3MsIHlvdSBtaWdodCB3YW50IHA1MCwgcDk5LCBhbmQgdG05OS4gRm9yIGF2YWlsYWJpbGl0eVxuICAgKiBtZXRyaWNzIHRoaXMgd2lsbCB0eXBpY2FsbHkganVzdCBiZSBcIlN1bVwiLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEZvciBhdmFpbGFiaWxpdHkgbWV0cmljcywgdGhpcyB3aWxsIGJlIFwiU3VtXCIsIGZvciBsYXRlbmN5IG1ldHJpY3MgaXQgd2lsbCBiZSBqdXN0IFwicDk5XCJcbiAgICovXG4gIHJlYWRvbmx5IGdyYXBoZWRGYXVsdFN0YXRpc3RpY3M/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIHVuaXQgdXNlZCBmb3IgdGhlc2UgbWV0cmljc1xuICAgKi9cbiAgcmVhZG9ubHkgdW5pdDogVW5pdDtcblxuICAvKipcbiAgICogVGhlIHBlcmlvZCBmb3IgdGhlIG1ldHJpY3NcbiAgICovXG4gIHJlYWRvbmx5IHBlcmlvZDogRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgZXZhbHVhdGlvbiBwZXJpb2RzIGZvciBsYXRlbmN5IGFuZCBhdmFpbGFiaWx0aXkgYWxhcm1zXG4gICAqL1xuICByZWFkb25seSBldmFsdWF0aW9uUGVyaW9kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGRhdGFwb2ludHMgdG8gYWxhcm0gb24gZm9yIGxhdGVuY3kgYW5kIGF2YWlsYWJpbGl0eSBhbGFybXNcbiAgICovXG4gIHJlYWRvbmx5IGRhdGFwb2ludHNUb0FsYXJtOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB0aHJlc2hvbGQgZm9yIGFsYXJtcyBhc3NvY2lhdGVkIHdpdGggc3VjY2VzcyBtZXRyaWNzLCBmb3IgZXhhbXBsZSBpZiBtZWFzdXJpbmdcbiAgICogc3VjY2VzcyByYXRlLCB0aGUgdGhyZXNob2xkIG1heSBiZSA5OSwgbWVhbmluZyB5b3Ugd291bGQgd2FudCBhbiBhbGFybSB0aGF0IHRyaWdnZXJzXG4gICAqIGlmIHN1Y2Nlc3MgZHJvcHMgYmVsb3cgOTklLlxuICAgKi9cbiAgcmVhZG9ubHkgc3VjY2Vzc0FsYXJtVGhyZXNob2xkOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB0aHJlc2hvbGQgZm9yIGFsYXJtcyBhc3NvY2lhdGVkIHdpdGggZmF1bHQgbWV0cmljcywgZm9yIGV4YW1wbGUgaWYgbWVhc3VyaW5nXG4gICAqIGZhdWx0IHJhdGUsIHRoZSB0aHJlc2hvbGQgbWF5IGJlIDEsIG1lYW5pbmcgeW91IHdvdWxkIHdhbnQgYW4gYWxhcm0gdGhhdCB0cmlnZ2Vyc1xuICAgKiBpZiB0aGUgZmF1bHQgcmF0ZSBnb2VzIGFib3ZlIDElLlxuICAgKi9cbiAgcmVhZG9ubHkgZmF1bHRBbGFybVRocmVzaG9sZDogbnVtYmVyO1xufVxuIl19
@@ -0,0 +1,55 @@
1
+ import { Dashboard, IAlarm } from 'aws-cdk-lib/aws-cloudwatch';
2
+ import { ILogGroup } from 'aws-cdk-lib/aws-logs';
3
+ import { Construct } from 'constructs';
4
+ import { IInstrumentedServiceMultiAZObservability } from './IInstrumentedServiceMultiAZObservability';
5
+ import { InstrumentedServiceMultiAZObservabilityProps } from './props/InstrumentedServiceMultiAZObservabilityProps';
6
+ import { IServiceAlarmsAndRules } from '../alarmsandrules/IServiceAlarmsAndRules';
7
+ /**
8
+ * An service that implements its own instrumentation to record
9
+ * availability and latency metrics that can be used to create
10
+ * alarms, rules, and dashboards from
11
+ */
12
+ export declare class InstrumentedServiceMultiAZObservability extends Construct implements IInstrumentedServiceMultiAZObservability {
13
+ /**
14
+ * Key represents the operation name and the value is the set
15
+ * of zonal alarms and rules for that operation. The values themselves
16
+ * are dictionaries that have a key for each AZ ID.
17
+ */
18
+ private readonly perOperationAlarmsAndRules;
19
+ /**
20
+ * Index into the dictionary by operation name, then by Availability Zone Id
21
+ * to get the alarms that indicate an AZ shows isolated impact from availability
22
+ * or latency as seen by either the server-side or canary. These are the alarms
23
+ * you would want to use to trigger automation to evacuate an AZ.
24
+ */
25
+ readonly perOperationZonalImpactAlarms: {
26
+ [key: string]: {
27
+ [key: string]: IAlarm;
28
+ };
29
+ };
30
+ /**
31
+ * The alarms and rules for the overall service
32
+ */
33
+ readonly serviceAlarms: IServiceAlarmsAndRules;
34
+ /**
35
+ * The dashboards for each operation
36
+ */
37
+ readonly operationDashboards?: Dashboard[];
38
+ /**
39
+ * The service level dashboard
40
+ */
41
+ readonly serviceDashboard?: Dashboard;
42
+ /**
43
+ * The AZ mapper custom resource used to map AZ Ids to Names and vice a versa
44
+ */
45
+ private readonly azMapper;
46
+ /**
47
+ * If the service is configured to have canary tests created, this will
48
+ * be the log group where the canary's logs are stored.
49
+ *
50
+ * @default - No log group is created if the canary is not requested.
51
+ */
52
+ readonly canaryLogGroup?: ILogGroup;
53
+ private readonly outlierDetectionFunction?;
54
+ constructor(scope: Construct, id: string, props: InstrumentedServiceMultiAZObservabilityProps);
55
+ }
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.InstrumentedServiceMultiAZObservability = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
7
+ // SPDX-License-Identifier: Apache-2.0
8
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
9
+ const constructs_1 = require("constructs");
10
+ const CanaryMetrics_1 = require("./CanaryMetrics");
11
+ const Operation_1 = require("./Operation");
12
+ const OperationMetricDetails_1 = require("./OperationMetricDetails");
13
+ const MetricDimensions_1 = require("./props/MetricDimensions");
14
+ const OperationAlarmsAndRules_1 = require("../alarmsandrules/OperationAlarmsAndRules");
15
+ const ServiceAlarmsAndRules_1 = require("../alarmsandrules/ServiceAlarmsAndRules");
16
+ const AvailabilityZoneMapper_1 = require("../azmapper/AvailabilityZoneMapper");
17
+ const CanaryFunction_1 = require("../canaries/CanaryFunction");
18
+ const CanaryTest_1 = require("../canaries/CanaryTest");
19
+ const OperationAvailabilityAndLatencyDashboard_1 = require("../dashboards/OperationAvailabilityAndLatencyDashboard");
20
+ const ServiceAvailabilityAndLatencyDashboard_1 = require("../dashboards/ServiceAvailabilityAndLatencyDashboard");
21
+ const OutlierDetectionFunction_1 = require("../outlier-detection/OutlierDetectionFunction");
22
+ const OutlierDetectionAlgorithm_1 = require("../utilities/OutlierDetectionAlgorithm");
23
+ const StackWithDynamicSource_1 = require("../utilities/StackWithDynamicSource");
24
+ /**
25
+ * An service that implements its own instrumentation to record
26
+ * availability and latency metrics that can be used to create
27
+ * alarms, rules, and dashboards from
28
+ */
29
+ class InstrumentedServiceMultiAZObservability extends constructs_1.Construct {
30
+ constructor(scope, id, props) {
31
+ super(scope, id);
32
+ let outlierThreshold;
33
+ if (!props.outlierThreshold) {
34
+ switch (props.outlierDetectionAlgorithm) {
35
+ case OutlierDetectionAlgorithm_1.OutlierDetectionAlgorithm.CHI_SQUARED:
36
+ outlierThreshold = 0.05;
37
+ break;
38
+ case OutlierDetectionAlgorithm_1.OutlierDetectionAlgorithm.IQR:
39
+ outlierThreshold = 1.5;
40
+ break;
41
+ case OutlierDetectionAlgorithm_1.OutlierDetectionAlgorithm.MAD:
42
+ outlierThreshold = 3;
43
+ break;
44
+ case OutlierDetectionAlgorithm_1.OutlierDetectionAlgorithm.STATIC:
45
+ outlierThreshold = 0.7;
46
+ break;
47
+ case OutlierDetectionAlgorithm_1.OutlierDetectionAlgorithm.Z_SCORE:
48
+ outlierThreshold = 2;
49
+ break;
50
+ }
51
+ }
52
+ else {
53
+ outlierThreshold = props.outlierThreshold;
54
+ }
55
+ this.azMapper = new AvailabilityZoneMapper_1.AvailabilityZoneMapper(this, 'AZMapper', {
56
+ availabilityZoneNames: props.service.availabilityZoneNames,
57
+ });
58
+ if (props.service.canaryTestProps !== undefined) {
59
+ let canaryStack = new StackWithDynamicSource_1.StackWithDynamicSource(this, 'Canary', {
60
+ assetsBucketsParameterName: props.assetsBucketParameterName,
61
+ assetsBucketPrefixParameterName: props.assetsBucketPrefixParameterName,
62
+ });
63
+ let canary = new CanaryFunction_1.CanaryFunction(canaryStack, 'CanaryFunction', {
64
+ vpc: props.service.canaryTestProps.networkConfiguration?.vpc,
65
+ subnetSelection: props.service.canaryTestProps.networkConfiguration?.subnetSelection,
66
+ httpTimeout: props.service.canaryTestProps.timeout
67
+ ? props.service.canaryTestProps.timeout
68
+ : aws_cdk_lib_1.Duration.seconds(2),
69
+ ignoreTlsErrors: props.service.canaryTestProps.ignoreTlsErrors
70
+ ? props.service.canaryTestProps.ignoreTlsErrors
71
+ : false,
72
+ });
73
+ this.canaryLogGroup = canary.logGroup;
74
+ for (let i = 0; i < props.service.operations.length; i++) {
75
+ let operation = props.service.operations[i];
76
+ if (operation.optOutOfServiceCreatedCanary != true) {
77
+ let testProps = operation.canaryTestProps
78
+ ? operation.canaryTestProps
79
+ : props.service.canaryTestProps;
80
+ let nestedStack = new aws_cdk_lib_1.NestedStack(this, operation.operationName + 'CanaryTest', {});
81
+ let test = new CanaryTest_1.CanaryTest(nestedStack, operation.operationName, {
82
+ function: canary.function,
83
+ requestCount: testProps.requestCount,
84
+ regionalRequestCount: testProps.regionalRequestCount
85
+ ? testProps.regionalRequestCount
86
+ : testProps.requestCount,
87
+ schedule: testProps.schedule,
88
+ operation: operation,
89
+ loadBalancer: testProps.loadBalancer,
90
+ headers: testProps.headers,
91
+ postData: testProps.postData,
92
+ azMapper: this.azMapper,
93
+ });
94
+ let defaultAvailabilityMetricDetails;
95
+ let defaultLatencyMetricDetails;
96
+ if (operation.canaryMetricDetails?.canaryAvailabilityMetricDetails) {
97
+ defaultAvailabilityMetricDetails = new OperationMetricDetails_1.OperationMetricDetails({
98
+ operationName: operation.operationName,
99
+ metricDimensions: new MetricDimensions_1.MetricDimensions({ Operation: operation.operationName }, 'AZ-ID', 'Region'),
100
+ alarmStatistic: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
101
+ .alarmStatistic,
102
+ datapointsToAlarm: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
103
+ .datapointsToAlarm,
104
+ evaluationPeriods: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
105
+ .evaluationPeriods,
106
+ faultAlarmThreshold: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
107
+ .faultAlarmThreshold,
108
+ faultMetricNames: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
109
+ .faultMetricNames,
110
+ graphedFaultStatistics: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
111
+ .graphedFaultStatistics,
112
+ graphedSuccessStatistics: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
113
+ .graphedSuccessStatistics,
114
+ metricNamespace: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
115
+ .metricNamespace,
116
+ period: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
117
+ .period,
118
+ successAlarmThreshold: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
119
+ .successAlarmThreshold,
120
+ successMetricNames: operation.canaryMetricDetails.canaryAvailabilityMetricDetails
121
+ .successMetricNames,
122
+ unit: operation.canaryMetricDetails
123
+ .canaryAvailabilityMetricDetails.unit,
124
+ }, operation.service.defaultAvailabilityMetricDetails);
125
+ }
126
+ else if (operation.canaryTestAvailabilityMetricsOverride) {
127
+ defaultAvailabilityMetricDetails = new OperationMetricDetails_1.OperationMetricDetails({
128
+ operationName: operation.operationName,
129
+ metricNamespace: test.metricNamespace,
130
+ successMetricNames: ['Success'],
131
+ faultMetricNames: ['Fault', 'Failure'],
132
+ metricDimensions: new MetricDimensions_1.MetricDimensions({ Operation: operation.operationName }, 'AZ-ID', 'Region'),
133
+ alarmStatistic: operation.canaryTestAvailabilityMetricsOverride
134
+ .alarmStatistic,
135
+ datapointsToAlarm: operation.canaryTestAvailabilityMetricsOverride
136
+ .datapointsToAlarm,
137
+ evaluationPeriods: operation.canaryTestAvailabilityMetricsOverride
138
+ .evaluationPeriods,
139
+ faultAlarmThreshold: operation.canaryTestAvailabilityMetricsOverride
140
+ .faultAlarmThreshold,
141
+ period: operation.canaryTestAvailabilityMetricsOverride.period,
142
+ successAlarmThreshold: operation.canaryTestAvailabilityMetricsOverride
143
+ .successAlarmThreshold,
144
+ }, props.service.defaultAvailabilityMetricDetails);
145
+ }
146
+ else {
147
+ defaultAvailabilityMetricDetails = new OperationMetricDetails_1.OperationMetricDetails({
148
+ operationName: operation.operationName,
149
+ metricNamespace: test.metricNamespace,
150
+ successMetricNames: ['Success'],
151
+ faultMetricNames: ['Fault', 'Failure'],
152
+ metricDimensions: new MetricDimensions_1.MetricDimensions({ Operation: operation.operationName }, 'AZ-ID', 'Region'),
153
+ }, props.service.defaultAvailabilityMetricDetails);
154
+ }
155
+ if (operation.canaryMetricDetails?.canaryLatencyMetricDetails) {
156
+ defaultLatencyMetricDetails = new OperationMetricDetails_1.OperationMetricDetails({
157
+ operationName: operation.operationName,
158
+ metricDimensions: new MetricDimensions_1.MetricDimensions({ Operation: operation.operationName }, 'AZ-ID', 'Region'),
159
+ alarmStatistic: operation.canaryMetricDetails.canaryLatencyMetricDetails
160
+ .alarmStatistic,
161
+ datapointsToAlarm: operation.canaryMetricDetails.canaryLatencyMetricDetails
162
+ .datapointsToAlarm,
163
+ evaluationPeriods: operation.canaryMetricDetails.canaryLatencyMetricDetails
164
+ .evaluationPeriods,
165
+ faultAlarmThreshold: operation.canaryMetricDetails.canaryLatencyMetricDetails
166
+ .faultAlarmThreshold,
167
+ faultMetricNames: operation.canaryMetricDetails.canaryLatencyMetricDetails
168
+ .faultMetricNames,
169
+ graphedFaultStatistics: operation.canaryMetricDetails.canaryLatencyMetricDetails
170
+ .graphedFaultStatistics,
171
+ graphedSuccessStatistics: operation.canaryMetricDetails.canaryLatencyMetricDetails
172
+ .graphedSuccessStatistics,
173
+ metricNamespace: operation.canaryMetricDetails.canaryLatencyMetricDetails
174
+ .metricNamespace,
175
+ period: operation.canaryMetricDetails.canaryLatencyMetricDetails
176
+ .period,
177
+ successAlarmThreshold: operation.canaryMetricDetails.canaryLatencyMetricDetails
178
+ .successAlarmThreshold,
179
+ successMetricNames: operation.canaryMetricDetails.canaryLatencyMetricDetails
180
+ .successMetricNames,
181
+ unit: operation.canaryMetricDetails.canaryLatencyMetricDetails
182
+ .unit,
183
+ }, operation.service.defaultLatencyMetricDetails);
184
+ }
185
+ else if (operation.canaryTestLatencyMetricsOverride) {
186
+ defaultLatencyMetricDetails = new OperationMetricDetails_1.OperationMetricDetails({
187
+ operationName: operation.operationName,
188
+ metricNamespace: test.metricNamespace,
189
+ successMetricNames: ['SuccessLatency'],
190
+ faultMetricNames: ['FaultLatency'],
191
+ metricDimensions: new MetricDimensions_1.MetricDimensions({ Operation: operation.operationName }, 'AZ-ID', 'Region'),
192
+ alarmStatistic: operation.canaryTestLatencyMetricsOverride.alarmStatistic,
193
+ datapointsToAlarm: operation.canaryTestLatencyMetricsOverride.datapointsToAlarm,
194
+ evaluationPeriods: operation.canaryTestLatencyMetricsOverride.evaluationPeriods,
195
+ faultAlarmThreshold: operation.canaryTestLatencyMetricsOverride
196
+ .faultAlarmThreshold,
197
+ period: operation.canaryTestLatencyMetricsOverride.period,
198
+ successAlarmThreshold: operation.canaryTestLatencyMetricsOverride
199
+ .successAlarmThreshold,
200
+ }, props.service.defaultLatencyMetricDetails);
201
+ }
202
+ else {
203
+ defaultLatencyMetricDetails = new OperationMetricDetails_1.OperationMetricDetails({
204
+ operationName: operation.operationName,
205
+ metricNamespace: test.metricNamespace,
206
+ successMetricNames: ['SuccessLatency'],
207
+ faultMetricNames: ['FaultLatency'],
208
+ metricDimensions: new MetricDimensions_1.MetricDimensions({ Operation: operation.operationName }, 'AZ-ID', 'Region'),
209
+ }, props.service.defaultLatencyMetricDetails);
210
+ }
211
+ let newOperation = new Operation_1.Operation({
212
+ serverSideAvailabilityMetricDetails: operation.serverSideAvailabilityMetricDetails,
213
+ serverSideLatencyMetricDetails: operation.serverSideLatencyMetricDetails,
214
+ serverSideContributorInsightRuleDetails: operation.serverSideContributorInsightRuleDetails,
215
+ service: operation.service,
216
+ operationName: operation.operationName,
217
+ path: operation.path,
218
+ critical: operation.critical,
219
+ httpMethods: operation.httpMethods,
220
+ canaryMetricDetails: new CanaryMetrics_1.CanaryMetrics({
221
+ canaryAvailabilityMetricDetails: defaultAvailabilityMetricDetails,
222
+ canaryLatencyMetricDetails: defaultLatencyMetricDetails,
223
+ }),
224
+ });
225
+ props.service.operations[i] = newOperation;
226
+ }
227
+ }
228
+ }
229
+ if (props.outlierDetectionAlgorithm != OutlierDetectionAlgorithm_1.OutlierDetectionAlgorithm.STATIC) {
230
+ let outlierDetectionStack = new StackWithDynamicSource_1.StackWithDynamicSource(this, 'OutlierDetectionStack', {
231
+ assetsBucketsParameterName: props.assetsBucketParameterName,
232
+ assetsBucketPrefixParameterName: props.assetsBucketPrefixParameterName,
233
+ });
234
+ this.outlierDetectionFunction = new OutlierDetectionFunction_1.OutlierDetectionFunction(outlierDetectionStack, 'OutlierDetectionFunction', {}).function;
235
+ }
236
+ this.perOperationAlarmsAndRules = Object.fromEntries(props.service.operations.map((operation) => {
237
+ let nestedStack = new aws_cdk_lib_1.NestedStack(this, operation.operationName + 'OperationAlarmsAndRulesNestedStack');
238
+ return [
239
+ operation.operationName,
240
+ new OperationAlarmsAndRules_1.OperationAlarmsAndRules(nestedStack, operation.operationName, {
241
+ operation: operation,
242
+ outlierDetectionAlgorithm: props.outlierDetectionAlgorithm,
243
+ outlierThreshold: outlierThreshold,
244
+ loadBalancer: props.service.loadBalancer,
245
+ azMapper: this.azMapper,
246
+ outlierDetectionFunction: this.outlierDetectionFunction,
247
+ }),
248
+ ];
249
+ }));
250
+ this.perOperationZonalImpactAlarms = Object.fromEntries(Object.entries(this.perOperationAlarmsAndRules).map(([key, value]) => {
251
+ return [key, value.aggregateZonalAlarmsMap];
252
+ }));
253
+ let serviceAlarmsStack = new aws_cdk_lib_1.NestedStack(this, 'ServiceAlarmsNestedStack');
254
+ this.serviceAlarms = new ServiceAlarmsAndRules_1.ServiceAlarmsAndRules(serviceAlarmsStack, props.service.serviceName, {
255
+ perOperationAlarmsAndRules: this.perOperationAlarmsAndRules,
256
+ service: props.service,
257
+ azMapper: this.azMapper,
258
+ });
259
+ if (props.createDashboards) {
260
+ this.operationDashboards = [];
261
+ props.service.operations.forEach((x) => {
262
+ let dashboardStack = new aws_cdk_lib_1.NestedStack(this, x.operationName + 'Dashboard', {});
263
+ if (this.operationDashboards) {
264
+ this.operationDashboards.push(new OperationAvailabilityAndLatencyDashboard_1.OperationAvailabilityAndLatencyDashboard(dashboardStack, x.operationName, {
265
+ operation: x,
266
+ azMapper: this.azMapper,
267
+ interval: props.interval
268
+ ? props.interval
269
+ : aws_cdk_lib_1.Duration.minutes(60),
270
+ loadBalancer: props.service.loadBalancer,
271
+ regionalEndpointCanaryAvailabilityAlarm: this.perOperationAlarmsAndRules[x.operationName]
272
+ .canaryRegionalAlarmsAndRules?.availabilityAlarm,
273
+ regionalEndpointCanaryLatencyAlarm: this.perOperationAlarmsAndRules[x.operationName]
274
+ .canaryRegionalAlarmsAndRules?.latencyAlarm,
275
+ regionalEndpointServerAvailabilityAlarm: this.perOperationAlarmsAndRules[x.operationName]
276
+ .serverSideRegionalAlarmsAndRules.availabilityAlarm,
277
+ regionalEndpointServerLatencyAlarm: this.perOperationAlarmsAndRules[x.operationName]
278
+ .serverSideRegionalAlarmsAndRules.latencyAlarm,
279
+ zonalEndpointCanaryAvailabilityAlarms: this.perOperationAlarmsAndRules[x.operationName].canaryZonalAlarmsAndRules?.map((a) => a.availabilityAlarm),
280
+ zonalEndpointCanaryLatencyAlarms: this.perOperationAlarmsAndRules[x.operationName].canaryZonalAlarmsAndRules?.map((a) => a.latencyAlarm),
281
+ zonalEndpointServerAvailabilityAlarms: this.perOperationAlarmsAndRules[x.operationName].serverSideZonalAlarmsAndRules.map((a) => a.availabilityAlarm),
282
+ zonalEndpointServerLatencyAlarms: this.perOperationAlarmsAndRules[x.operationName].serverSideZonalAlarmsAndRules.map((a) => a.latencyAlarm),
283
+ isolatedAZImpactAlarms: this.perOperationAlarmsAndRules[x.operationName]
284
+ .aggregateZonalAlarms,
285
+ regionalImpactAlarm: this.perOperationAlarmsAndRules[x.operationName]
286
+ .aggregateRegionalAlarm,
287
+ instanceContributorsToFaults: this.perOperationAlarmsAndRules[x.operationName]
288
+ .serverSideRegionalAlarmsAndRules
289
+ .instanceContributorsToRegionalFaults,
290
+ instanceContributorsToHighLatency: this.perOperationAlarmsAndRules[x.operationName]
291
+ .serverSideRegionalAlarmsAndRules
292
+ .instanceContributorsToRegionalHighLatency,
293
+ }).dashboard);
294
+ }
295
+ });
296
+ let dashboardStack = new aws_cdk_lib_1.NestedStack(this, 'ServiceDashboard', {});
297
+ this.serviceDashboard = new ServiceAvailabilityAndLatencyDashboard_1.ServiceAvailabilityAndLatencyDashboard(dashboardStack, props.service.serviceName.toLowerCase(), {
298
+ interval: props.interval ? props.interval : aws_cdk_lib_1.Duration.minutes(60),
299
+ service: props.service,
300
+ aggregateRegionalAlarm: this.serviceAlarms.regionalFaultCountServerSideAlarm,
301
+ zonalAggregateAlarms: this.serviceAlarms.zonalAggregateIsolatedImpactAlarms,
302
+ azMapper: this.azMapper,
303
+ }).dashboard;
304
+ }
305
+ }
306
+ }
307
+ exports.InstrumentedServiceMultiAZObservability = InstrumentedServiceMultiAZObservability;
308
+ _a = JSII_RTTI_SYMBOL_1;
309
+ InstrumentedServiceMultiAZObservability[_a] = { fqn: "@cdklabs/multi-az-observability.InstrumentedServiceMultiAZObservability", version: "0.0.0-alpha.0" };
310
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5zdHJ1bWVudGVkU2VydmljZU11bHRpQVpPYnNlcnZhYmlsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL0luc3RydW1lbnRlZFNlcnZpY2VNdWx0aUFaT2JzZXJ2YWJpbGl0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHFFQUFxRTtBQUNyRSxzQ0FBc0M7QUFDdEMsNkNBQW9EO0FBSXBELDJDQUF1QztBQUN2QyxtREFBZ0Q7QUFJaEQsMkNBQXdDO0FBQ3hDLHFFQUFrRTtBQUVsRSwrREFBNEQ7QUFHNUQsdUZBQW9GO0FBQ3BGLG1GQUFnRjtBQUNoRiwrRUFBNEU7QUFDNUUsK0RBQTREO0FBQzVELHVEQUFvRDtBQUVwRCxxSEFBa0g7QUFDbEgsaUhBQThHO0FBQzlHLDRGQUF5RjtBQUN6RixzRkFBbUY7QUFDbkYsZ0ZBQTZFO0FBRTdFOzs7O0dBSUc7QUFDSCxNQUFhLHVDQUNYLFNBQVEsc0JBQVM7SUFtRGpCLFlBQ0UsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLEtBQW1EO1FBRW5ELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSxnQkFBd0IsQ0FBQztRQUU3QixJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDNUIsUUFBUSxLQUFLLENBQUMseUJBQXlCLEVBQUUsQ0FBQztnQkFDeEMsS0FBSyxxREFBeUIsQ0FBQyxXQUFXO29CQUN4QyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7b0JBQ3hCLE1BQU07Z0JBQ1IsS0FBSyxxREFBeUIsQ0FBQyxHQUFHO29CQUNoQyxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7b0JBQ3ZCLE1BQU07Z0JBQ1IsS0FBSyxxREFBeUIsQ0FBQyxHQUFHO29CQUNoQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7b0JBQ3JCLE1BQU07Z0JBQ1IsS0FBSyxxREFBeUIsQ0FBQyxNQUFNO29CQUNuQyxnQkFBZ0IsR0FBRyxH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QUMsQ0FBQyxDQUFDLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDaEUsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO2dCQUN0QixzQkFBc0IsRUFDcEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQ0FBaUM7Z0JBQ3RELG9CQUFvQixFQUNsQixJQUFJLENBQUMsYUFBYSxDQUFDLGtDQUFrQztnQkFDdkQsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2FBQ3hCLENBQ0YsQ0FBQyxTQUFTLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQzs7QUFwZ0JILDBGQXFnQkMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5pbXBvcnQgeyBEdXJhdGlvbiwgTmVzdGVkU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBEYXNoYm9hcmQsIElBbGFybSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCB7IElGdW5jdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgSUxvZ0dyb3VwIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBDYW5hcnlNZXRyaWNzIH0gZnJvbSAnLi9DYW5hcnlNZXRyaWNzJztcbmltcG9ydCB7IElJbnN0cnVtZW50ZWRTZXJ2aWNlTXVsdGlBWk9ic2VydmFiaWxpdHkgfSBmcm9tICcuL0lJbnN0cnVtZW50ZWRTZXJ2aWNlTXVsdGlBWk9ic2VydmFiaWxpdHknO1xuaW1wb3J0IHsgSU9wZXJhdGlvbiB9IGZyb20gJy4vSU9wZXJhdGlvbic7XG5pbXBvcnQgeyBJT3BlcmF0aW9uTWV0cmljRGV0YWlscyB9IGZyb20gJy4vSU9wZXJhdGlvbk1ldHJpY0RldGFpbHMnO1xuaW1wb3J0IHsgT3BlcmF0aW9uIH0gZnJvbSAnLi9PcGVyYXRpb24nO1xuaW1wb3J0IHsgT3BlcmF0aW9uTWV0cmljRGV0YWlscyB9IGZyb20gJy4vT3BlcmF0aW9uTWV0cmljRGV0YWlscyc7XG5pbXBvcnQgeyBJbnN0cnVtZW50ZWRTZXJ2aWNlTXVsdGlBWk9ic2VydmFiaWxpdHlQcm9wcyB9IGZyb20gJy4vcHJvcHMvSW5zdHJ1bWVudGVkU2VydmljZU11bHRpQVpPYnNlcnZhYmlsaXR5UHJvcHMnO1xuaW1wb3J0IHsgTWV0cmljRGltZW5zaW9ucyB9IGZyb20gJy4vcHJvcHMvTWV0cmljRGltZW5zaW9ucyc7XG5pbXBvcnQgeyBJT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXMgfSBmcm9tICcuLi9hbGFybXNhbmRydWxlcy9JT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXMnO1xuaW1wb3J0IHsgSVNlcnZpY2VBbGFybXNBbmRSdWxlcyB9IGZyb20gJy4uL2FsYXJtc2FuZHJ1bGVzL0lTZXJ2aWNlQWxhcm1zQW5kUnVsZXMnO1xuaW1wb3J0IHsgT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXMgfSBmcm9tICcuLi9hbGFybXNhbmRydWxlcy9PcGVyYXRpb25BbGFybXNBbmRSdWxlcyc7XG5pbXBvcnQgeyBTZXJ2aWNlQWxhcm1zQW5kUnVsZXMgfSBmcm9tICcuLi9hbGFybXNhbmRydWxlcy9TZXJ2aWNlQWxhcm1zQW5kUnVsZXMnO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5Wm9uZU1hcHBlciB9IGZyb20gJy4uL2F6bWFwcGVyL0F2YWlsYWJpbGl0eVpvbmVNYXBwZXInO1xuaW1wb3J0IHsgQ2FuYXJ5RnVuY3Rpb24gfSBmcm9tICcuLi9jYW5hcmllcy9DYW5hcnlGdW5jdGlvbic7XG5pbXBvcnQgeyBDYW5hcnlUZXN0IH0gZnJvbSAnLi4vY2FuYXJpZXMvQ2FuYXJ5VGVzdCc7XG5pbXBvcnQgeyBBZGRDYW5hcnlUZXN0UHJvcHMgfSBmcm9tICcuLi9jYW5hcmllcy9wcm9wcy9BZGRDYW5hcnlUZXN0UHJvcHMnO1xuaW1wb3J0IHsgT3BlcmF0aW9uQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZCB9IGZyb20gJy4uL2Rhc2hib2FyZHMvT3BlcmF0aW9uQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZCc7XG5pbXBvcnQgeyBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZCB9IGZyb20gJy4uL2Rhc2hib2FyZHMvU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQnO1xuaW1wb3J0IHsgT3V0bGllckRldGVjdGlvbkZ1bmN0aW9uIH0gZnJvbSAnLi4vb3V0bGllci1kZXRlY3Rpb24vT3V0bGllckRldGVjdGlvbkZ1bmN0aW9uJztcbmltcG9ydCB7IE91dGxpZXJEZXRlY3Rpb25BbGdvcml0aG0gfSBmcm9tICcuLi91dGlsaXRpZXMvT3V0bGllckRldGVjdGlvbkFsZ29yaXRobSc7XG5pbXBvcnQgeyBTdGFja1dpdGhEeW5hbWljU291cmNlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL1N0YWNrV2l0aER5bmFtaWNTb3VyY2UnO1xuXG4vKipcbiAqIEFuIHNlcnZpY2UgdGhhdCBpbXBsZW1lbnRzIGl0cyBvd24gaW5zdHJ1bWVudGF0aW9uIHRvIHJlY29yZFxuICogYXZhaWxhYmlsaXR5IGFuZCBsYXRlbmN5IG1ldHJpY3MgdGhhdCBjYW4gYmUgdXNlZCB0byBjcmVhdGVcbiAqIGFsYXJtcywgcnVsZXMsIGFuZCBkYXNoYm9hcmRzIGZyb21cbiAqL1xuZXhwb3J0IGNsYXNzIEluc3RydW1lbnRlZFNlcnZpY2VNdWx0aUFaT2JzZXJ2YWJpbGl0eVxuICBleHRlbmRzIENvbnN0cnVjdFxuICBpbXBsZW1lbnRzIElJbnN0cnVtZW50ZWRTZXJ2aWNlTXVsdGlBWk9ic2VydmFiaWxpdHkge1xuICAvKipcbiAgICogS2V5IHJlcHJlc2VudHMgdGhlIG9wZXJhdGlvbiBuYW1lIGFuZCB0aGUgdmFsdWUgaXMgdGhlIHNldFxuICAgKiBvZiB6b25hbCBhbGFybXMgYW5kIHJ1bGVzIGZvciB0aGF0IG9wZXJhdGlvbi4gVGhlIHZhbHVlcyB0aGVtc2VsdmVzXG4gICAqIGFyZSBkaWN0aW9uYXJpZXMgdGhhdCBoYXZlIGEga2V5IGZvciBlYWNoIEFaIElELlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwZXJPcGVyYXRpb25BbGFybXNBbmRSdWxlczoge1xuICAgIFtrZXk6IHN0cmluZ106IElPcGVyYXRpb25BbGFybXNBbmRSdWxlcztcbiAgfTtcblxuICAvKipcbiAgICogSW5kZXggaW50byB0aGUgZGljdGlvbmFyeSBieSBvcGVyYXRpb24gbmFtZSwgdGhlbiBieSBBdmFpbGFiaWxpdHkgWm9uZSBJZFxuICAgKiB0byBnZXQgdGhlIGFsYXJtcyB0aGF0IGluZGljYXRlIGFuIEFaIHNob3dzIGlzb2xhdGVkIGltcGFjdCBmcm9tIGF2YWlsYWJpbGl0eVxuICAgKiBvciBsYXRlbmN5IGFzIHNlZW4gYnkgZWl0aGVyIHRoZSBzZXJ2ZXItc2lkZSBvciBjYW5hcnkuIFRoZXNlIGFyZSB0aGUgYWxhcm1zXG4gICAqIHlvdSB3b3VsZCB3YW50IHRvIHVzZSB0byB0cmlnZ2VyIGF1dG9tYXRpb24gdG8gZXZhY3VhdGUgYW4gQVouXG4gICAqL1xuICByZWFkb25seSBwZXJPcGVyYXRpb25ab25hbEltcGFjdEFsYXJtczoge1xuICAgIFtrZXk6IHN0cmluZ106IHsgW2tleTogc3RyaW5nXTogSUFsYXJtIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIFRoZSBhbGFybXMgYW5kIHJ1bGVzIGZvciB0aGUgb3ZlcmFsbCBzZXJ2aWNlXG4gICAqL1xuICByZWFkb25seSBzZXJ2aWNlQWxhcm1zOiBJU2VydmljZUFsYXJtc0FuZFJ1bGVzO1xuXG4gIC8qKlxuICAgKiBUaGUgZGFzaGJvYXJkcyBmb3IgZWFjaCBvcGVyYXRpb25cbiAgICovXG4gIHJlYWRvbmx5IG9wZXJhdGlvbkRhc2hib2FyZHM/OiBEYXNoYm9hcmRbXTtcblxuICAvKipcbiAgICogVGhlIHNlcnZpY2UgbGV2ZWwgZGFzaGJvYXJkXG4gICAqL1xuICByZWFkb25seSBzZXJ2aWNlRGFzaGJvYXJkPzogRGFzaGJvYXJkO1xuXG4gIC8qKlxuICAgKiBUaGUgQVogbWFwcGVyIGN1c3RvbSByZXNvdXJjZSB1c2VkIHRvIG1hcCBBWiBJZHMgdG8gTmFtZXMgYW5kIHZpY2UgYSB2ZXJzYVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlcjtcblxuICAvKipcbiAgICogSWYgdGhlIHNlcnZpY2UgaXMgY29uZmlndXJlZCB0byBoYXZlIGNhbmFyeSB0ZXN0cyBjcmVhdGVkLCB0aGlzIHdpbGxcbiAgICogYmUgdGhlIGxvZyBncm91cCB3aGVyZSB0aGUgY2FuYXJ5J3MgbG9ncyBhcmUgc3RvcmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGxvZyBncm91cCBpcyBjcmVhdGVkIGlmIHRoZSBjYW5hcnkgaXMgbm90IHJlcXVlc3RlZC5cbiAgICovXG4gIHJlYWRvbmx5IGNhbmFyeUxvZ0dyb3VwPzogSUxvZ0dyb3VwO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgb3V0bGllckRldGVjdGlvbkZ1bmN0aW9uPzogSUZ1bmN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogSW5zdHJ1bWVudGVkU2VydmljZU11bHRpQVpPYnNlcnZhYmlsaXR5UHJvcHMsXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBsZXQgb3V0bGllclRocmVzaG9sZDogbnVtYmVyO1xuXG4gICAgaWYgKCFwcm9wcy5vdXRsaWVyVGhyZXNob2xkKSB7XG4gICAgICBzd2l0Y2ggKHByb3BzLm91dGxpZXJEZXRlY3Rpb25BbGdvcml0aG0pIHtcbiAgICAgICAgY2FzZSBPdXRsaWVyRGV0ZWN0aW9uQWxnb3JpdGhtLkNISV9TUVVBUkVEOlxuICAgICAgICAgIG91dGxpZXJUaHJlc2hvbGQgPSAwLjA1O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIE91dGxpZXJEZXRlY3Rpb25BbGdvcml0aG0uSVFSOlxuICAgICAgICAgIG91dGxpZXJUaHJlc2hvbGQgPSAxLjU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgT3V0bGllckRldGVjdGlvbkFsZ29yaXRobS5NQUQ6XG4gICAgICAgICAgb3V0bGllclRocmVzaG9sZCA9IDM7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgT3V0bGllckRldGVjdGlvbkFsZ29yaXRobS5TVEFUSUM6XG4gICAgICAgICAgb3V0bGllclRocmVzaG9sZCA9IDAuNztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBPdXRsaWVyRGV0ZWN0aW9uQWxnb3JpdGhtLlpfU0NPUkU6XG4gICAgICAgICAgb3V0bGllclRocmVzaG9sZCA9IDI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dGxpZXJUaHJlc2hvbGQgPSBwcm9wcy5vdXRsaWVyVGhyZXNob2xkO1xuICAgIH1cblxuICAgIHRoaXMuYXpNYXBwZXIgPSBuZXcgQXZhaWxhYmlsaXR5Wm9uZU1hcHBlcih0aGlzLCAnQVpNYXBwZXInLCB7XG4gICAgICBhdmFpbGFiaWxpdHlab25lTmFtZXM6IHByb3BzLnNlcnZpY2UuYXZhaWxhYmlsaXR5Wm9uZU5hbWVzLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLnNlcnZpY2UuY2FuYXJ5VGVzdFByb3BzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGxldCBjYW5hcnlTdGFjazogU3RhY2tXaXRoRHluYW1pY1NvdXJjZSA9IG5ldyBTdGFja1dpdGhEeW5hbWljU291cmNlKFxuICAgICAgICB0aGlzLFxuICAgICAgICAnQ2FuYXJ5JyxcbiAgICAgICAge1xuICAgICAgICAgIGFzc2V0c0J1Y2tldHNQYXJhbWV0ZXJOYW1lOiBwcm9wcy5hc3NldHNCdWNrZXRQYXJhbWV0ZXJOYW1lLFxuICAgICAgICAgIGFzc2V0c0J1Y2tldFByZWZpeFBhcmFtZXRlck5hbWU6XG4gICAgICAgICAgICBwcm9wcy5hc3NldHNCdWNrZXRQcmVmaXhQYXJhbWV0ZXJOYW1lLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgbGV0IGNhbmFyeSA9IG5ldyBDYW5hcnlGdW5jdGlvbihjYW5hcnlTdGFjaywgJ0NhbmFyeUZ1bmN0aW9uJywge1xuICAgICAgICB2cGM6IHByb3BzLnNlcnZpY2UuY2FuYXJ5VGVzdFByb3BzLm5ldHdvcmtDb25maWd1cmF0aW9uPy52cGMsXG4gICAgICAgIHN1Ym5ldFNlbGVjdGlvbjpcbiAgICAgICAgICBwcm9wcy5zZXJ2aWNlLmNhbmFyeVRlc3RQcm9wcy5uZXR3b3JrQ29uZmlndXJhdGlvbj8uc3VibmV0U2VsZWN0aW9uLFxuICAgICAgICBodHRwVGltZW91dDogcHJvcHMuc2VydmljZS5jYW5hcnlUZXN0UHJvcHMudGltZW91dFxuICAgICAgICAgID8gcHJvcHMuc2VydmljZS5jYW5hcnlUZXN0UHJvcHMudGltZW91dFxuICAgICAgICAgIDogRHVyYXRpb24uc2Vjb25kcygyKSxcbiAgICAgICAgaWdub3JlVGxzRXJyb3JzOiBwcm9wcy5zZXJ2aWNlLmNhbmFyeVRlc3RQcm9wcy5pZ25vcmVUbHNFcnJvcnNcbiAgICAgICAgICA/IHByb3BzLnNlcnZpY2UuY2FuYXJ5VGVzdFByb3BzLmlnbm9yZVRsc0Vycm9yc1xuICAgICAgICAgIDogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5jYW5hcnlMb2dHcm91cCA9IGNhbmFyeS5sb2dHcm91cDtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9wcy5zZXJ2aWNlLm9wZXJhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IG9wZXJhdGlvbjogSU9wZXJhdGlvbiA9IHByb3BzLnNlcnZpY2Uub3BlcmF0aW9uc1tpXTtcblxuICAgICAgICBpZiAob3BlcmF0aW9uLm9wdE91dE9mU2VydmljZUNyZWF0ZWRDYW5hcnkgIT0gdHJ1ZSkge1xuICAgICAgICAgIGxldCB0ZXN0UHJvcHM6IEFkZENhbmFyeVRlc3RQcm9wcyA9IG9wZXJhdGlvbi5jYW5hcnlUZXN0UHJvcHNcbiAgICAgICAgICAgID8gb3BlcmF0aW9uLmNhbmFyeVRlc3RQcm9wc1xuICAgICAgICAgICAgOiAocHJvcHMuc2VydmljZS5jYW5hcnlUZXN0UHJvcHMgYXMgQWRkQ2FuYXJ5VGVzdFByb3BzKTtcblxuICAgICAgICAgIGxldCBuZXN0ZWRTdGFjazogTmVzdGVkU3RhY2sgPSBuZXcgTmVzdGVkU3RhY2soXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgb3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUgKyAnQ2FuYXJ5VGVzdCcsXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgbGV0IHRlc3QgPSBuZXcgQ2FuYXJ5VGVzdChuZXN0ZWRTdGFjaywgb3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUsIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uOiBjYW5hcnkuZnVuY3Rpb24sXG4gICAgICAgICAgICByZXF1ZXN0Q291bnQ6IHRlc3RQcm9wcy5yZXF1ZXN0Q291bnQsXG4gICAgICAgICAgICByZWdpb25hbFJlcXVlc3RDb3VudDogdGVzdFByb3BzLnJlZ2lvbmFsUmVxdWVzdENvdW50XG4gICAgICAgICAgICAgID8gdGVzdFByb3BzLnJlZ2lvbmFsUmVxdWVzdENvdW50XG4gICAgICAgICAgICAgIDogdGVzdFByb3BzLnJlcXVlc3RDb3VudCxcbiAgICAgICAgICAgIHNjaGVkdWxlOiB0ZXN0UHJvcHMuc2NoZWR1bGUsXG4gICAgICAgICAgICBvcGVyYXRpb246IG9wZXJhdGlvbixcbiAgICAgICAgICAgIGxvYWRCYWxhbmNlcjogdGVzdFByb3BzLmxvYWRCYWxhbmNlcixcbiAgICAgICAgICAgIGhlYWRlcnM6IHRlc3RQcm9wcy5oZWFkZXJzLFxuICAgICAgICAgICAgcG9zdERhdGE6IHRlc3RQcm9wcy5wb3N0RGF0YSxcbiAgICAgICAgICAgIGF6TWFwcGVyOiB0aGlzLmF6TWFwcGVyLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgbGV0IGRlZmF1bHRBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzOiBJT3BlcmF0aW9uTWV0cmljRGV0YWlscztcbiAgICAgICAgICBsZXQgZGVmYXVsdExhdGVuY3lNZXRyaWNEZXRhaWxzOiBJT3BlcmF0aW9uTWV0cmljRGV0YWlscztcblxuICAgICAgICAgIGlmIChvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscz8uY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscykge1xuICAgICAgICAgICAgZGVmYXVsdEF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMgPSBuZXcgT3BlcmF0aW9uTWV0cmljRGV0YWlscyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lLFxuICAgICAgICAgICAgICAgIG1ldHJpY0RpbWVuc2lvbnM6IG5ldyBNZXRyaWNEaW1lbnNpb25zKFxuICAgICAgICAgICAgICAgICAgeyBPcGVyYXRpb246IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lIH0sXG4gICAgICAgICAgICAgICAgICAnQVotSUQnLFxuICAgICAgICAgICAgICAgICAgJ1JlZ2lvbicsXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBhbGFybVN0YXRpc3RpYzpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHNcbiAgICAgICAgICAgICAgICAgICAgLmFsYXJtU3RhdGlzdGljLFxuICAgICAgICAgICAgICAgIGRhdGFwb2ludHNUb0FsYXJtOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICAgICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6XG4gICAgICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscy5jYW5hcnlBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5ldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgICAgICBmYXVsdEFsYXJtVGhyZXNob2xkOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuZmF1bHRBbGFybVRocmVzaG9sZCxcbiAgICAgICAgICAgICAgICBmYXVsdE1ldHJpY05hbWVzOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuZmF1bHRNZXRyaWNOYW1lcyxcbiAgICAgICAgICAgICAgICBncmFwaGVkRmF1bHRTdGF0aXN0aWNzOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuZ3JhcGhlZEZhdWx0U3RhdGlzdGljcyxcbiAgICAgICAgICAgICAgICBncmFwaGVkU3VjY2Vzc1N0YXRpc3RpY3M6XG4gICAgICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscy5jYW5hcnlBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5ncmFwaGVkU3VjY2Vzc1N0YXRpc3RpY3MsXG4gICAgICAgICAgICAgICAgbWV0cmljTmFtZXNwYWNlOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAubWV0cmljTmFtZXNwYWNlLFxuICAgICAgICAgICAgICAgIHBlcmlvZDpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHNcbiAgICAgICAgICAgICAgICAgICAgLnBlcmlvZCxcbiAgICAgICAgICAgICAgICBzdWNjZXNzQWxhcm1UaHJlc2hvbGQ6XG4gICAgICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscy5jYW5hcnlBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5zdWNjZXNzQWxhcm1UaHJlc2hvbGQsXG4gICAgICAgICAgICAgICAgc3VjY2Vzc01ldHJpY05hbWVzOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuc3VjY2Vzc01ldHJpY05hbWVzLFxuICAgICAgICAgICAgICAgIHVuaXQ6IG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscy51bml0LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBvcGVyYXRpb24uc2VydmljZS5kZWZhdWx0QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24uY2FuYXJ5VGVzdEF2YWlsYWJpbGl0eU1ldHJpY3NPdmVycmlkZSkge1xuICAgICAgICAgICAgZGVmYXVsdEF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMgPSBuZXcgT3BlcmF0aW9uTWV0cmljRGV0YWlscyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lLFxuICAgICAgICAgICAgICAgIG1ldHJpY05hbWVzcGFjZTogdGVzdC5tZXRyaWNOYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgc3VjY2Vzc01ldHJpY05hbWVzOiBbJ1N1Y2Nlc3MnXSxcbiAgICAgICAgICAgICAgICBmYXVsdE1ldHJpY05hbWVzOiBbJ0ZhdWx0JywgJ0ZhaWx1cmUnXSxcbiAgICAgICAgICAgICAgICBtZXRyaWNEaW1lbnNpb25zOiBuZXcgTWV0cmljRGltZW5zaW9ucyhcbiAgICAgICAgICAgICAgICAgIHsgT3BlcmF0aW9uOiBvcGVyYXRpb24ub3BlcmF0aW9uTmFtZSB9LFxuICAgICAgICAgICAgICAgICAgJ0FaLUlEJyxcbiAgICAgICAgICAgICAgICAgICdSZWdpb24nLFxuICAgICAgICAgICAgICAgICksXG5cbiAgICAgICAgICAgICAgICBhbGFybVN0YXRpc3RpYzpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlUZXN0QXZhaWxhYmlsaXR5TWV0cmljc092ZXJyaWRlXG4gICAgICAgICAgICAgICAgICAgIC5hbGFybVN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlUZXN0QXZhaWxhYmlsaXR5TWV0cmljc092ZXJyaWRlXG4gICAgICAgICAgICAgICAgICAgIC5kYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgICAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlUZXN0QXZhaWxhYmlsaXR5TWV0cmljc092ZXJyaWRlXG4gICAgICAgICAgICAgICAgICAgIC5ldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgICAgICBmYXVsdEFsYXJtVGhyZXNob2xkOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeVRlc3RBdmFpbGFiaWxpdHlNZXRyaWNzT3ZlcnJpZGVcbiAgICAgICAgICAgICAgICAgICAgLmZhdWx0QWxhcm1UaHJlc2hvbGQsXG4gICAgICAgICAgICAgICAgcGVyaW9kOiBvcGVyYXRpb24uY2FuYXJ5VGVzdEF2YWlsYWJpbGl0eU1ldHJpY3NPdmVycmlkZS5wZXJpb2QsXG4gICAgICAgICAgICAgICAgc3VjY2Vzc0FsYXJtVGhyZXNob2xkOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeVRlc3RBdmFpbGFiaWxpdHlNZXRyaWNzT3ZlcnJpZGVcbiAgICAgICAgICAgICAgICAgICAgLnN1Y2Nlc3NBbGFybVRocmVzaG9sZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcHJvcHMuc2VydmljZS5kZWZhdWx0QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlZmF1bHRBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzID0gbmV3IE9wZXJhdGlvbk1ldHJpY0RldGFpbHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb25OYW1lOiBvcGVyYXRpb24ub3BlcmF0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICBtZXRyaWNOYW1lc3BhY2U6IHRlc3QubWV0cmljTmFtZXNwYWNlLFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3NNZXRyaWNOYW1lczogWydTdWNjZXNzJ10sXG4gICAgICAgICAgICAgICAgZmF1bHRNZXRyaWNOYW1lczogWydGYXVsdCcsICdGYWlsdXJlJ10sXG4gICAgICAgICAgICAgICAgbWV0cmljRGltZW5zaW9uczogbmV3IE1ldHJpY0RpbWVuc2lvbnMoXG4gICAgICAgICAgICAgICAgICB7IE9wZXJhdGlvbjogb3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUgfSxcbiAgICAgICAgICAgICAgICAgICdBWi1JRCcsXG4gICAgICAgICAgICAgICAgICAnUmVnaW9uJyxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBwcm9wcy5zZXJ2aWNlLmRlZmF1bHRBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAob3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHM/LmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzKSB7XG4gICAgICAgICAgICBkZWZhdWx0TGF0ZW5jeU1ldHJpY0RldGFpbHMgPSBuZXcgT3BlcmF0aW9uTWV0cmljRGV0YWlscyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lLFxuICAgICAgICAgICAgICAgIG1ldHJpY0RpbWVuc2lvbnM6IG5ldyBNZXRyaWNEaW1lbnNpb25zKFxuICAgICAgICAgICAgICAgICAgeyBPcGVyYXRpb246IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lIH0sXG4gICAgICAgICAgICAgICAgICAnQVotSUQnLFxuICAgICAgICAgICAgICAgICAgJ1JlZ2lvbicsXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBhbGFybVN0YXRpc3RpYzpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5hbGFybVN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5kYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgICAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5ldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgICAgICBmYXVsdEFsYXJtVGhyZXNob2xkOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHNcbiAgICAgICAgICAgICAgICAgICAgLmZhdWx0QWxhcm1UaHJlc2hvbGQsXG4gICAgICAgICAgICAgICAgZmF1bHRNZXRyaWNOYW1lczpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5mYXVsdE1ldHJpY05hbWVzLFxuICAgICAgICAgICAgICAgIGdyYXBoZWRGYXVsdFN0YXRpc3RpY3M6XG4gICAgICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscy5jYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuZ3JhcGhlZEZhdWx0U3RhdGlzdGljcyxcbiAgICAgICAgICAgICAgICBncmFwaGVkU3VjY2Vzc1N0YXRpc3RpY3M6XG4gICAgICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscy5jYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuZ3JhcGhlZFN1Y2Nlc3NTdGF0aXN0aWNzLFxuICAgICAgICAgICAgICAgIG1ldHJpY05hbWVzcGFjZTpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5tZXRyaWNOYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgcGVyaW9kOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHNcbiAgICAgICAgICAgICAgICAgICAgLnBlcmlvZCxcbiAgICAgICAgICAgICAgICBzdWNjZXNzQWxhcm1UaHJlc2hvbGQ6XG4gICAgICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscy5jYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlsc1xuICAgICAgICAgICAgICAgICAgICAuc3VjY2Vzc0FsYXJtVGhyZXNob2xkLFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3NNZXRyaWNOYW1lczpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgIC5zdWNjZXNzTWV0cmljTmFtZXMsXG4gICAgICAgICAgICAgICAgdW5pdDogb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHNcbiAgICAgICAgICAgICAgICAgIC51bml0LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBvcGVyYXRpb24uc2VydmljZS5kZWZhdWx0TGF0ZW5jeU1ldHJpY0RldGFpbHMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uLmNhbmFyeVRlc3RMYXRlbmN5TWV0cmljc092ZXJyaWRlKSB7XG4gICAgICAgICAgICBkZWZhdWx0TGF0ZW5jeU1ldHJpY0RldGFpbHMgPSBuZXcgT3BlcmF0aW9uTWV0cmljRGV0YWlscyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lLFxuICAgICAgICAgICAgICAgIG1ldHJpY05hbWVzcGFjZTogdGVzdC5tZXRyaWNOYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgc3VjY2Vzc01ldHJpY05hbWVzOiBbJ1N1Y2Nlc3NMYXRlbmN5J10sXG4gICAgICAgICAgICAgICAgZmF1bHRNZXRyaWNOYW1lczogWydGYXVsdExhdGVuY3knXSxcbiAgICAgICAgICAgICAgICBtZXRyaWNEaW1lbnNpb25zOiBuZXcgTWV0cmljRGltZW5zaW9ucyhcbiAgICAgICAgICAgICAgICAgIHsgT3BlcmF0aW9uOiBvcGVyYXRpb24ub3BlcmF0aW9uTmFtZSB9LFxuICAgICAgICAgICAgICAgICAgJ0FaLUlEJyxcbiAgICAgICAgICAgICAgICAgICdSZWdpb24nLFxuICAgICAgICAgICAgICAgICksXG5cbiAgICAgICAgICAgICAgICBhbGFybVN0YXRpc3RpYzpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlUZXN0TGF0ZW5jeU1ldHJpY3NPdmVycmlkZS5hbGFybVN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlUZXN0TGF0ZW5jeU1ldHJpY3NPdmVycmlkZS5kYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgICAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczpcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5jYW5hcnlUZXN0TGF0ZW5jeU1ldHJpY3NPdmVycmlkZS5ldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgICAgICBmYXVsdEFsYXJtVGhyZXNob2xkOlxuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLmNhbmFyeVRlc3RMYXRlbmN5TWV0cmljc092ZXJyaWRlXG4gICAgICAgICAgICAgICAgICAgIC5mYXVsdEFsYXJtVGhyZXNob2xkLFxuICAgICAgICAgICAgICAgIHBlcmlvZDogb3BlcmF0aW9uLmNhbmFyeVRlc3RMYXRlbmN5TWV0cmljc092ZXJyaWRlLnBlcmlvZCxcbiAgICAgICAgICAgICAgICBzdWNjZXNzQWxhcm1UaHJlc2hvbGQ6XG4gICAgICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5VGVzdExhdGVuY3lNZXRyaWNzT3ZlcnJpZGVcbiAgICAgICAgICAgICAgICAgICAgLnN1Y2Nlc3NBbGFybVRocmVzaG9sZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcHJvcHMuc2VydmljZS5kZWZhdWx0TGF0ZW5jeU1ldHJpY0RldGFpbHMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWZhdWx0TGF0ZW5jeU1ldHJpY0RldGFpbHMgPSBuZXcgT3BlcmF0aW9uTWV0cmljRGV0YWlscyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lLFxuICAgICAgICAgICAgICAgIG1ldHJpY05hbWVzcGFjZTogdGVzdC5tZXRyaWNOYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgc3VjY2Vzc01ldHJpY05hbWVzOiBbJ1N1Y2Nlc3NMYXRlbmN5J10sXG4gICAgICAgICAgICAgICAgZmF1bHRNZXRyaWNOYW1lczogWydGYXVsdExhdGVuY3knXSxcbiAgICAgICAgICAgICAgICBtZXRyaWNEaW1lbnNpb25zOiBuZXcgTWV0cmljRGltZW5zaW9ucyhcbiAgICAgICAgICAgICAgICAgIHsgT3BlcmF0aW9uOiBvcGVyYXRpb24ub3BlcmF0aW9uTmFtZSB9LFxuICAgICAgICAgICAgICAgICAgJ0FaLUlEJyxcbiAgICAgICAgICAgICAgICAgICdSZWdpb24nLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHByb3BzLnNlcnZpY2UuZGVmYXVsdExhdGVuY3lNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgbmV3T3BlcmF0aW9uID0gbmV3IE9wZXJhdGlvbih7XG4gICAgICAgICAgICBzZXJ2ZXJTaWRlQXZhaWxhYmlsaXR5TWV0cmljRGV0YWlsczpcbiAgICAgICAgICAgICAgb3BlcmF0aW9uLnNlcnZlclNpZGVBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgc2VydmVyU2lkZUxhdGVuY3lNZXRyaWNEZXRhaWxzOlxuICAgICAgICAgICAgICBvcGVyYXRpb24uc2VydmVyU2lkZUxhdGVuY3lNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgc2VydmVyU2lkZUNvbnRyaWJ1dG9ySW5zaWdodFJ1bGVEZXRhaWxzOlxuICAgICAgICAgICAgICBvcGVyYXRpb24uc2VydmVyU2lkZUNvbnRyaWJ1dG9ySW5zaWdodFJ1bGVEZXRhaWxzLFxuICAgICAgICAgICAgc2VydmljZTogb3BlcmF0aW9uLnNlcnZpY2UsXG4gICAgICAgICAgICBvcGVyYXRpb25OYW1lOiBvcGVyYXRpb24ub3BlcmF0aW9uTmFtZSxcbiAgICAgICAgICAgIHBhdGg6IG9wZXJhdGlvbi5wYXRoLFxuICAgICAgICAgICAgY3JpdGljYWw6IG9wZXJhdGlvbi5jcml0aWNhbCxcbiAgICAgICAgICAgIGh0dHBNZXRob2RzOiBvcGVyYXRpb24uaHR0cE1ldGhvZHMsXG4gICAgICAgICAgICBjYW5hcnlNZXRyaWNEZXRhaWxzOiBuZXcgQ2FuYXJ5TWV0cmljcyh7XG4gICAgICAgICAgICAgIGNhbmFyeUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHM6IGRlZmF1bHRBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgICBjYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlsczogZGVmYXVsdExhdGVuY3lNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBwcm9wcy5zZXJ2aWNlLm9wZXJhdGlvbnNbaV0gPSBuZXdPcGVyYXRpb247XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvcHMub3V0bGllckRldGVjdGlvbkFsZ29yaXRobSAhPSBPdXRsaWVyRGV0ZWN0aW9uQWxnb3JpdGhtLlNUQVRJQykge1xuICAgICAgbGV0IG91dGxpZXJEZXRlY3Rpb25TdGFjazogU3RhY2tXaXRoRHluYW1pY1NvdXJjZSA9XG4gICAgICAgIG5ldyBTdGFja1dpdGhEeW5hbWljU291cmNlKHRoaXMsICdPdXRsaWVyRGV0ZWN0aW9uU3RhY2snLCB7XG4gICAgICAgICAgYXNzZXRzQnVja2V0c1BhcmFtZXRlck5hbWU6IHByb3BzLmFzc2V0c0J1Y2tldFBhcmFtZXRlck5hbWUsXG4gICAgICAgICAgYXNzZXRzQnVja2V0UHJlZml4UGFyYW1ldGVyTmFtZTpcbiAgICAgICAgICAgIHByb3BzLmFzc2V0c0J1Y2tldFByZWZpeFBhcmFtZXRlck5hbWUsXG4gICAgICAgIH0pO1xuXG4gICAgICB0aGlzLm91dGxpZXJEZXRlY3Rpb25GdW5jdGlvbiA9IG5ldyBPdXRsaWVyRGV0ZWN0aW9uRnVuY3Rpb24oXG4gICAgICAgIG91dGxpZXJEZXRlY3Rpb25TdGFjayxcbiAgICAgICAgJ091dGxpZXJEZXRlY3Rpb25GdW5jdGlvbicsXG4gICAgICAgIHt9LFxuICAgICAgKS5mdW5jdGlvbjtcbiAgICB9XG5cbiAgICB0aGlzLnBlck9wZXJhdGlvbkFsYXJtc0FuZFJ1bGVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLm1hcCgob3BlcmF0aW9uOiBJT3BlcmF0aW9uKSA9PiB7XG4gICAgICAgIGxldCBuZXN0ZWRTdGFjazogTmVzdGVkU3RhY2sgPSBuZXcgTmVzdGVkU3RhY2soXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBvcGVyYXRpb24ub3BlcmF0aW9uTmFtZSArICdPcGVyYXRpb25BbGFybXNBbmRSdWxlc05lc3RlZFN0YWNrJyxcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lLFxuICAgICAgICAgIG5ldyBPcGVyYXRpb25BbGFybXNBbmRSdWxlcyhuZXN0ZWRTdGFjaywgb3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogb3BlcmF0aW9uLFxuICAgICAgICAgICAgb3V0bGllckRldGVjdGlvbkFsZ29yaXRobTogcHJvcHMub3V0bGllckRldGVjdGlvbkFsZ29yaXRobSxcbiAgICAgICAgICAgIG91dGxpZXJUaHJlc2hvbGQ6IG91dGxpZXJUaHJlc2hvbGQsXG4gICAgICAgICAgICBsb2FkQmFsYW5jZXI6IHByb3BzLnNlcnZpY2UubG9hZEJhbGFuY2VyLFxuICAgICAgICAgICAgYXpNYXBwZXI6IHRoaXMuYXpNYXBwZXIsXG4gICAgICAgICAgICBvdXRsaWVyRGV0ZWN0aW9uRnVuY3Rpb246IHRoaXMub3V0bGllckRldGVjdGlvbkZ1bmN0aW9uLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdO1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIHRoaXMucGVyT3BlcmF0aW9uWm9uYWxJbXBhY3RBbGFybXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLnBlck9wZXJhdGlvbkFsYXJtc0FuZFJ1bGVzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICByZXR1cm4gW2tleSwgdmFsdWUuYWdncmVnYXRlWm9uYWxBbGFybXNNYXBdO1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIGxldCBzZXJ2aWNlQWxhcm1zU3RhY2s6IE5lc3RlZFN0YWNrID0gbmV3IE5lc3RlZFN0YWNrKFxuICAgICAgdGhpcyxcbiAgICAgICdTZXJ2aWNlQWxhcm1zTmVzdGVkU3RhY2snLFxuICAgICk7XG5cbiAgICB0aGlzLnNlcnZpY2VBbGFybXMgPSBuZXcgU2VydmljZUFsYXJtc0FuZFJ1bGVzKFxuICAgICAgc2VydmljZUFsYXJtc1N0YWNrLFxuICAgICAgcHJvcHMuc2VydmljZS5zZXJ2aWNlTmFtZSxcbiAgICAgIHtcbiAgICAgICAgcGVyT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXM6IHRoaXMucGVyT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXMsXG4gICAgICAgIHNlcnZpY2U6IHByb3BzLnNlcnZpY2UsXG4gICAgICAgIGF6TWFwcGVyOiB0aGlzLmF6TWFwcGVyLFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgaWYgKHByb3BzLmNyZWF0ZURhc2hib2FyZHMpIHtcbiAgICAgIHRoaXMub3BlcmF0aW9uRGFzaGJvYXJkcyA9IFtdO1xuXG4gICAgICBwcm9wcy5zZXJ2aWNlLm9wZXJhdGlvbnMuZm9yRWFjaCgoeCkgPT4ge1xuICAgICAgICBsZXQgZGFzaGJvYXJkU3RhY2s6IE5lc3RlZFN0YWNrID0gbmV3IE5lc3RlZFN0YWNrKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgeC5vcGVyYXRpb25OYW1lICsgJ0Rhc2hib2FyZCcsXG4gICAgICAgICAge30sXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHRoaXMub3BlcmF0aW9uRGFzaGJvYXJkcykge1xuICAgICAgICAgIHRoaXMub3BlcmF0aW9uRGFzaGJvYXJkcy5wdXNoKFxuICAgICAgICAgICAgbmV3IE9wZXJhdGlvbkF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQoXG4gICAgICAgICAgICAgIGRhc2hib2FyZFN0YWNrLFxuICAgICAgICAgICAgICB4Lm9wZXJhdGlvbk5hbWUsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb246IHgsXG4gICAgICAgICAgICAgICAgYXpNYXBwZXI6IHRoaXMuYXpNYXBwZXIsXG4gICAgICAgICAgICAgICAgaW50ZXJ2YWw6IHByb3BzLmludGVydmFsXG4gICAgICAgICAgICAgICAgICA/IHByb3BzLmludGVydmFsXG4gICAgICAgICAgICAgICAgICA6IER1cmF0aW9uLm1pbnV0ZXMoNjApLFxuICAgICAgICAgICAgICAgIGxvYWRCYWxhbmNlcjogcHJvcHMuc2VydmljZS5sb2FkQmFsYW5jZXIsXG5cbiAgICAgICAgICAgICAgICByZWdpb25hbEVuZHBvaW50Q2FuYXJ5QXZhaWxhYmlsaXR5QWxhcm06XG4gICAgICAgICAgICAgICAgICB0aGlzLnBlck9wZXJhdGlvbkFsYXJtc0FuZFJ1bGVzW3gub3BlcmF0aW9uTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgLmNhbmFyeVJlZ2lvbmFsQWxhcm1zQW5kUnVsZXM/LmF2YWlsYWJpbGl0eUFsYXJtLFxuXG4gICAgICAgICAgICAgICAgcmVnaW9uYWxFbmRwb2ludENhbmFyeUxhdGVuY3lBbGFybTpcbiAgICAgICAgICAgICAgICAgIHRoaXMucGVyT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXNbeC5vcGVyYXRpb25OYW1lXVxuICAgICAgICAgICAgICAgICAgICAuY2FuYXJ5UmVnaW9uYWxBbGFybXNBbmRSdWxlcz8ubGF0ZW5jeUFsYXJtLFxuXG4gICAgICAgICAgICAgICAgcmVnaW9uYWxFbmRwb2ludFNlcnZlckF2YWlsYWJpbGl0eUFsYXJtOlxuICAgICAgICAgICAgICAgICAgdGhpcy5wZXJPcGVyYXRpb25BbGFybXNBbmRSdWxlc1t4Lm9wZXJhdGlvbk5hbWVdXG4gICAgICAgICAgICAgICAgICAgIC5zZXJ2ZXJTaWRlUmVnaW9uYWxBbGFybXNBbmRSdWxlcy5hdmFpbGFiaWxpdHlBbGFybSxcblxuICAgICAgICAgICAgICAgIHJlZ2lvbmFsRW5kcG9pbnRTZXJ2ZXJMYXRlbmN5QWxhcm06XG4gICAgICAgICAgICAgICAgICB0aGlzLnBlck9wZXJhdGlvbkFsYXJtc0FuZFJ1bGVzW3gub3BlcmF0aW9uTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgLnNlcnZlclNpZGVSZWdpb25hbEFsYXJtc0FuZFJ1bGVzLmxhdGVuY3lBbGFybSxcblxuICAgICAgICAgICAgICAgIHpvbmFsRW5kcG9pbnRDYW5hcnlBdmFpbGFiaWxpdHlBbGFybXM6XG4gICAgICAgICAgICAgICAgICB0aGlzLnBlck9wZXJhdGlvbkFsYXJtc0FuZFJ1bGVzW1xuICAgICAgICAgICAgICAgICAgICB4Lm9wZXJhdGlvbk5hbWVcbiAgICAgICAgICAgICAgICAgIF0uY2FuYXJ5Wm9uYWxBbGFybXNBbmRSdWxlcz8ubWFwKChhKSA9PiBhLmF2YWlsYWJpbGl0eUFsYXJtKSxcblxuICAgICAgICAgICAgICAgIHpvbmFsRW5kcG9pbnRDYW5hcnlMYXRlbmN5QWxhcm1zOlxuICAgICAgICAgICAgICAgICAgdGhpcy5wZXJPcGVyYXRpb25BbGFybXNBbmRSdWxlc1tcbiAgICAgICAgICAgICAgICAgICAgeC5vcGVyYXRpb25OYW1lXG4gICAgICAgICAgICAgICAgICBdLmNhbmFyeVpvbmFsQWxhcm1zQW5kUnVsZXM/Lm1hcCgoYSkgPT4gYS5sYXRlbmN5QWxhcm0pLFxuXG4gICAgICAgICAgICAgICAgem9uYWxFbmRwb2ludFNlcnZlckF2YWlsYWJpbGl0eUFsYXJtczpcbiAgICAgICAgICAgICAgICAgIHRoaXMucGVyT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXNbXG4gICAgICAgICAgICAgICAgICAgIHgub3BlcmF0aW9uTmFtZVxuICAgICAgICAgICAgICAgICAgXS5zZXJ2ZXJTaWRlWm9uYWxBbGFybXNBbmRSdWxlcy5tYXAoXG4gICAgICAgICAgICAgICAgICAgIChhKSA9PiBhLmF2YWlsYWJpbGl0eUFsYXJtLFxuICAgICAgICAgICAgICAgICAgKSxcblxuICAgICAgICAgICAgICAgIHpvbmFsRW5kcG9pbnRTZXJ2ZXJMYXRlbmN5QWxhcm1zOlxuICAgICAgICAgICAgICAgICAgdGhpcy5wZXJPcGVyYXRpb25BbGFybXNBbmRSdWxlc1tcbiAgICAgICAgICAgICAgICAgICAgeC5vcGVyYXRpb25OYW1lXG4gICAgICAgICAgICAgICAgICBdLnNlcnZlclNpZGVab25hbEFsYXJtc0FuZFJ1bGVzLm1hcCgoYSkgPT4gYS5sYXRlbmN5QWxhcm0pLFxuXG4gICAgICAgICAgICAgICAgaXNvbGF0ZWRBWkltcGFjdEFsYXJtczpcbiAgICAgICAgICAgICAgICAgIHRoaXMucGVyT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXNbeC5vcGVyYXRpb25OYW1lXVxuICAgICAgICAgICAgICAgICAgICAuYWdncmVnYXRlWm9uYWxBbGFybXMsXG5cbiAgICAgICAgICAgICAgICByZWdpb25hbEltcGFjdEFsYXJtOlxuICAgICAgICAgICAgICAgICAgdGhpcy5wZXJPcGVyYXRpb25BbGFybXNBbmRSdWxlc1t4Lm9wZXJhdGlvbk5hbWVdXG4gICAgICAgICAgICAgICAgICAgIC5hZ2dyZWdhdGVSZWdpb25hbEFsYXJtLFxuXG4gICAgICAgICAgICAgICAgaW5zdGFuY2VDb250cmlidXRvcnNUb0ZhdWx0czpcbiAgICAgICAgICAgICAgICAgIHRoaXMucGVyT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXNbeC5vcGVyYXRpb25OYW1lXVxuICAgICAgICAgICAgICAgICAgICAuc2VydmVyU2lkZVJlZ2lvbmFsQWxhcm1zQW5kUnVsZXNcbiAgICAgICAgICAgICAgICAgICAgLmluc3RhbmNlQ29udHJpYnV0b3JzVG9SZWdpb25hbEZhdWx0cyxcblxuICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udHJpYnV0b3JzVG9IaWdoTGF0ZW5jeTpcbiAgICAgICAgICAgICAgICAgIHRoaXMucGVyT3BlcmF0aW9uQWxhcm1zQW5kUnVsZXNbeC5vcGVyYXRpb25OYW1lXVxuICAgICAgICAgICAgICAgICAgICAuc2VydmVyU2lkZVJlZ2lvbmFsQWxhcm1zQW5kUnVsZXNcbiAgICAgICAgICAgICAgICAgICAgLmluc3RhbmNlQ29udHJpYnV0b3JzVG9SZWdpb25hbEhpZ2hMYXRlbmN5LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgKS5kYXNoYm9hcmQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGxldCBkYXNoYm9hcmRTdGFjazogTmVzdGVkU3RhY2sgPSBuZXcgTmVzdGVkU3RhY2soXG4gICAgICAgIHRoaXMsXG4gICAgICAgICdTZXJ2aWNlRGFzaGJvYXJkJyxcbiAgICAgICAge30sXG4gICAgICApO1xuXG4gICAgICB0aGlzLnNlcnZpY2VEYXNoYm9hcmQgPSBuZXcgU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQoXG4gICAgICAgIGRhc2hib2FyZFN0YWNrLFxuICAgICAgICBwcm9wcy5zZXJ2aWNlLnNlcnZpY2VOYW1lLnRvTG93ZXJDYXNlKCksXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcnZhbDogcHJvcHMuaW50ZXJ2YWwgPyBwcm9wcy5pbnRlcnZhbCA6IER1cmF0aW9uLm1pbnV0ZXMoNjApLFxuICAgICAgICAgIHNlcnZpY2U6IHByb3BzLnNlcnZpY2UsXG4gICAgICAgICAgYWdncmVnYXRlUmVnaW9uYWxBbGFybTpcbiAgICAgICAgICAgIHRoaXMuc2VydmljZUFsYXJtcy5yZWdpb25hbEZhdWx0Q291bnRTZXJ2ZXJTaWRlQWxhcm0sXG4gICAgICAgICAgem9uYWxBZ2dyZWdhdGVBbGFybXM6XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2VBbGFybXMuem9uYWxBZ2dyZWdhdGVJc29sYXRlZEltcGFjdEFsYXJtcyxcbiAgICAgICAgICBhek1hcHBlcjogdGhpcy5hek1hcHBlcixcbiAgICAgICAgfSxcbiAgICAgICkuZGFzaGJvYXJkO1xuICAgIH1cbiAgfVxufVxuIl19