@cdklabs/cdk-appmod-catalog-blueprints 1.0.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 (105) hide show
  1. package/.jsii +8644 -0
  2. package/LICENSE +202 -0
  3. package/README.md +212 -0
  4. package/lib/document-processing/agentic-document-processing.d.ts +16 -0
  5. package/lib/document-processing/agentic-document-processing.js +90 -0
  6. package/lib/document-processing/base-document-processing.d.ts +189 -0
  7. package/lib/document-processing/base-document-processing.js +509 -0
  8. package/lib/document-processing/bedrock-document-processing.d.ts +167 -0
  9. package/lib/document-processing/bedrock-document-processing.js +297 -0
  10. package/lib/document-processing/index.d.ts +3 -0
  11. package/lib/document-processing/index.js +20 -0
  12. package/lib/document-processing/resources/default-bedrock-invoke/index.py +63 -0
  13. package/lib/document-processing/resources/default-bedrock-invoke/requirements.txt +4 -0
  14. package/lib/document-processing/resources/default-doc-retrieval-lambda/index.mjs +92 -0
  15. package/lib/document-processing/resources/default-doc-retrieval-lambda/package.json +10 -0
  16. package/lib/document-processing/resources/default-error-handler/index.js +46 -0
  17. package/lib/document-processing/resources/default-error-handler/package.json +4 -0
  18. package/lib/document-processing/resources/default-image-processor/classifier.mjs +665 -0
  19. package/lib/document-processing/resources/default-image-processor/extractors.mjs +465 -0
  20. package/lib/document-processing/resources/default-image-processor/index.mjs +143 -0
  21. package/lib/document-processing/resources/default-image-processor/package-lock.json +12 -0
  22. package/lib/document-processing/resources/default-image-processor/package.json +4 -0
  23. package/lib/document-processing/resources/default-image-validator/index.mjs +76 -0
  24. package/lib/document-processing/resources/default-image-validator/package-lock.json +154 -0
  25. package/lib/document-processing/resources/default-image-validator/package.json +7 -0
  26. package/lib/document-processing/resources/default-pdf-processor/index.js +46 -0
  27. package/lib/document-processing/resources/default-pdf-validator/index.js +36 -0
  28. package/lib/document-processing/resources/default-sqs-consumer/index.py +111 -0
  29. package/lib/document-processing/resources/default-sqs-consumer/requirements.txt +4 -0
  30. package/lib/document-processing/resources/default-sqs-consumer/sample_payload.json +20 -0
  31. package/lib/document-processing/resources/default-sqs-consumer/sample_payload_multi.json +24 -0
  32. package/lib/document-processing/resources/default-strands-agent/index.py +111 -0
  33. package/lib/document-processing/resources/default-strands-agent/requirements.txt +6 -0
  34. package/lib/document-processing/tests/agentic-document-processing-nag.test.d.ts +1 -0
  35. package/lib/document-processing/tests/agentic-document-processing-nag.test.js +107 -0
  36. package/lib/document-processing/tests/agentic-document-processing.test.d.ts +1 -0
  37. package/lib/document-processing/tests/agentic-document-processing.test.js +125 -0
  38. package/lib/document-processing/tests/bedrock-document-processing-nag.test.d.ts +1 -0
  39. package/lib/document-processing/tests/bedrock-document-processing-nag.test.js +101 -0
  40. package/lib/document-processing/tests/bedrock-document-processing.test.d.ts +1 -0
  41. package/lib/document-processing/tests/bedrock-document-processing.test.js +79 -0
  42. package/lib/framework/custom-resource/default-runtimes.d.ts +21 -0
  43. package/lib/framework/custom-resource/default-runtimes.js +34 -0
  44. package/lib/framework/custom-resource/index.d.ts +1 -0
  45. package/lib/framework/custom-resource/index.js +18 -0
  46. package/lib/framework/foundation/access-log.d.ts +69 -0
  47. package/lib/framework/foundation/access-log.js +121 -0
  48. package/lib/framework/foundation/eventbridge-broker.d.ts +18 -0
  49. package/lib/framework/foundation/eventbridge-broker.js +42 -0
  50. package/lib/framework/foundation/index.d.ts +3 -0
  51. package/lib/framework/foundation/index.js +20 -0
  52. package/lib/framework/foundation/network.d.ts +19 -0
  53. package/lib/framework/foundation/network.js +83 -0
  54. package/lib/framework/index.d.ts +2 -0
  55. package/lib/framework/index.js +19 -0
  56. package/lib/framework/quickstart/base-quickstart.d.ts +30 -0
  57. package/lib/framework/quickstart/base-quickstart.js +30 -0
  58. package/lib/index.d.ts +4 -0
  59. package/lib/index.js +21 -0
  60. package/lib/tsconfig.tsbuildinfo +1 -0
  61. package/lib/utilities/cdk-nag-config.d.ts +42 -0
  62. package/lib/utilities/cdk-nag-config.js +194 -0
  63. package/lib/utilities/data-loader-lambda/index.py +282 -0
  64. package/lib/utilities/data-loader-lambda/requirements.txt +3 -0
  65. package/lib/utilities/data-loader.d.ts +173 -0
  66. package/lib/utilities/data-loader.js +447 -0
  67. package/lib/utilities/index.d.ts +3 -0
  68. package/lib/utilities/index.js +20 -0
  69. package/lib/utilities/lambda-iam-utils.d.ts +145 -0
  70. package/lib/utilities/lambda-iam-utils.js +235 -0
  71. package/lib/utilities/lambda_layers/data-masking/layer-construct.d.ts +42 -0
  72. package/lib/utilities/lambda_layers/data-masking/layer-construct.js +53 -0
  73. package/lib/utilities/lambda_layers/data-masking/layer-construct.ts +88 -0
  74. package/lib/utilities/observability/bedrock-observability.d.ts +18 -0
  75. package/lib/utilities/observability/bedrock-observability.js +131 -0
  76. package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.d.ts +6 -0
  77. package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.js +22 -0
  78. package/lib/utilities/observability/index.d.ts +6 -0
  79. package/lib/utilities/observability/index.js +25 -0
  80. package/lib/utilities/observability/lambda-observability-property-injector.d.ts +8 -0
  81. package/lib/utilities/observability/lambda-observability-property-injector.js +43 -0
  82. package/lib/utilities/observability/log-group-data-protection-props.d.ts +19 -0
  83. package/lib/utilities/observability/log-group-data-protection-props.js +5 -0
  84. package/lib/utilities/observability/observability.d.ts +83 -0
  85. package/lib/utilities/observability/observability.js +278 -0
  86. package/lib/utilities/observability/observable.d.ts +32 -0
  87. package/lib/utilities/observability/observable.js +3 -0
  88. package/lib/utilities/observability/powertools-config.d.ts +3 -0
  89. package/lib/utilities/observability/powertools-config.js +25 -0
  90. package/lib/utilities/observability/resources/bedrock-manage-logging-configuration/index.py +27 -0
  91. package/lib/utilities/observability/state-machine-observability-property-injector.d.ts +8 -0
  92. package/lib/utilities/observability/state-machine-observability-property-injector.js +49 -0
  93. package/lib/utilities/tests/data-loader-nag.test.d.ts +1 -0
  94. package/lib/utilities/tests/data-loader-nag.test.js +432 -0
  95. package/lib/utilities/tests/data-loader.test.d.ts +1 -0
  96. package/lib/utilities/tests/data-loader.test.js +284 -0
  97. package/lib/webapp/frontend-construct.d.ts +136 -0
  98. package/lib/webapp/frontend-construct.js +253 -0
  99. package/lib/webapp/index.d.ts +1 -0
  100. package/lib/webapp/index.js +18 -0
  101. package/lib/webapp/tests/frontend-construct-nag.test.d.ts +1 -0
  102. package/lib/webapp/tests/frontend-construct-nag.test.js +266 -0
  103. package/lib/webapp/tests/frontend-construct.test.d.ts +1 -0
  104. package/lib/webapp/tests/frontend-construct.test.js +385 -0
  105. package/package.json +183 -0
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.ServerlessObservability = void 0;
6
+ const cdk = require("aws-cdk-lib");
7
+ const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
8
+ const iam = require("aws-cdk-lib/aws-iam");
9
+ const lambda = require("aws-cdk-lib/aws-lambda");
10
+ const logs = require("aws-cdk-lib/aws-logs");
11
+ const constructs_1 = require("constructs");
12
+ /**
13
+ * Comprehensive observability construct for serverless use cases
14
+ */
15
+ class ServerlessObservability extends constructs_1.Construct {
16
+ constructor(scope, id, resources, config = {}) {
17
+ super(scope, id);
18
+ // Configuration with defaults
19
+ const observabilityConfig = {
20
+ enableDashboard: true,
21
+ enableAlarms: true,
22
+ enableTracing: true,
23
+ logRetentionDays: logs.RetentionDays.ONE_MONTH,
24
+ dashboardName: `${resources.useCaseName}-${cdk.Stack.of(this).stackName}`,
25
+ metricsNamespace: resources.useCaseName,
26
+ ...config,
27
+ };
28
+ this.metricsNamespace = observabilityConfig.metricsNamespace;
29
+ this.logGroups = [];
30
+ this.alarms = [];
31
+ // Create log groups for Lambda functions
32
+ this.createLogGroups(resources.lambdaFunctions, observabilityConfig);
33
+ // Enable X-Ray tracing
34
+ if (observabilityConfig.enableTracing) {
35
+ this.enableTracing(resources);
36
+ }
37
+ // Create CloudWatch alarms
38
+ if (observabilityConfig.enableAlarms) {
39
+ this.createAlarms(resources, observabilityConfig);
40
+ }
41
+ // Create CloudWatch dashboard
42
+ if (observabilityConfig.enableDashboard) {
43
+ this.dashboard = this.createDashboard(resources, observabilityConfig);
44
+ }
45
+ }
46
+ /**
47
+ * Create log groups for Lambda functions with proper retention
48
+ */
49
+ createLogGroups(lambdaFunctions, config) {
50
+ lambdaFunctions.forEach((fn, index) => {
51
+ const logGroup = new logs.LogGroup(this, `LogGroup-${index}`, {
52
+ logGroupName: `/aws/lambda/${fn.functionName}`,
53
+ retention: config.logRetentionDays,
54
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
55
+ });
56
+ this.logGroups.push(logGroup);
57
+ });
58
+ }
59
+ /**
60
+ * Enable AWS X-Ray tracing for all resources
61
+ */
62
+ enableTracing(resources) {
63
+ // Enable X-Ray tracing for Lambda functions
64
+ resources.lambdaFunctions.forEach(fn => {
65
+ // Enable X-Ray tracing via Lambda configuration (not environment variables)
66
+ const cfnFunction = fn.node.defaultChild;
67
+ cfnFunction.tracingConfig = {
68
+ mode: lambda.Tracing.ACTIVE,
69
+ };
70
+ // Add X-Ray permissions
71
+ fn.addToRolePolicy(new iam.PolicyStatement({
72
+ actions: ['xray:PutTraceSegments', 'xray:PutTelemetryRecords'],
73
+ resources: ['*'],
74
+ }));
75
+ // Note: _X_AMZN_TRACE_ID is automatically managed by Lambda runtime
76
+ });
77
+ // Enable tracing for Step Functions
78
+ // Note: Tracing should be enabled during state machine creation with tracingEnabled: true
79
+ }
80
+ /**
81
+ * Create CloudWatch alarms for monitoring critical metrics
82
+ */
83
+ createAlarms(resources, config) {
84
+ // Step Functions execution failure alarm (if state machine exists)
85
+ if (resources.stateMachine) {
86
+ const stepFunctionFailureAlarm = new cloudwatch.Alarm(this, 'StepFunctionFailureAlarm', {
87
+ alarmName: `${config.dashboardName}-StepFunction-Failures`,
88
+ alarmDescription: 'Step Function execution failures',
89
+ metric: resources.stateMachine.metricFailed({
90
+ period: cdk.Duration.minutes(5),
91
+ statistic: 'Sum',
92
+ }),
93
+ threshold: 1,
94
+ evaluationPeriods: 1,
95
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
96
+ });
97
+ this.alarms.push(stepFunctionFailureAlarm);
98
+ }
99
+ // Lambda function error rate alarms
100
+ resources.lambdaFunctions.forEach((fn, index) => {
101
+ const errorAlarm = new cloudwatch.Alarm(this, `LambdaErrorAlarm-${index}`, {
102
+ alarmName: `${config.dashboardName}-Lambda-${fn.functionName}-Errors`,
103
+ alarmDescription: `High error rate for Lambda function ${fn.functionName}`,
104
+ metric: fn.metricErrors({
105
+ period: cdk.Duration.minutes(5),
106
+ statistic: 'Sum',
107
+ }),
108
+ threshold: 5,
109
+ evaluationPeriods: 2,
110
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
111
+ });
112
+ this.alarms.push(errorAlarm);
113
+ // Lambda function duration alarm
114
+ const durationAlarm = new cloudwatch.Alarm(this, `LambdaDurationAlarm-${index}`, {
115
+ alarmName: `${config.dashboardName}-Lambda-${fn.functionName}-Duration`,
116
+ alarmDescription: `High duration for Lambda function ${fn.functionName}`,
117
+ metric: fn.metricDuration({
118
+ period: cdk.Duration.minutes(5),
119
+ statistic: 'Average',
120
+ }),
121
+ threshold: 30000, // 30 seconds
122
+ evaluationPeriods: 3,
123
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
124
+ });
125
+ this.alarms.push(durationAlarm);
126
+ });
127
+ // SQS queue depth alarm (if queues exist)
128
+ if (resources.sqsQueues) {
129
+ resources.sqsQueues.forEach((queue, index) => {
130
+ const queueDepthAlarm = new cloudwatch.Alarm(this, `SQSDepthAlarm-${index}`, {
131
+ alarmName: `${config.dashboardName}-SQS-${queue.queueName}-Depth`,
132
+ alarmDescription: `High message count in SQS queue ${queue.queueName}`,
133
+ metric: queue.metricApproximateNumberOfMessagesVisible({
134
+ period: cdk.Duration.minutes(5),
135
+ statistic: 'Average',
136
+ }),
137
+ threshold: 100,
138
+ evaluationPeriods: 2,
139
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
140
+ });
141
+ this.alarms.push(queueDepthAlarm);
142
+ });
143
+ }
144
+ // Dead letter queue alarm
145
+ if (resources.deadLetterQueue) {
146
+ const dlqAlarm = new cloudwatch.Alarm(this, 'DeadLetterQueueAlarm', {
147
+ alarmName: `${config.dashboardName}-DeadLetterQueue-Messages`,
148
+ alarmDescription: 'Messages in dead letter queue',
149
+ metric: resources.deadLetterQueue.metricApproximateNumberOfMessagesVisible({
150
+ period: cdk.Duration.minutes(5),
151
+ statistic: 'Sum',
152
+ }),
153
+ threshold: 1,
154
+ evaluationPeriods: 1,
155
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
156
+ });
157
+ this.alarms.push(dlqAlarm);
158
+ }
159
+ }
160
+ /**
161
+ * Create comprehensive CloudWatch dashboard
162
+ */
163
+ createDashboard(resources, config) {
164
+ const dashboard = new cloudwatch.Dashboard(this, 'Dashboard', {
165
+ dashboardName: config.dashboardName,
166
+ });
167
+ // Step Functions metrics (if state machine exists)
168
+ if (resources.stateMachine) {
169
+ dashboard.addWidgets(new cloudwatch.GraphWidget({
170
+ title: 'Step Functions Executions',
171
+ left: [
172
+ resources.stateMachine.metricStarted({
173
+ label: 'Started',
174
+ color: cloudwatch.Color.BLUE,
175
+ }),
176
+ resources.stateMachine.metricSucceeded({
177
+ label: 'Succeeded',
178
+ color: cloudwatch.Color.GREEN,
179
+ }),
180
+ resources.stateMachine.metricFailed({
181
+ label: 'Failed',
182
+ color: cloudwatch.Color.RED,
183
+ }),
184
+ ],
185
+ width: 12,
186
+ height: 6,
187
+ }));
188
+ dashboard.addWidgets(new cloudwatch.GraphWidget({
189
+ title: 'Step Functions Execution Duration',
190
+ left: [
191
+ resources.stateMachine.metricTime({
192
+ label: 'Execution Time',
193
+ statistic: 'Average',
194
+ color: cloudwatch.Color.PURPLE,
195
+ }),
196
+ ],
197
+ width: 12,
198
+ height: 6,
199
+ }));
200
+ }
201
+ // Lambda functions metrics
202
+ const lambdaInvocations = resources.lambdaFunctions.map(fn => fn.metricInvocations({
203
+ label: fn.functionName,
204
+ }));
205
+ const lambdaErrors = resources.lambdaFunctions.map(fn => fn.metricErrors({
206
+ label: `${fn.functionName} Errors`,
207
+ color: cloudwatch.Color.RED,
208
+ }));
209
+ dashboard.addWidgets(new cloudwatch.GraphWidget({
210
+ title: 'Lambda Function Invocations',
211
+ left: lambdaInvocations,
212
+ width: 12,
213
+ height: 6,
214
+ }));
215
+ dashboard.addWidgets(new cloudwatch.GraphWidget({
216
+ title: 'Lambda Function Errors',
217
+ left: lambdaErrors,
218
+ width: 12,
219
+ height: 6,
220
+ }));
221
+ // SQS queue metrics (if queues exist)
222
+ if (resources.sqsQueues && resources.sqsQueues.length > 0) {
223
+ const sqsMessages = resources.sqsQueues.map(queue => queue.metricApproximateNumberOfMessagesVisible({
224
+ label: `${queue.queueName} Messages`,
225
+ }));
226
+ dashboard.addWidgets(new cloudwatch.GraphWidget({
227
+ title: 'SQS Queue Depth',
228
+ left: sqsMessages,
229
+ width: 12,
230
+ height: 6,
231
+ }));
232
+ }
233
+ // Custom metrics widget for use case specific metrics
234
+ dashboard.addWidgets(new cloudwatch.GraphWidget({
235
+ title: `${resources.useCaseName} Metrics`,
236
+ left: [
237
+ new cloudwatch.Metric({
238
+ namespace: this.metricsNamespace,
239
+ metricName: 'ProcessedItems',
240
+ statistic: 'Sum',
241
+ label: 'Items Processed',
242
+ color: cloudwatch.Color.GREEN,
243
+ }),
244
+ new cloudwatch.Metric({
245
+ namespace: this.metricsNamespace,
246
+ metricName: 'FailedItems',
247
+ statistic: 'Sum',
248
+ label: 'Items Failed',
249
+ color: cloudwatch.Color.RED,
250
+ }),
251
+ ],
252
+ width: 12,
253
+ height: 6,
254
+ }));
255
+ return dashboard;
256
+ }
257
+ /**
258
+ * Add custom widget to the dashboard
259
+ */
260
+ addCustomWidget(widget) {
261
+ if (this.dashboard) {
262
+ this.dashboard.addWidgets(widget);
263
+ }
264
+ }
265
+ /**
266
+ * Create a custom metric for use case specific events
267
+ */
268
+ createCustomMetric(metricName, dimensionsMap) {
269
+ return new cloudwatch.Metric({
270
+ namespace: this.metricsNamespace,
271
+ metricName,
272
+ dimensionsMap,
273
+ statistic: 'Sum',
274
+ });
275
+ }
276
+ }
277
+ exports.ServerlessObservability = ServerlessObservability;
278
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JzZXJ2YWJpbGl0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3VzZS1jYXNlcy91dGlsaXRpZXMvb2JzZXJ2YWJpbGl0eS9vYnNlcnZhYmlsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxxRUFBcUU7QUFDckUsc0NBQXNDOzs7QUFFdEMsbUNBQW1DO0FBQ25DLHlEQUF5RDtBQUN6RCwyQ0FBMkM7QUFDM0MsaURBQWlEO0FBQ2pELDZDQUE2QztBQUk3QywyQ0FBdUM7QUFtRHZDOztHQUVHO0FBQ0gsTUFBYSx1QkFBd0IsU0FBUSxzQkFBUztJQWFwRCxZQUNFLEtBQWdCLEVBQ2hCLEVBQVUsRUFDVixTQUFpQyxFQUNqQyxTQUE4QixFQUFFO1FBRWhDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsOEJBQThCO1FBQzlCLE1BQU0sbUJBQW1CLEdBQUc7WUFDMUIsZUFBZSxFQUFFLElBQUk7WUFDckIsWUFBWSxFQUFFLElBQUk7WUFDbEIsYUFBYSxFQUFFLElBQUk7WUFDbkIsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTO1lBQzlDLGFBQWEsRUFBRSxHQUFHLFNBQVMsQ0FBQyxXQUFXLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFO1lBQ3pFLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxXQUFXO1lBQ3ZDLEdBQUcsTUFBTTtTQUNWLENBQUM7UUFFRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsbUJBQW1CLENBQUMsZ0JBQWdCLENBQUM7UUFDN0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFFakIseUNBQXlDO1FBQ3pDLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1FBRXJFLHVC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LEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLO2lCQUM5QixDQUFDO2dCQUNGLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQztvQkFDcEIsU0FBUyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7b0JBQ2hDLFVBQVUsRUFBRSxhQUFhO29CQUN6QixTQUFTLEVBQUUsS0FBSztvQkFDaEIsS0FBSyxFQUFFLGNBQWM7b0JBQ3JCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUc7aUJBQzVCLENBQUM7YUFDSDtZQUNELEtBQUssRUFBRSxFQUFFO1lBQ1QsTUFBTSxFQUFFLENBQUM7U0FDVixDQUFDLENBQ0gsQ0FBQztRQUVGLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRDs7T0FFRztJQUNJLGVBQWUsQ0FBQyxNQUEwQjtRQUMvQyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ksa0JBQWtCLENBQ3ZCLFVBQWtCLEVBQ2xCLGFBQXlDO1FBRXpDLE9BQU8sSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDO1lBQzNCLFNBQVMsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1lBQ2hDLFVBQVU7WUFDVixhQUFhO1lBQ2IsU0FBUyxFQUFFLEtBQUs7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBbFZELDBEQWtWQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBzMyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMnO1xuaW1wb3J0ICogYXMgc3FzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zcXMnO1xuaW1wb3J0ICogYXMgc3RlcGZ1bmN0aW9ucyBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc3RlcGZ1bmN0aW9ucyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBvYnNlcnZhYmlsaXR5IGZlYXR1cmVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2JzZXJ2YWJpbGl0eUNvbmZpZyB7XG4gIC8qKiBFbmFibGUgQ2xvdWRXYXRjaCBEYXNoYm9hcmQgKi9cbiAgcmVhZG9ubHkgZW5hYmxlRGFzaGJvYXJkPzogYm9vbGVhbjtcblxuICAvKiogRW5hYmxlIENsb3VkV2F0Y2ggQWxhcm1zICovXG4gIHJlYWRvbmx5IGVuYWJsZUFsYXJtcz86IGJvb2xlYW47XG5cbiAgLyoqIEVuYWJsZSBBV1MgWC1SYXkgdHJhY2luZyAqL1xuICByZWFkb25seSBlbmFibGVUcmFjaW5nPzogYm9vbGVhbjtcblxuICAvKiogTG9nIHJldGVudGlvbiBwZXJpb2QgaW4gZGF5cyAqL1xuICByZWFkb25seSBsb2dSZXRlbnRpb25EYXlzPzogbG9ncy5SZXRlbnRpb25EYXlzO1xuXG4gIC8qKiBDdXN0b20gZGFzaGJvYXJkIG5hbWUgKi9cbiAgcmVhZG9ubHkgZGFzaGJvYXJkTmFtZT86IHN0cmluZztcblxuICAvKiogU05TIHRvcGljIEFSTiBmb3IgYWxhcm0gbm90aWZpY2F0aW9ucyAqL1xuICByZWFkb25seSBhbGFybU5vdGlmaWNhdGlvblRvcGljQXJuPzogc3RyaW5nO1xuXG4gIC8qKiBDdXN0b20gbWV0cmljIG5hbWVzcGFjZSAqL1xuICByZWFkb25seSBtZXRyaWNzTmFtZXNwYWNlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlc291cmNlcyB0aGF0IG5lZWQgb2JzZXJ2YWJpbGl0eSBtb25pdG9yaW5nXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2JzZXJ2YWJpbGl0eVJlc291cmNlcyB7XG4gIC8qKiBTdGVwIEZ1bmN0aW9ucyBzdGF0ZSBtYWNoaW5lIChvcHRpb25hbCkgKi9cbiAgcmVhZG9ubHkgc3RhdGVNYWNoaW5lPzogc3RlcGZ1bmN0aW9ucy5TdGF0ZU1hY2hpbmU7XG5cbiAgLyoqIExhbWJkYSBmdW5jdGlvbnMgdG8gbW9uaXRvciAqL1xuICByZWFkb25seSBsYW1iZGFGdW5jdGlvbnM6IGxhbWJkYS5GdW5jdGlvbltdO1xuXG4gIC8qKiBTUVMgcXVldWVzIHRvIG1vbml0b3IgKG9wdGlvbmFsKSAqL1xuICByZWFkb25seSBzcXNRdWV1ZXM/OiBzcXMuUXVldWVbXTtcblxuICAvKiogUzMgYnVja2V0cyBmb3Igc3RvcmFnZSAob3B0aW9uYWwpICovXG4gIHJlYWRvbmx5IHMzQnVja2V0cz86IHMzLklCdWNrZXRbXTtcblxuICAvKiogRGVhZCBsZXR0ZXIgcXVldWUgKG9wdGlvbmFsKSAqL1xuICByZWFkb25seSBkZWFkTGV0dGVyUXVldWU/OiBzcXMuSVF1ZXVlO1xuXG4gIC8qKiBVc2UgY2FzZSBuYW1lIGZvciBsYWJlbGluZyAqL1xuICByZWFkb25seSB1c2VDYXNlTmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbXByZWhlbnNpdmUgb2JzZXJ2YWJpbGl0eSBjb25zdHJ1Y3QgZm9yIHNlcnZlcmxlc3MgdXNlIGNhc2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2ZXJsZXNzT2JzZXJ2YWJpbGl0eSBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKiBDbG91ZFdhdGNoIERhc2hib2FyZCBmb3IgbW9uaXRvcmluZyAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZGFzaGJvYXJkPzogY2xvdWR3YXRjaC5EYXNoYm9hcmQ7XG5cbiAgLyoqIENsb3VkV2F0Y2ggTG9nIEdyb3VwcyAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbG9nR3JvdXBzOiBsb2dzLkxvZ0dyb3VwW107XG5cbiAgLyoqIENsb3VkV2F0Y2ggQWxhcm1zICovXG4gIHB1YmxpYyByZWFkb25seSBhbGFybXM6IGNsb3Vkd2F0Y2guQWxhcm1bXTtcblxuICAvKiogTWV0cmljcyBuYW1lc3BhY2UgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1ldHJpY3NOYW1lc3BhY2U6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcmVzb3VyY2VzOiBPYnNlcnZhYmlsaXR5UmVzb3VyY2VzLFxuICAgIGNvbmZpZzogT2JzZXJ2YWJpbGl0eUNvbmZpZyA9IHt9LFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gQ29uZmlndXJhdGlvbiB3aXRoIGRlZmF1bHRzXG4gICAgY29uc3Qgb2JzZXJ2YWJpbGl0eUNvbmZpZyA9IHtcbiAgICAgIGVuYWJsZURhc2hib2FyZDogdHJ1ZSxcbiAgICAgIGVuYWJsZUFsYXJtczogdHJ1ZSxcbiAgICAgIGVuYWJsZVRyYWNpbmc6IHRydWUsXG4gICAgICBsb2dSZXRlbnRpb25EYXlzOiBsb2dzLlJldGVudGlvbkRheXMuT05FX01PTlRILFxuICAgICAgZGFzaGJvYXJkTmFtZTogYCR7cmVzb3VyY2VzLnVzZUNhc2VOYW1lfS0ke2Nkay5TdGFjay5vZih0aGlzKS5zdGFja05hbWV9YCxcbiAgICAgIG1ldHJpY3NOYW1lc3BhY2U6IHJlc291cmNlcy51c2VDYXNlTmFtZSxcbiAgICAgIC4uLmNvbmZpZyxcbiAgICB9O1xuXG4gICAgdGhpcy5tZXRyaWNzTmFtZXNwYWNlID0gb2JzZXJ2YWJpbGl0eUNvbmZpZy5tZXRyaWNzTmFtZXNwYWNlO1xuICAgIHRoaXMubG9nR3JvdXBzID0gW107XG4gICAgdGhpcy5hbGFybXMgPSBbXTtcblxuICAgIC8vIENyZWF0ZSBsb2cgZ3JvdXBzIGZvciBMYW1iZGEgZnVuY3Rpb25zXG4gICAgdGhpcy5jcmVhdGVMb2dHcm91cHMocmVzb3VyY2VzLmxhbWJkYUZ1bmN0aW9ucywgb2JzZXJ2YWJpbGl0eUNvbmZpZyk7XG5cbiAgICAvLyBFbmFibGUgWC1SYXkgdHJhY2luZ1xuICAgIGlmIChvYnNlcnZhYmlsaXR5Q29uZmlnLmVuYWJsZVRyYWNpbmcpIHtcbiAgICAgIHRoaXMuZW5hYmxlVHJhY2luZyhyZXNvdXJjZXMpO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBDbG91ZFdhdGNoIGFsYXJtc1xuICAgIGlmIChvYnNlcnZhYmlsaXR5Q29uZmlnLmVuYWJsZUFsYXJtcykge1xuICAgICAgdGhpcy5jcmVhdGVBbGFybXMocmVzb3VyY2VzLCBvYnNlcnZhYmlsaXR5Q29uZmlnKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgQ2xvdWRXYXRjaCBkYXNoYm9hcmRcbiAgICBpZiAob2JzZXJ2YWJpbGl0eUNvbmZpZy5lbmFibGVEYXNoYm9hcmQpIHtcbiAgICAgIHRoaXMuZGFzaGJvYXJkID0gdGhpcy5jcmVhdGVEYXNoYm9hcmQocmVzb3VyY2VzLCBvYnNlcnZhYmlsaXR5Q29uZmlnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGxvZyBncm91cHMgZm9yIExhbWJkYSBmdW5jdGlvbnMgd2l0aCBwcm9wZXIgcmV0ZW50aW9uXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUxvZ0dyb3VwcyhcbiAgICBsYW1iZGFGdW5jdGlvbnM6IGxhbWJkYS5GdW5jdGlvbltdLFxuICAgIGNvbmZpZzogT2JzZXJ2YWJpbGl0eUNvbmZpZyxcbiAgKTogdm9pZCB7XG4gICAgbGFtYmRhRnVuY3Rpb25zLmZvckVhY2goKGZuLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgbG9nR3JvdXAgPSBuZXcgbG9ncy5Mb2dHcm91cCh0aGlzLCBgTG9nR3JvdXAtJHtpbmRleH1gLCB7XG4gICAgICAgIGxvZ0dyb3VwTmFtZTogYC9hd3MvbGFtYmRhLyR7Zm4uZnVuY3Rpb25OYW1lfWAsXG4gICAgICAgIHJldGVudGlvbjogY29uZmlnLmxvZ1JldGVudGlvbkRheXMhLFxuICAgICAgICByZW1vdmFsUG9saWN5OiBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMubG9nR3JvdXBzLnB1c2gobG9nR3JvdXApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuYWJsZSBBV1MgWC1SYXkgdHJhY2luZyBmb3IgYWxsIHJlc291cmNlc1xuICAgKi9cbiAgcHJpdmF0ZSBlbmFibGVUcmFjaW5nKHJlc291cmNlczogT2JzZXJ2YWJpbGl0eVJlc291cmNlcyk6IHZvaWQge1xuICAgIC8vIEVuYWJsZSBYLVJheSB0cmFjaW5nIGZvciBMYW1iZGEgZnVuY3Rpb25zXG4gICAgcmVzb3VyY2VzLmxhbWJkYUZ1bmN0aW9ucy5mb3JFYWNoKGZuID0+IHtcbiAgICAgIC8vIEVuYWJsZSBYLVJheSB0cmFjaW5nIHZpYSBMYW1iZGEgY29uZmlndXJhdGlvbiAobm90IGVudmlyb25tZW50IHZhcmlhYmxlcylcbiAgICAgIGNvbnN0IGNmbkZ1bmN0aW9uID0gZm4ubm9kZS5kZWZhdWx0Q2hpbGQgYXMgbGFtYmRhLkNmbkZ1bmN0aW9uO1xuICAgICAgY2ZuRnVuY3Rpb24udHJhY2luZ0NvbmZpZyA9IHtcbiAgICAgICAgbW9kZTogbGFtYmRhLlRyYWNpbmcuQUNUSVZFLFxuICAgICAgfTtcblxuICAgICAgLy8gQWRkIFgtUmF5IHBlcm1pc3Npb25zXG4gICAgICBmbi5hZGRUb1JvbGVQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ3hyYXk6UHV0VHJhY2VTZWdtZW50cycsICd4cmF5OlB1dFRlbGVtZXRyeVJlY29yZHMnXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIH0pKTtcblxuICAgICAgLy8gTm90ZTogX1hfQU1aTl9UUkFDRV9JRCBpcyBhdXRvbWF0aWNhbGx5IG1hbmFnZWQgYnkgTGFtYmRhIHJ1bnRpbWVcbiAgICB9KTtcblxuICAgIC8vIEVuYWJsZSB0cmFjaW5nIGZvciBTdGVwIEZ1bmN0aW9uc1xuICAgIC8vIE5vdGU6IFRyYWNpbmcgc2hvdWxkIGJlIGVuYWJsZWQgZHVyaW5nIHN0YXRlIG1hY2hpbmUgY3JlYXRpb24gd2l0aCB0cmFjaW5nRW5hYmxlZDogdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBDbG91ZFdhdGNoIGFsYXJtcyBmb3IgbW9uaXRvcmluZyBjcml0aWNhbCBtZXRyaWNzXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUFsYXJtcyhcbiAgICByZXNvdXJjZXM6IE9ic2VydmFiaWxpdHlSZXNvdXJjZXMsXG4gICAgY29uZmlnOiBPYnNlcnZhYmlsaXR5Q29uZmlnLFxuICApOiB2b2lkIHtcbiAgICAvLyBTdGVwIEZ1bmN0aW9ucyBleGVjdXRpb24gZmFpbHVyZSBhbGFybSAoaWYgc3RhdGUgbWFjaGluZSBleGlzdHMpXG4gICAgaWYgKHJlc291cmNlcy5zdGF0ZU1hY2hpbmUpIHtcbiAgICAgIGNvbnN0IHN0ZXBGdW5jdGlvbkZhaWx1cmVBbGFybSA9IG5ldyBjbG91ZHdhdGNoLkFsYXJtKHRoaXMsICdTdGVwRnVuY3Rpb25GYWlsdXJlQWxhcm0nLCB7XG4gICAgICAgIGFsYXJtTmFtZTogYCR7Y29uZmlnLmRhc2hib2FyZE5hbWV9LVN0ZXBGdW5jdGlvbi1GYWlsdXJlc2AsXG4gICAgICAgIGFsYXJtRGVzY3JpcHRpb246ICdTdGVwIEZ1bmN0aW9uIGV4ZWN1dGlvbiBmYWlsdXJlcycsXG4gICAgICAgIG1ldHJpYzogcmVzb3VyY2VzLnN0YXRlTWFjaGluZS5tZXRyaWNGYWlsZWQoe1xuICAgICAgICAgIHBlcmlvZDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgfSksXG4gICAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5OT1RfQlJFQUNISU5HLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFsYXJtcy5wdXNoKHN0ZXBGdW5jdGlvbkZhaWx1cmVBbGFybSk7XG4gICAgfVxuXG4gICAgLy8gTGFtYmRhIGZ1bmN0aW9uIGVycm9yIHJhdGUgYWxhcm1zXG4gICAgcmVzb3VyY2VzLmxhbWJkYUZ1bmN0aW9ucy5mb3JFYWNoKChmbiwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGVycm9yQWxhcm0gPSBuZXcgY2xvdWR3YXRjaC5BbGFybSh0aGlzLCBgTGFtYmRhRXJyb3JBbGFybS0ke2luZGV4fWAsIHtcbiAgICAgICAgYWxhcm1OYW1lOiBgJHtjb25maWcuZGFzaGJvYXJkTmFtZX0tTGFtYmRhLSR7Zm4uZnVuY3Rpb25OYW1lfS1FcnJvcnNgLFxuICAgICAgICBhbGFybURlc2NyaXB0aW9uOiBgSGlnaCBlcnJvciByYXRlIGZvciBMYW1iZGEgZnVuY3Rpb24gJHtmbi5mdW5jdGlvbk5hbWV9YCxcbiAgICAgICAgbWV0cmljOiBmbi5tZXRyaWNFcnJvcnMoe1xuICAgICAgICAgIHBlcmlvZDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgfSksXG4gICAgICAgIHRocmVzaG9sZDogNSxcbiAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDIsXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5OT1RfQlJFQUNISU5HLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFsYXJtcy5wdXNoKGVycm9yQWxhcm0pO1xuXG4gICAgICAvLyBMYW1iZGEgZnVuY3Rpb24gZHVyYXRpb24gYWxhcm1cbiAgICAgIGNvbnN0IGR1cmF0aW9uQWxhcm0gPSBuZXcgY2xvdWR3YXRjaC5BbGFybSh0aGlzLCBgTGFtYmRhRHVyYXRpb25BbGFybS0ke2luZGV4fWAsIHtcbiAgICAgICAgYWxhcm1OYW1lOiBgJHtjb25maWcuZGFzaGJvYXJkTmFtZX0tTGFtYmRhLSR7Zm4uZnVuY3Rpb25OYW1lfS1EdXJhdGlvbmAsXG4gICAgICAgIGFsYXJtRGVzY3JpcHRpb246IGBIaWdoIGR1cmF0aW9uIGZvciBMYW1iZGEgZnVuY3Rpb24gJHtmbi5mdW5jdGlvbk5hbWV9YCxcbiAgICAgICAgbWV0cmljOiBmbi5tZXRyaWNEdXJhdGlvbih7XG4gICAgICAgICAgcGVyaW9kOiBjZGsuRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICBzdGF0aXN0aWM6ICdBdmVyYWdlJyxcbiAgICAgICAgfSksXG4gICAgICAgIHRocmVzaG9sZDogMzAwMDAsIC8vIDMwIHNlY29uZHNcbiAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDMsXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5OT1RfQlJFQUNISU5HLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFsYXJtcy5wdXNoKGR1cmF0aW9uQWxhcm0pO1xuICAgIH0pO1xuXG4gICAgLy8gU1FTIHF1ZXVlIGRlcHRoIGFsYXJtIChpZiBxdWV1ZXMgZXhpc3QpXG4gICAgaWYgKHJlc291cmNlcy5zcXNRdWV1ZXMpIHtcbiAgICAgIHJlc291cmNlcy5zcXNRdWV1ZXMuZm9yRWFjaCgocXVldWUsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IHF1ZXVlRGVwdGhBbGFybSA9IG5ldyBjbG91ZHdhdGNoLkFsYXJtKHRoaXMsIGBTUVNEZXB0aEFsYXJtLSR7aW5kZXh9YCwge1xuICAgICAgICAgIGFsYXJtTmFtZTogYCR7Y29uZmlnLmRhc2hib2FyZE5hbWV9LVNRUy0ke3F1ZXVlLnF1ZXVlTmFtZX0tRGVwdGhgLFxuICAgICAgICAgIGFsYXJtRGVzY3JpcHRpb246IGBIaWdoIG1lc3NhZ2UgY291bnQgaW4gU1FTIHF1ZXVlICR7cXVldWUucXVldWVOYW1lfWAsXG4gICAgICAgICAgbWV0cmljOiBxdWV1ZS5tZXRyaWNBcHByb3hpbWF0ZU51bWJlck9mTWVzc2FnZXNWaXNpYmxlKHtcbiAgICAgICAgICAgIHBlcmlvZDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgICAgICBzdGF0aXN0aWM6ICdBdmVyYWdlJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB0aHJlc2hvbGQ6IDEwMCxcbiAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogMixcbiAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuTk9UX0JSRUFDSElORyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWxhcm1zLnB1c2gocXVldWVEZXB0aEFsYXJtKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIERlYWQgbGV0dGVyIHF1ZXVlIGFsYXJtXG4gICAgaWYgKHJlc291cmNlcy5kZWFkTGV0dGVyUXVldWUpIHtcbiAgICAgIGNvbnN0IGRscUFsYXJtID0gbmV3IGNsb3Vkd2F0Y2guQWxhcm0odGhpcywgJ0RlYWRMZXR0ZXJRdWV1ZUFsYXJtJywge1xuICAgICAgICBhbGFybU5hbWU6IGAke2NvbmZpZy5kYXNoYm9hcmROYW1lfS1EZWFkTGV0dGVyUXVldWUtTWVzc2FnZXNgLFxuICAgICAgICBhbGFybURlc2NyaXB0aW9uOiAnTWVzc2FnZXMgaW4gZGVhZCBsZXR0ZXIgcXVldWUnLFxuICAgICAgICBtZXRyaWM6IHJlc291cmNlcy5kZWFkTGV0dGVyUXVldWUubWV0cmljQXBwcm94aW1hdGVOdW1iZXJPZk1lc3NhZ2VzVmlzaWJsZSh7XG4gICAgICAgICAgcGVyaW9kOiBjZGsuRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgICB9KSxcbiAgICAgICAgdGhyZXNob2xkOiAxLFxuICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk5PVF9CUkVBQ0hJTkcsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYWxhcm1zLnB1c2goZGxxQWxhcm0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgY29tcHJlaGVuc2l2ZSBDbG91ZFdhdGNoIGRhc2hib2FyZFxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEYXNoYm9hcmQoXG4gICAgcmVzb3VyY2VzOiBPYnNlcnZhYmlsaXR5UmVzb3VyY2VzLFxuICAgIGNvbmZpZzogT2JzZXJ2YWJpbGl0eUNvbmZpZyxcbiAgKTogY2xvdWR3YXRjaC5EYXNoYm9hcmQge1xuICAgIGNvbnN0IGRhc2hib2FyZCA9IG5ldyBjbG91ZHdhdGNoLkRhc2hib2FyZCh0aGlzLCAnRGFzaGJvYXJkJywge1xuICAgICAgZGFzaGJvYXJkTmFtZTogY29uZmlnLmRhc2hib2FyZE5hbWUsXG4gICAgfSk7XG5cbiAgICAvLyBTdGVwIEZ1bmN0aW9ucyBtZXRyaWNzIChpZiBzdGF0ZSBtYWNoaW5lIGV4aXN0cylcbiAgICBpZiAocmVzb3VyY2VzLnN0YXRlTWFjaGluZSkge1xuICAgICAgZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICAgIG5ldyBjbG91ZHdhdGNoLkdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICB0aXRsZTogJ1N0ZXAgRnVuY3Rpb25zIEV4ZWN1dGlvbnMnLFxuICAgICAgICAgIGxlZnQ6IFtcbiAgICAgICAgICAgIHJlc291cmNlcy5zdGF0ZU1hY2hpbmUubWV0cmljU3RhcnRlZCh7XG4gICAgICAgICAgICAgIGxhYmVsOiAnU3RhcnRlZCcsXG4gICAgICAgICAgICAgIGNvbG9yOiBjbG91ZHdhdGNoLkNvbG9yLkJMVUUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHJlc291cmNlcy5zdGF0ZU1hY2hpbmUubWV0cmljU3VjY2VlZGVkKHtcbiAgICAgICAgICAgICAgbGFiZWw6ICdTdWNjZWVkZWQnLFxuICAgICAgICAgICAgICBjb2xvcjogY2xvdWR3YXRjaC5Db2xvci5HUkVFTixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcmVzb3VyY2VzLnN0YXRlTWFjaGluZS5tZXRyaWNGYWlsZWQoe1xuICAgICAgICAgICAgICBsYWJlbDogJ0ZhaWxlZCcsXG4gICAgICAgICAgICAgIGNvbG9yOiBjbG91ZHdhdGNoLkNvbG9yLlJFRCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgd2lkdGg6IDEyLFxuICAgICAgICAgIGhlaWdodDogNixcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBkYXNoYm9hcmQuYWRkV2lkZ2V0cyhcbiAgICAgICAgbmV3IGNsb3Vkd2F0Y2guR3JhcGhXaWRnZXQoe1xuICAgICAgICAgIHRpdGxlOiAnU3RlcCBGdW5jdGlvbnMgRXhlY3V0aW9uIER1cmF0aW9uJyxcbiAgICAgICAgICBsZWZ0OiBbXG4gICAgICAgICAgICByZXNvdXJjZXMuc3RhdGVNYWNoaW5lLm1ldHJpY1RpbWUoe1xuICAgICAgICAgICAgICBsYWJlbDogJ0V4ZWN1dGlvbiBUaW1lJyxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiAnQXZlcmFnZScsXG4gICAgICAgICAgICAgIGNvbG9yOiBjbG91ZHdhdGNoLkNvbG9yLlBVUlBMRSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgd2lkdGg6IDEyLFxuICAgICAgICAgIGhlaWdodDogNixcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIExhbWJkYSBmdW5jdGlvbnMgbWV0cmljc1xuICAgIGNvbnN0IGxhbWJkYUludm9jYXRpb25zID0gcmVzb3VyY2VzLmxhbWJkYUZ1bmN0aW9ucy5tYXAoZm4gPT5cbiAgICAgIGZuLm1ldHJpY0ludm9jYXRpb25zKHtcbiAgICAgICAgbGFiZWw6IGZuLmZ1bmN0aW9uTmFtZSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBsYW1iZGFFcnJvcnMgPSByZXNvdXJjZXMubGFtYmRhRnVuY3Rpb25zLm1hcChmbiA9PlxuICAgICAgZm4ubWV0cmljRXJyb3JzKHtcbiAgICAgICAgbGFiZWw6IGAke2ZuLmZ1bmN0aW9uTmFtZX0gRXJyb3JzYCxcbiAgICAgICAgY29sb3I6IGNsb3Vkd2F0Y2guQ29sb3IuUkVELFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIGRhc2hib2FyZC5hZGRXaWRnZXRzKFxuICAgICAgbmV3IGNsb3Vkd2F0Y2guR3JhcGhXaWRnZXQoe1xuICAgICAgICB0aXRsZTogJ0xhbWJkYSBGdW5jdGlvbiBJbnZvY2F0aW9ucycsXG4gICAgICAgIGxlZnQ6IGxhbWJkYUludm9jYXRpb25zLFxuICAgICAgICB3aWR0aDogMTIsXG4gICAgICAgIGhlaWdodDogNixcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBkYXNoYm9hcmQuYWRkV2lkZ2V0cyhcbiAgICAgIG5ldyBjbG91ZHdhdGNoLkdyYXBoV2lkZ2V0KHtcbiAgICAgICAgdGl0bGU6ICdMYW1iZGEgRnVuY3Rpb24gRXJyb3JzJyxcbiAgICAgICAgbGVmdDogbGFtYmRhRXJyb3JzLFxuICAgICAgICB3aWR0aDogMTIsXG4gICAgICAgIGhlaWdodDogNixcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBTUVMgcXVldWUgbWV0cmljcyAoaWYgcXVldWVzIGV4aXN0KVxuICAgIGlmIChyZXNvdXJjZXMuc3FzUXVldWVzICYmIHJlc291cmNlcy5zcXNRdWV1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgc3FzTWVzc2FnZXMgPSByZXNvdXJjZXMuc3FzUXVldWVzLm1hcChxdWV1ZSA9PlxuICAgICAgICBxdWV1ZS5tZXRyaWNBcHByb3hpbWF0ZU51bWJlck9mTWVzc2FnZXNWaXNpYmxlKHtcbiAgICAgICAgICBsYWJlbDogYCR7cXVldWUucXVldWVOYW1lfSBNZXNzYWdlc2AsXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICAgIG5ldyBjbG91ZHdhdGNoLkdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICB0aXRsZTogJ1NRUyBRdWV1ZSBEZXB0aCcsXG4gICAgICAgICAgbGVmdDogc3FzTWVzc2FnZXMsXG4gICAgICAgICAgd2lkdGg6IDEyLFxuICAgICAgICAgIGhlaWdodDogNixcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEN1c3RvbSBtZXRyaWNzIHdpZGdldCBmb3IgdXNlIGNhc2Ugc3BlY2lmaWMgbWV0cmljc1xuICAgIGRhc2hib2FyZC5hZGRXaWRnZXRzKFxuICAgICAgbmV3IGNsb3Vkd2F0Y2guR3JhcGhXaWRnZXQoe1xuICAgICAgICB0aXRsZTogYCR7cmVzb3VyY2VzLnVzZUNhc2VOYW1lfSBNZXRyaWNzYCxcbiAgICAgICAgbGVmdDogW1xuICAgICAgICAgIG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMubWV0cmljc05hbWVzcGFjZSxcbiAgICAgICAgICAgIG1ldHJpY05hbWU6ICdQcm9jZXNzZWRJdGVtcycsXG4gICAgICAgICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgICAgICAgbGFiZWw6ICdJdGVtcyBQcm9jZXNzZWQnLFxuICAgICAgICAgICAgY29sb3I6IGNsb3Vkd2F0Y2guQ29sb3IuR1JFRU4sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5tZXRyaWNzTmFtZXNwYWNlLFxuICAgICAgICAgICAgbWV0cmljTmFtZTogJ0ZhaWxlZEl0ZW1zJyxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICAgICAgICBsYWJlbDogJ0l0ZW1zIEZhaWxlZCcsXG4gICAgICAgICAgICBjb2xvcjogY2xvdWR3YXRjaC5Db2xvci5SRUQsXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICAgIHdpZHRoOiAxMixcbiAgICAgICAgaGVpZ2h0OiA2LFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHJldHVybiBkYXNoYm9hcmQ7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGN1c3RvbSB3aWRnZXQgdG8gdGhlIGRhc2hib2FyZFxuICAgKi9cbiAgcHVibGljIGFkZEN1c3RvbVdpZGdldCh3aWRnZXQ6IGNsb3Vkd2F0Y2guSVdpZGdldCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRhc2hib2FyZCkge1xuICAgICAgdGhpcy5kYXNoYm9hcmQuYWRkV2lkZ2V0cyh3aWRnZXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBjdXN0b20gbWV0cmljIGZvciB1c2UgY2FzZSBzcGVjaWZpYyBldmVudHNcbiAgICovXG4gIHB1YmxpYyBjcmVhdGVDdXN0b21NZXRyaWMoXG4gICAgbWV0cmljTmFtZTogc3RyaW5nLFxuICAgIGRpbWVuc2lvbnNNYXA/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICApOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICBuYW1lc3BhY2U6IHRoaXMubWV0cmljc05hbWVzcGFjZSxcbiAgICAgIG1ldHJpY05hbWUsXG4gICAgICBkaW1lbnNpb25zTWFwLFxuICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICB9KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,32 @@
1
+ import { IMetric } from 'aws-cdk-lib/aws-cloudwatch';
2
+ import { LogGroupDataProtectionProps } from './log-group-data-protection-props';
3
+ /**
4
+ * Additional properties that constructs implementing the IObservable
5
+ * interface should extend as part of their input props
6
+ */
7
+ export interface ObservableProps {
8
+ /**
9
+ * Business metric service name dimension
10
+ * @default would be defined per use case
11
+ */
12
+ readonly metricServiceName?: string;
13
+ /**
14
+ * Business metric namespace
15
+ * @default would be defined per use case
16
+ */
17
+ readonly metricNamespace?: string;
18
+ /**
19
+ * Data protection related configuration
20
+ * @default a new KMS key would be generated
21
+ */
22
+ readonly logGroupDataProtection?: LogGroupDataProtectionProps;
23
+ }
24
+ /**
25
+ * Interface providing configuration parameters for constructs that support Observability
26
+ */
27
+ export interface IObservable {
28
+ readonly metricServiceName: string;
29
+ readonly metricNamespace: string;
30
+ readonly logGroupDataProtection: LogGroupDataProtectionProps;
31
+ metrics(): IMetric[];
32
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JzZXJ2YWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3VzZS1jYXNlcy91dGlsaXRpZXMvb2JzZXJ2YWJpbGl0eS9vYnNlcnZhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5pbXBvcnQgeyBJTWV0cmljIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0IHsgTG9nR3JvdXBEYXRhUHJvdGVjdGlvblByb3BzIH0gZnJvbSAnLi9sb2ctZ3JvdXAtZGF0YS1wcm90ZWN0aW9uLXByb3BzJztcblxuLyoqXG4gKiBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdGhhdCBjb25zdHJ1Y3RzIGltcGxlbWVudGluZyB0aGUgSU9ic2VydmFibGVcbiAqIGludGVyZmFjZSBzaG91bGQgZXh0ZW5kIGFzIHBhcnQgb2YgdGhlaXIgaW5wdXQgcHJvcHNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPYnNlcnZhYmxlUHJvcHMge1xuICAvKipcbiAgICogQnVzaW5lc3MgbWV0cmljIHNlcnZpY2UgbmFtZSBkaW1lbnNpb25cbiAgICogQGRlZmF1bHQgd291bGQgYmUgZGVmaW5lZCBwZXIgdXNlIGNhc2VcbiAgICovXG4gIHJlYWRvbmx5IG1ldHJpY1NlcnZpY2VOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBCdXNpbmVzcyBtZXRyaWMgbmFtZXNwYWNlXG4gICAqIEBkZWZhdWx0IHdvdWxkIGJlIGRlZmluZWQgcGVyIHVzZSBjYXNlXG4gICAqL1xuICByZWFkb25seSBtZXRyaWNOYW1lc3BhY2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERhdGEgcHJvdGVjdGlvbiByZWxhdGVkIGNvbmZpZ3VyYXRpb25cbiAgICogQGRlZmF1bHQgYSBuZXcgS01TIGtleSB3b3VsZCBiZSBnZW5lcmF0ZWRcbiAgICovXG4gIHJlYWRvbmx5IGxvZ0dyb3VwRGF0YVByb3RlY3Rpb24/OiBMb2dHcm91cERhdGFQcm90ZWN0aW9uUHJvcHM7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIHByb3ZpZGluZyBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMgZm9yIGNvbnN0cnVjdHMgdGhhdCBzdXBwb3J0IE9ic2VydmFiaWxpdHlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJT2JzZXJ2YWJsZSB7XG4gIHJlYWRvbmx5IG1ldHJpY1NlcnZpY2VOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1ldHJpY05hbWVzcGFjZTogc3RyaW5nO1xuICByZWFkb25seSBsb2dHcm91cERhdGFQcm90ZWN0aW9uOiBMb2dHcm91cERhdGFQcm90ZWN0aW9uUHJvcHM7XG5cbiAgbWV0cmljcygpOiBJTWV0cmljW107XG59Il19
@@ -0,0 +1,3 @@
1
+ export declare class PowertoolsConfig {
2
+ static generateDefaultLambdaConfig(enableObservability?: boolean, metricsNamespace?: string, serviceName?: string): Record<string, string>;
3
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PowertoolsConfig = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ class PowertoolsConfig {
7
+ static generateDefaultLambdaConfig(enableObservability = false, metricsNamespace = 'appmod-catalog', serviceName = 'appmod-catalog-service') {
8
+ if (enableObservability) {
9
+ return {
10
+ POWERTOOLS_METRICS_NAMESPACE: metricsNamespace,
11
+ POWERTOOLS_SERVICE_NAME: serviceName,
12
+ };
13
+ }
14
+ else {
15
+ return {
16
+ POWERTOOLS_METRICS_DISABLED: 'true',
17
+ POWERTOOLS_TRACE_DISABLED: 'true',
18
+ };
19
+ }
20
+ }
21
+ }
22
+ exports.PowertoolsConfig = PowertoolsConfig;
23
+ _a = JSII_RTTI_SYMBOL_1;
24
+ PowertoolsConfig[_a] = { fqn: "@cdklabs/cdk-appmod-catalog-blueprints.PowertoolsConfig", version: "1.0.0" };
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG93ZXJ0b29scy1jb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvdXRpbGl0aWVzL29ic2VydmFiaWxpdHkvcG93ZXJ0b29scy1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxNQUFhLGdCQUFnQjtJQUNwQixNQUFNLENBQUMsMkJBQTJCLENBQUMsc0JBQStCLEtBQUssRUFBRSxtQkFBMkIsZ0JBQWdCLEVBQUUsY0FBc0Isd0JBQXdCO1FBQ3pLLElBQUksbUJBQW1CLEVBQUUsQ0FBQztZQUN4QixPQUFPO2dCQUNMLDRCQUE0QixFQUFFLGdCQUFnQjtnQkFDOUMsdUJBQXVCLEVBQUUsV0FBVzthQUNyQyxDQUFDO1FBQ0osQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPO2dCQUNMLDJCQUEyQixFQUFFLE1BQU07Z0JBQ25DLHlCQUF5QixFQUFFLE1BQU07YUFDbEMsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDOztBQWJILDRDQWNDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIFBvd2VydG9vbHNDb25maWcge1xuICBwdWJsaWMgc3RhdGljIGdlbmVyYXRlRGVmYXVsdExhbWJkYUNvbmZpZyhlbmFibGVPYnNlcnZhYmlsaXR5OiBib29sZWFuID0gZmFsc2UsIG1ldHJpY3NOYW1lc3BhY2U6IHN0cmluZyA9ICdhcHBtb2QtY2F0YWxvZycsIHNlcnZpY2VOYW1lOiBzdHJpbmcgPSAnYXBwbW9kLWNhdGFsb2ctc2VydmljZScpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBpZiAoZW5hYmxlT2JzZXJ2YWJpbGl0eSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgUE9XRVJUT09MU19NRVRSSUNTX05BTUVTUEFDRTogbWV0cmljc05hbWVzcGFjZSxcbiAgICAgICAgUE9XRVJUT09MU19TRVJWSUNFX05BTUU6IHNlcnZpY2VOYW1lLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgUE9XRVJUT09MU19NRVRSSUNTX0RJU0FCTEVEOiAndHJ1ZScsXG4gICAgICAgIFBPV0VSVE9PTFNfVFJBQ0VfRElTQUJMRUQ6ICd0cnVlJyxcbiAgICAgIH07XG4gICAgfVxuICB9XG59Il19
@@ -0,0 +1,27 @@
1
+ import boto3
2
+
3
+ client = boto3.client('bedrock')
4
+
5
+ def handler(event, context):
6
+ request_type = event['RequestType']
7
+
8
+ # Only process CREATE and UPDATE events
9
+ if request_type not in ['Create', 'Update']:
10
+ return
11
+
12
+ current_logging_config = client.get_model_invocation_logging_configuration()
13
+
14
+ # Check if logging is already configured and override is not set
15
+ if current_logging_config.get('loggingConfig') and not event.get('ResourceProperties', {}).get('override', False):
16
+ return
17
+
18
+ # Update logging configuration
19
+ props = event['ResourceProperties']
20
+ client.put_model_invocation_logging_configuration(
21
+ loggingConfig={
22
+ 'cloudWatchConfig': {
23
+ 'logGroupName': props['logGroupName'],
24
+ 'roleArn': props['roleArn']
25
+ }
26
+ }
27
+ )
@@ -0,0 +1,8 @@
1
+ import { InjectionContext, IPropertyInjector } from 'aws-cdk-lib';
2
+ import { LogGroupDataProtectionProps } from './log-group-data-protection-props';
3
+ export declare class StateMachineObservabilityPropertyInjector implements IPropertyInjector {
4
+ readonly constructUniqueId: string;
5
+ readonly logGroupDataProtection: LogGroupDataProtectionProps;
6
+ constructor(logGroupDataProtection: LogGroupDataProtectionProps);
7
+ inject(originalProps: any, _context: InjectionContext): any;
8
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.StateMachineObservabilityPropertyInjector = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
8
+ const aws_logs_1 = require("aws-cdk-lib/aws-logs");
9
+ const aws_stepfunctions_1 = require("aws-cdk-lib/aws-stepfunctions");
10
+ class StateMachineObservabilityPropertyInjector {
11
+ constructor(logGroupDataProtection) {
12
+ this.constructUniqueId = aws_stepfunctions_1.StateMachine.PROPERTY_INJECTION_ID;
13
+ this.logGroupDataProtection = logGroupDataProtection;
14
+ }
15
+ inject(originalProps, _context) {
16
+ const namePrefix = aws_cdk_lib_1.Names.uniqueResourceName(_context.scope, {
17
+ maxLength: 100,
18
+ });
19
+ const { region, account } = aws_cdk_lib_1.Stack.of(_context.scope);
20
+ const logGroupName = `/aws/sfn-statemachine/${namePrefix}-statemachine`;
21
+ const logGroupArn = `arn:aws:logs:${region}:${account}:log-group:${logGroupName}`;
22
+ this.logGroupDataProtection.logGroupEncryptionKey?.grantEncryptDecrypt(new aws_iam_1.ServicePrincipal('logs.amazonaws.com', {
23
+ conditions: {
24
+ ArnEquals: {
25
+ 'kms:EncryptionContext:aws:logs:arn': logGroupArn,
26
+ },
27
+ },
28
+ }));
29
+ return {
30
+ tracingEnabled: true,
31
+ logs: {
32
+ destination: new aws_logs_1.LogGroup(_context.scope, `${_context.id}-LogGroup`, {
33
+ logGroupName,
34
+ encryptionKey: this.logGroupDataProtection.logGroupEncryptionKey,
35
+ dataProtectionPolicy: this.logGroupDataProtection.dataProtectionIdentifiers ? new aws_logs_1.DataProtectionPolicy({
36
+ identifiers: this.logGroupDataProtection.dataProtectionIdentifiers,
37
+ }) : undefined,
38
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
39
+ }),
40
+ level: aws_stepfunctions_1.LogLevel.ALL,
41
+ },
42
+ ...originalProps,
43
+ };
44
+ }
45
+ }
46
+ exports.StateMachineObservabilityPropertyInjector = StateMachineObservabilityPropertyInjector;
47
+ _a = JSII_RTTI_SYMBOL_1;
48
+ StateMachineObservabilityPropertyInjector[_a] = { fqn: "@cdklabs/cdk-appmod-catalog-blueprints.StateMachineObservabilityPropertyInjector", version: "1.0.0" };
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUtbWFjaGluZS1vYnNlcnZhYmlsaXR5LXByb3BlcnR5LWluamVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdXNlLWNhc2VzL3V0aWxpdGllcy9vYnNlcnZhYmlsaXR5L3N0YXRlLW1hY2hpbmUtb2JzZXJ2YWJpbGl0eS1wcm9wZXJ0eS1pbmplY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUErRjtBQUMvRixpREFBdUQ7QUFDdkQsbURBQXNFO0FBQ3RFLHFFQUF1RTtBQUd2RSxNQUFhLHlDQUF5QztJQUlwRCxZQUFZLHNCQUFtRDtRQUM3RCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsZ0NBQVksQ0FBQyxxQkFBcUIsQ0FBQztRQUM1RCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsc0JBQXNCLENBQUM7SUFDdkQsQ0FBQztJQUVELE1BQU0sQ0FBQyxhQUFrQixFQUFFLFFBQTBCO1FBQ25ELE1BQU0sVUFBVSxHQUFHLG1CQUFLLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtZQUMxRCxTQUFTLEVBQUUsR0FBRztTQUNmLENBQUMsQ0FBQztRQUNILE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JELE1BQU0sWUFBWSxHQUFHLHlCQUF5QixVQUFVLGVBQWUsQ0FBQztRQUN4RSxNQUFNLFdBQVcsR0FBRyxnQkFBZ0IsTUFBTSxJQUFJLE9BQU8sY0FBYyxZQUFZLEVBQUUsQ0FBQztRQUNsRixJQUFJLENBQUMsc0JBQXNCLENBQUMscUJBQXFCLEVBQUUsbUJBQW1CLENBQUMsSUFBSSwwQkFBZ0IsQ0FBQyxvQkFBb0IsRUFBRTtZQUNoSCxVQUFVLEVBQUU7Z0JBQ1YsU0FBUyxFQUFFO29CQUNULG9DQUFvQyxFQUFFLFdBQVc7aUJBQ2xEO2FBQ0Y7U0FDRixDQUFDLENBQUMsQ0FBQztRQUVKLE9BQU87WUFDTCxjQUFjLEVBQUUsSUFBSTtZQUNwQixJQUFJLEVBQUU7Z0JBQ0osV0FBVyxFQUFFLElBQUksbUJBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEdBQUcsUUFBUSxDQUFDLEVBQUUsV0FBVyxFQUFFO29CQUNuRSxZQUFZO29CQUNaLGFBQWEsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMscUJBQXFCO29CQUNoRSxvQkFBb0IsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLElBQUksK0JBQW9CLENBQUM7d0JBQ3JHLFdBQVcsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMseUJBQXlCO3FCQUNuRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7b0JBQ2QsYUFBYSxFQUFFLDJCQUFhLENBQUMsT0FBTztpQkFDckMsQ0FBQztnQkFDRixLQUFLLEVBQUUsNEJBQVEsQ0FBQyxHQUFHO2FBQ3BCO1lBQ0QsR0FBRyxhQUFhO1NBQ2pCLENBQUM7SUFDSixDQUFDOztBQXZDSCw4RkF5Q0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3Rpb25Db250ZXh0LCBJUHJvcGVydHlJbmplY3RvciwgTmFtZXMsIFJlbW92YWxQb2xpY3ksIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgU2VydmljZVByaW5jaXBhbCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgRGF0YVByb3RlY3Rpb25Qb2xpY3ksIExvZ0dyb3VwIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0IHsgTG9nTGV2ZWwsIFN0YXRlTWFjaGluZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zJztcbmltcG9ydCB7IExvZ0dyb3VwRGF0YVByb3RlY3Rpb25Qcm9wcyB9IGZyb20gJy4vbG9nLWdyb3VwLWRhdGEtcHJvdGVjdGlvbi1wcm9wcyc7XG5cbmV4cG9ydCBjbGFzcyBTdGF0ZU1hY2hpbmVPYnNlcnZhYmlsaXR5UHJvcGVydHlJbmplY3RvciBpbXBsZW1lbnRzIElQcm9wZXJ0eUluamVjdG9yIHtcbiAgcmVhZG9ubHkgY29uc3RydWN0VW5pcXVlSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbG9nR3JvdXBEYXRhUHJvdGVjdGlvbjogTG9nR3JvdXBEYXRhUHJvdGVjdGlvblByb3BzO1xuXG4gIGNvbnN0cnVjdG9yKGxvZ0dyb3VwRGF0YVByb3RlY3Rpb246IExvZ0dyb3VwRGF0YVByb3RlY3Rpb25Qcm9wcykge1xuICAgIHRoaXMuY29uc3RydWN0VW5pcXVlSWQgPSBTdGF0ZU1hY2hpbmUuUFJPUEVSVFlfSU5KRUNUSU9OX0lEO1xuICAgIHRoaXMubG9nR3JvdXBEYXRhUHJvdGVjdGlvbiA9IGxvZ0dyb3VwRGF0YVByb3RlY3Rpb247XG4gIH1cblxuICBpbmplY3Qob3JpZ2luYWxQcm9wczogYW55LCBfY29udGV4dDogSW5qZWN0aW9uQ29udGV4dCk6IGFueSB7XG4gICAgY29uc3QgbmFtZVByZWZpeCA9IE5hbWVzLnVuaXF1ZVJlc291cmNlTmFtZShfY29udGV4dC5zY29wZSwge1xuICAgICAgbWF4TGVuZ3RoOiAxMDAsXG4gICAgfSk7XG4gICAgY29uc3QgeyByZWdpb24sIGFjY291bnQgfSA9IFN0YWNrLm9mKF9jb250ZXh0LnNjb3BlKTtcbiAgICBjb25zdCBsb2dHcm91cE5hbWUgPSBgL2F3cy9zZm4tc3RhdGVtYWNoaW5lLyR7bmFtZVByZWZpeH0tc3RhdGVtYWNoaW5lYDtcbiAgICBjb25zdCBsb2dHcm91cEFybiA9IGBhcm46YXdzOmxvZ3M6JHtyZWdpb259OiR7YWNjb3VudH06bG9nLWdyb3VwOiR7bG9nR3JvdXBOYW1lfWA7XG4gICAgdGhpcy5sb2dHcm91cERhdGFQcm90ZWN0aW9uLmxvZ0dyb3VwRW5jcnlwdGlvbktleT8uZ3JhbnRFbmNyeXB0RGVjcnlwdChuZXcgU2VydmljZVByaW5jaXBhbCgnbG9ncy5hbWF6b25hd3MuY29tJywge1xuICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICBBcm5FcXVhbHM6IHtcbiAgICAgICAgICAna21zOkVuY3J5cHRpb25Db250ZXh0OmF3czpsb2dzOmFybic6IGxvZ0dyb3VwQXJuLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHJhY2luZ0VuYWJsZWQ6IHRydWUsXG4gICAgICBsb2dzOiB7XG4gICAgICAgIGRlc3RpbmF0aW9uOiBuZXcgTG9nR3JvdXAoX2NvbnRleHQuc2NvcGUsIGAke19jb250ZXh0LmlkfS1Mb2dHcm91cGAsIHtcbiAgICAgICAgICBsb2dHcm91cE5hbWUsXG4gICAgICAgICAgZW5jcnlwdGlvbktleTogdGhpcy5sb2dHcm91cERhdGFQcm90ZWN0aW9uLmxvZ0dyb3VwRW5jcnlwdGlvbktleSxcbiAgICAgICAgICBkYXRhUHJvdGVjdGlvblBvbGljeTogdGhpcy5sb2dHcm91cERhdGFQcm90ZWN0aW9uLmRhdGFQcm90ZWN0aW9uSWRlbnRpZmllcnMgPyBuZXcgRGF0YVByb3RlY3Rpb25Qb2xpY3koe1xuICAgICAgICAgICAgaWRlbnRpZmllcnM6IHRoaXMubG9nR3JvdXBEYXRhUHJvdGVjdGlvbi5kYXRhUHJvdGVjdGlvbklkZW50aWZpZXJzLFxuICAgICAgICAgIH0pIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHJlbW92YWxQb2xpY3k6IFJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICAgICAgfSksXG4gICAgICAgIGxldmVsOiBMb2dMZXZlbC5BTEwsXG4gICAgICB9LFxuICAgICAgLi4ub3JpZ2luYWxQcm9wcyxcbiAgICB9O1xuICB9XG5cbn0iXX0=
@@ -0,0 +1 @@
1
+ export {};