quidproquo-deploy-awscdk 0.0.96 → 0.0.97

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.
@@ -1,2 +1 @@
1
1
  export declare const QPQ_LOG_BUCKET_NAME = "logs";
2
- export declare const QPQ_FROM_LOG_BUCKET_NAME = "flogs";
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QPQ_FROM_LOG_BUCKET_NAME = exports.QPQ_LOG_BUCKET_NAME = void 0;
3
+ exports.QPQ_LOG_BUCKET_NAME = void 0;
4
4
  exports.QPQ_LOG_BUCKET_NAME = 'logs';
5
- exports.QPQ_FROM_LOG_BUCKET_NAME = 'flogs';
@@ -86,7 +86,7 @@ class Function extends QpqConstructBlock_1.QpqConstructBlock {
86
86
  // 'aws:ResourceTag/Name': '*qpqlog',
87
87
  // },
88
88
  // },
89
- resources: ['arn:aws:dynamodb:*:*:table/logs-*', 'arn:aws:dynamodb:*:*:table/flogs-*'],
89
+ resources: ['arn:aws:dynamodb:*:*:table/logs-*'],
90
90
  }));
91
91
  }
92
92
  }
@@ -7,14 +7,16 @@ export interface LogStorageProps extends QpqConstructBlockProps {
7
7
  }
8
8
  export declare abstract class LogStorageConstructBase extends QpqConstructBlock implements QpqResource {
9
9
  abstract bucket: aws_s3.IBucket;
10
- abstract table: aws_dynamodb.ITable;
10
+ abstract storyResultsTable: aws_dynamodb.ITable;
11
+ abstract fromStoryResultsTable: aws_dynamodb.ITable;
11
12
  grantRead(grantee: aws_iam.IGrantable): aws_iam.Grant;
12
13
  grantWrite(grantee: aws_iam.IGrantable): aws_iam.Grant;
13
14
  grantAll(grantee: aws_iam.IGrantable): void;
14
15
  }
15
16
  export declare class LogStorage extends QpqConstructBlock {
16
17
  readonly bucket: aws_s3.IBucket;
17
- readonly table: aws_dynamodb.ITable;
18
+ readonly storyResultsTable: aws_dynamodb.ITable;
19
+ readonly fromStoryResultsTable: aws_dynamodb.ITable;
18
20
  static fromOtherStack(scope: Construct, id: string, qpqConfig: QPQConfig, awsAccountId: string, serviceBucketName: string): QpqResource;
19
21
  constructor(scope: Construct, id: string, props: LogStorageProps);
20
22
  }
@@ -35,11 +35,13 @@ const constants_1 = require("../../constants");
35
35
  const Function_1 = require("./Function");
36
36
  class LogStorageConstructBase extends QpqConstructBlock_1.QpqConstructBlock {
37
37
  grantRead(grantee) {
38
- this.table.grantReadData(grantee);
38
+ this.storyResultsTable.grantReadData(grantee);
39
+ this.fromStoryResultsTable.grantReadData(grantee);
39
40
  return this.bucket.grantRead(grantee);
40
41
  }
41
42
  grantWrite(grantee) {
42
- this.table.grantWriteData(grantee);
43
+ this.storyResultsTable.grantWriteData(grantee);
44
+ this.fromStoryResultsTable.grantWriteData(grantee);
43
45
  return this.bucket.grantWrite(grantee);
44
46
  }
45
47
  grantAll(grantee) {
@@ -54,7 +56,8 @@ class LogStorage extends QpqConstructBlock_1.QpqConstructBlock {
54
56
  constructor() {
55
57
  super(...arguments);
56
58
  this.bucket = aws_cdk_lib_1.aws_s3.Bucket.fromBucketName(scope, `${id}-log-storage`, this.qpqResourceName(serviceBucketName, 'log'));
57
- this.table = aws_cdk_lib_1.aws_dynamodb.Table.fromTableName(scope, `${id}-table`, this.qpqResourceName(serviceBucketName, 'log'));
59
+ this.storyResultsTable = aws_cdk_lib_1.aws_dynamodb.Table.fromTableName(scope, `${id}-log-table`, this.qpqResourceName(serviceBucketName, 'log'));
60
+ this.fromStoryResultsTable = aws_cdk_lib_1.aws_dynamodb.Table.fromTableName(scope, `${id}-flog-table`, this.qpqResourceName(serviceBucketName, 'flog'));
58
61
  }
59
62
  }
60
63
  return new Import(scope, id, { qpqConfig, awsAccountId });
@@ -87,13 +90,14 @@ class LogStorage extends QpqConstructBlock_1.QpqConstructBlock {
87
90
  // Also, we cant have a GSI on keys that can be undefined, this table will only contain
88
91
  // logs with a fromCorrelation
89
92
  const fromStoryResultsTable = new aws_cdk_lib_1.aws_dynamodb.Table(this, 'from-table', {
90
- tableName: this.qpqResourceName(constants_1.QPQ_FROM_LOG_BUCKET_NAME, 'flog'),
93
+ tableName: this.qpqResourceName(constants_1.QPQ_LOG_BUCKET_NAME, 'flog'),
91
94
  partitionKey: { name: 'fromCorrelation', type: aws_cdk_lib_1.aws_dynamodb.AttributeType.STRING },
92
95
  sortKey: { name: 'startedAtWithCorrelation', type: aws_cdk_lib_1.aws_dynamodb.AttributeType.STRING },
93
96
  billingMode: aws_cdk_lib_1.aws_dynamodb.BillingMode.PAY_PER_REQUEST,
94
97
  removalPolicy: cdk.RemovalPolicy.DESTROY,
95
98
  });
96
- this.table = storyResultsTable;
99
+ this.storyResultsTable = storyResultsTable;
100
+ this.fromStoryResultsTable = fromStoryResultsTable;
97
101
  // Create a lambda that is trigged when files are written to the bucket
98
102
  const func = new Function_1.Function(this, 'function', {
99
103
  buildPath: path_1.default.join(__dirname, '../..'),
@@ -5,6 +5,6 @@ const quidproquo_core_1 = require("quidproquo-core");
5
5
  const quidproquo_actionprocessor_awslambda_1 = require("quidproquo-actionprocessor-awslambda");
6
6
  const getRuntimeCorrelation = (qpqConfig) => {
7
7
  const moduleName = quidproquo_core_1.qpqCoreUtils.getApplicationModuleName(qpqConfig);
8
- return `${moduleName}-${quidproquo_actionprocessor_awslambda_1.awsLambdaUtils.randomGuid()}`;
8
+ return `${moduleName}::${quidproquo_actionprocessor_awslambda_1.awsLambdaUtils.randomGuid()}`;
9
9
  };
10
10
  exports.getRuntimeCorrelation = getRuntimeCorrelation;
@@ -10,27 +10,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.getLogger = exports.storyLogger = void 0;
13
+ const client_s3_1 = require("@aws-sdk/client-s3");
14
+ const quidproquo_actionprocessor_awslambda_1 = require("quidproquo-actionprocessor-awslambda");
15
+ const quidproquo_core_1 = require("quidproquo-core");
16
+ const constants_1 = require("../../constants");
13
17
  const storyLogger = (result, qpqConfig) => __awaiter(void 0, void 0, void 0, function* () {
14
- /*
15
-
16
- const bucketName = awsNamingUtils.getQpqRuntimeResourceNameFromConfig(
17
- QPQ_LOG_BUCKET_NAME,
18
- qpqConfig,
19
- 'log',
20
- );
21
- const region = qpqCoreUtils.getApplicationModuleDeployRegion(qpqConfig);
22
-
23
- const s3Client = new S3Client({ region });
24
-
25
- await s3Client.send(
26
- new PutObjectCommand({
18
+ const bucketName = quidproquo_actionprocessor_awslambda_1.awsNamingUtils.getQpqRuntimeResourceNameFromConfig(constants_1.QPQ_LOG_BUCKET_NAME, qpqConfig, 'log');
19
+ const region = quidproquo_core_1.qpqCoreUtils.getApplicationModuleDeployRegion(qpqConfig);
20
+ const s3Client = new client_s3_1.S3Client({ region });
21
+ yield s3Client.send(new client_s3_1.PutObjectCommand({
27
22
  Key: `${result.correlation}.json`,
28
23
  Bucket: bucketName,
29
24
  Body: JSON.stringify(result),
30
- }),
31
- );
32
-
33
- */
25
+ }));
34
26
  });
35
27
  exports.storyLogger = storyLogger;
36
28
  const getLogger = (qpqConfig) => (result) => __awaiter(void 0, void 0, void 0, function* () {
@@ -38,6 +38,7 @@ const writeStoryResultMetadataToDynamo = (tableName, storyResultMetadata, region
38
38
  S: `${storyResultMetadata.startedAt}#${storyResultMetadata.correlation}`,
39
39
  },
40
40
  runtimeType: { S: storyResultMetadata.runtimeType },
41
+ correlation: { S: storyResultMetadata.correlation },
41
42
  error: { S: storyResultMetadata.error || '' },
42
43
  generic: { S: storyResultMetadata.generic },
43
44
  moduleName: { S: storyResultMetadata.moduleName },
@@ -70,18 +71,27 @@ const getFromCorrelationBucketNameFromLog = (storyResultMetadata, localBucketNam
70
71
  return newBucketName;
71
72
  };
72
73
  exports.getFromCorrelationBucketNameFromLog = getFromCorrelationBucketNameFromLog;
74
+ function getFromCorrelationDynamoTableNameFromBucketName(bucketName) {
75
+ const target = 'qpqlog';
76
+ const replacement = 'qpqflog';
77
+ if (bucketName.endsWith(target)) {
78
+ return bucketName.slice(0, bucketName.length - target.length) + replacement;
79
+ }
80
+ return bucketName;
81
+ }
73
82
  const executeS3FileWriteEvent = (event) => __awaiter(void 0, void 0, void 0, function* () {
74
83
  for (const record of event.Records) {
75
84
  const bucketName = record.s3.bucket.name;
76
85
  const awsRegion = record.awsRegion;
77
- const key = record.s3.object.key;
86
+ const key = decodeURIComponent(record.s3.object.key);
78
87
  const storyResultMetadata = yield readLogFromBucket(bucketName, awsRegion, key);
79
88
  // Write the main log to the service table
80
89
  yield writeStoryResultMetadataToDynamo(bucketName, storyResultMetadata, awsRegion);
81
90
  // Write the same log to the table of the from service, so it can query links on the fromGuid GSI
82
91
  const fromBucketName = (0, exports.getFromCorrelationBucketNameFromLog)(storyResultMetadata, bucketName);
83
- if (fromBucketName) {
84
- yield writeStoryResultMetadataToDynamo(fromBucketName, storyResultMetadata, awsRegion);
92
+ const targetFromCorrelationDynamoTableName = getFromCorrelationDynamoTableNameFromBucketName(fromBucketName);
93
+ if (targetFromCorrelationDynamoTableName) {
94
+ yield writeStoryResultMetadataToDynamo(targetFromCorrelationDynamoTableName, storyResultMetadata, awsRegion);
85
95
  }
86
96
  }
87
97
  });
@@ -9,10 +9,10 @@ class InfQpqServiceStack extends QpqServiceStack_1.QpqServiceStack {
9
9
  constructor(scope, id, props) {
10
10
  super(scope, id, props);
11
11
  // Build the log storage drive
12
- // const logBucket = new LogStorage(this, 'logStorage', {
13
- // awsAccountId: props.awsAccountId,
14
- // qpqConfig: props.qpqConfig,
15
- // }).bucket;
12
+ const logBucket = new constructs_1.LogStorage(this, 'logStorage', {
13
+ awsAccountId: props.awsAccountId,
14
+ qpqConfig: props.qpqConfig,
15
+ }).bucket;
16
16
  // Build the storage drives
17
17
  const storageDrives = quidproquo_core_1.qpqCoreUtils.getStorageDrives(props.qpqConfig).map((setting) => new constructs_1.QpqCoreStorageDriveConstruct(this, quidproquo_core_1.qpqCoreUtils.getUniqueKeyForSetting(setting), {
18
18
  awsAccountId: props.awsAccountId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-deploy-awscdk",
3
- "version": "0.0.96",
3
+ "version": "0.0.97",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.js",
@@ -1,2 +1 @@
1
1
  export const QPQ_LOG_BUCKET_NAME = 'logs';
2
- export const QPQ_FROM_LOG_BUCKET_NAME = 'flogs';
@@ -109,7 +109,7 @@ export class Function extends QpqConstructBlock {
109
109
  // 'aws:ResourceTag/Name': '*qpqlog',
110
110
  // },
111
111
  // },
112
- resources: ['arn:aws:dynamodb:*:*:table/logs-*', 'arn:aws:dynamodb:*:*:table/flogs-*'],
112
+ resources: ['arn:aws:dynamodb:*:*:table/logs-*'],
113
113
  }),
114
114
  );
115
115
  }
@@ -6,7 +6,7 @@ import { aws_s3, aws_iam, aws_dynamodb, aws_s3_notifications } from 'aws-cdk-lib
6
6
  import * as cdk from 'aws-cdk-lib';
7
7
  import { QpqResource } from '../base';
8
8
  import { QPQConfig } from 'quidproquo-core/lib';
9
- import { QPQ_LOG_BUCKET_NAME, QPQ_FROM_LOG_BUCKET_NAME } from '../../constants';
9
+ import { QPQ_LOG_BUCKET_NAME } from '../../constants';
10
10
  import { Function } from './Function';
11
11
  // import { qpqWebServerUtils } from '../../utils';
12
12
 
@@ -14,15 +14,18 @@ export interface LogStorageProps extends QpqConstructBlockProps {}
14
14
 
15
15
  export abstract class LogStorageConstructBase extends QpqConstructBlock implements QpqResource {
16
16
  abstract bucket: aws_s3.IBucket;
17
- abstract table: aws_dynamodb.ITable;
17
+ abstract storyResultsTable: aws_dynamodb.ITable;
18
+ abstract fromStoryResultsTable: aws_dynamodb.ITable;
18
19
 
19
20
  public grantRead(grantee: aws_iam.IGrantable): aws_iam.Grant {
20
- this.table.grantReadData(grantee);
21
+ this.storyResultsTable.grantReadData(grantee);
22
+ this.fromStoryResultsTable.grantReadData(grantee);
21
23
  return this.bucket.grantRead(grantee);
22
24
  }
23
25
 
24
26
  public grantWrite(grantee: aws_iam.IGrantable): aws_iam.Grant {
25
- this.table.grantWriteData(grantee);
27
+ this.storyResultsTable.grantWriteData(grantee);
28
+ this.fromStoryResultsTable.grantWriteData(grantee);
26
29
  return this.bucket.grantWrite(grantee);
27
30
  }
28
31
 
@@ -34,7 +37,8 @@ export abstract class LogStorageConstructBase extends QpqConstructBlock implemen
34
37
 
35
38
  export class LogStorage extends QpqConstructBlock {
36
39
  public readonly bucket: aws_s3.IBucket;
37
- public readonly table: aws_dynamodb.ITable;
40
+ public readonly storyResultsTable: aws_dynamodb.ITable;
41
+ public readonly fromStoryResultsTable: aws_dynamodb.ITable;
38
42
 
39
43
  static fromOtherStack(
40
44
  scope: Construct,
@@ -50,11 +54,17 @@ export class LogStorage extends QpqConstructBlock {
50
54
  this.qpqResourceName(serviceBucketName, 'log'),
51
55
  );
52
56
 
53
- table = aws_dynamodb.Table.fromTableName(
57
+ storyResultsTable = aws_dynamodb.Table.fromTableName(
54
58
  scope,
55
- `${id}-table`,
59
+ `${id}-log-table`,
56
60
  this.qpqResourceName(serviceBucketName, 'log'),
57
61
  );
62
+
63
+ fromStoryResultsTable = aws_dynamodb.Table.fromTableName(
64
+ scope,
65
+ `${id}-flog-table`,
66
+ this.qpqResourceName(serviceBucketName, 'flog'),
67
+ );
58
68
  }
59
69
 
60
70
  return new Import(scope, id, { qpqConfig, awsAccountId });
@@ -94,14 +104,15 @@ export class LogStorage extends QpqConstructBlock {
94
104
  // Also, we cant have a GSI on keys that can be undefined, this table will only contain
95
105
  // logs with a fromCorrelation
96
106
  const fromStoryResultsTable = new aws_dynamodb.Table(this, 'from-table', {
97
- tableName: this.qpqResourceName(QPQ_FROM_LOG_BUCKET_NAME, 'flog'),
107
+ tableName: this.qpqResourceName(QPQ_LOG_BUCKET_NAME, 'flog'),
98
108
  partitionKey: { name: 'fromCorrelation', type: aws_dynamodb.AttributeType.STRING },
99
109
  sortKey: { name: 'startedAtWithCorrelation', type: aws_dynamodb.AttributeType.STRING },
100
110
  billingMode: aws_dynamodb.BillingMode.PAY_PER_REQUEST,
101
111
  removalPolicy: cdk.RemovalPolicy.DESTROY,
102
112
  });
103
113
 
104
- this.table = storyResultsTable;
114
+ this.storyResultsTable = storyResultsTable;
115
+ this.fromStoryResultsTable = fromStoryResultsTable;
105
116
 
106
117
  // Create a lambda that is trigged when files are written to the bucket
107
118
  const func = new Function(this, 'function', {
@@ -3,5 +3,5 @@ import { awsLambdaUtils } from 'quidproquo-actionprocessor-awslambda';
3
3
 
4
4
  export const getRuntimeCorrelation = (qpqConfig: QPQConfig): string => {
5
5
  const moduleName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
- return `${moduleName}-${awsLambdaUtils.randomGuid()}`;
6
+ return `${moduleName}::${awsLambdaUtils.randomGuid()}`;
7
7
  };
@@ -10,8 +10,6 @@ export const storyLogger = async (
10
10
  result: StoryResult<any>,
11
11
  qpqConfig: QPQConfig,
12
12
  ): Promise<void> => {
13
- /*
14
-
15
13
  const bucketName = awsNamingUtils.getQpqRuntimeResourceNameFromConfig(
16
14
  QPQ_LOG_BUCKET_NAME,
17
15
  qpqConfig,
@@ -28,8 +26,6 @@ export const storyLogger = async (
28
26
  Body: JSON.stringify(result),
29
27
  }),
30
28
  );
31
-
32
- */
33
29
  };
34
30
 
35
31
  export const getLogger = (qpqConfig: QPQConfig) => async (result: StoryResult<any>) => {
@@ -17,7 +17,6 @@ import {
17
17
  getConfigGetParametersActionProcessor,
18
18
  getServiceFunctionActionProcessor,
19
19
  getAdminActionProcessor,
20
- awsLambdaUtils,
21
20
  DynamicModuleLoader,
22
21
  LambdaRuntimeConfig,
23
22
  } from 'quidproquo-actionprocessor-awslambda';
@@ -45,6 +45,7 @@ const writeStoryResultMetadataToDynamo = async (
45
45
  S: `${storyResultMetadata.startedAt}#${storyResultMetadata.correlation}`,
46
46
  },
47
47
  runtimeType: { S: storyResultMetadata.runtimeType },
48
+ correlation: { S: storyResultMetadata.correlation },
48
49
  error: { S: storyResultMetadata.error || '' },
49
50
  generic: { S: storyResultMetadata.generic },
50
51
  moduleName: { S: storyResultMetadata.moduleName },
@@ -87,11 +88,22 @@ export const getFromCorrelationBucketNameFromLog = (
87
88
  return newBucketName;
88
89
  };
89
90
 
91
+ function getFromCorrelationDynamoTableNameFromBucketName(bucketName: string): string {
92
+ const target = 'qpqlog';
93
+ const replacement = 'qpqflog';
94
+
95
+ if (bucketName.endsWith(target)) {
96
+ return bucketName.slice(0, bucketName.length - target.length) + replacement;
97
+ }
98
+
99
+ return bucketName;
100
+ }
101
+
90
102
  export const executeS3FileWriteEvent: S3Handler = async (event: S3Event) => {
91
103
  for (const record of event.Records) {
92
104
  const bucketName = record.s3.bucket.name;
93
105
  const awsRegion = record.awsRegion;
94
- const key = record.s3.object.key;
106
+ const key = decodeURIComponent(record.s3.object.key);
95
107
 
96
108
  const storyResultMetadata = await readLogFromBucket(bucketName, awsRegion, key);
97
109
 
@@ -100,8 +112,16 @@ export const executeS3FileWriteEvent: S3Handler = async (event: S3Event) => {
100
112
 
101
113
  // Write the same log to the table of the from service, so it can query links on the fromGuid GSI
102
114
  const fromBucketName = getFromCorrelationBucketNameFromLog(storyResultMetadata, bucketName);
103
- if (fromBucketName) {
104
- await writeStoryResultMetadataToDynamo(fromBucketName, storyResultMetadata, awsRegion);
115
+
116
+ const targetFromCorrelationDynamoTableName =
117
+ getFromCorrelationDynamoTableNameFromBucketName(fromBucketName);
118
+
119
+ if (targetFromCorrelationDynamoTableName) {
120
+ await writeStoryResultMetadataToDynamo(
121
+ targetFromCorrelationDynamoTableName,
122
+ storyResultMetadata,
123
+ awsRegion,
124
+ );
105
125
  }
106
126
  }
107
127
  };
@@ -24,10 +24,10 @@ export class InfQpqServiceStack extends QpqServiceStack {
24
24
  super(scope, id, props);
25
25
 
26
26
  // Build the log storage drive
27
- // const logBucket = new LogStorage(this, 'logStorage', {
28
- // awsAccountId: props.awsAccountId,
29
- // qpqConfig: props.qpqConfig,
30
- // }).bucket;
27
+ const logBucket = new LogStorage(this, 'logStorage', {
28
+ awsAccountId: props.awsAccountId,
29
+ qpqConfig: props.qpqConfig,
30
+ }).bucket;
31
31
 
32
32
  // Build the storage drives
33
33
  const storageDrives = qpqCoreUtils.getStorageDrives(props.qpqConfig).map(