diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml index 5924ccd8b727e..61fa5967b2722 100644 --- a/.github/workflows/close-stale-issues.yml +++ b/.github/workflows/close-stale-issues.yml @@ -8,6 +8,8 @@ on: jobs: cleanup: + # this workflow will always fail in forks; bail if this isn't running in the upstream + if: github.repository == 'aws/aws-cdk' permissions: issues: write contents: read diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml index d8543bc1725df..4fe804c13ad34 100644 --- a/.github/workflows/close-stale-prs.yml +++ b/.github/workflows/close-stale-prs.yml @@ -5,6 +5,8 @@ on: workflow_dispatch: jobs: close-stale-prs: + # this workflow will always fail in forks; bail if this isn't running in the upstream + if: github.repository == 'aws/aws-cdk' permissions: pull-requests: write runs-on: ubuntu-latest diff --git a/.github/workflows/handle-stale-discussions.yml b/.github/workflows/handle-stale-discussions.yml index 2b89f2da15f21..7a5ad637905f9 100644 --- a/.github/workflows/handle-stale-discussions.yml +++ b/.github/workflows/handle-stale-discussions.yml @@ -7,6 +7,8 @@ on: jobs: handle-stale-discussions: + # this workflow will always fail in forks; bail if this isn't running in the upstream + if: github.repository == 'aws/aws-cdk' name: Handle stale discussions runs-on: ubuntu-latest permissions: @@ -15,4 +17,4 @@ jobs: - name: Stale discussions action uses: aws-github-ops/handle-stale-discussions@v1 env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} \ No newline at end of file + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/repo-metrics.yml b/.github/workflows/repo-metrics.yml index cba553913c84b..221f5de888bed 100644 --- a/.github/workflows/repo-metrics.yml +++ b/.github/workflows/repo-metrics.yml @@ -10,6 +10,8 @@ permissions: jobs: build: + # this workflow will always fail in forks; bail if this isn't running in the upstream + if: github.repository == 'aws/aws-cdk' name: metrics runs-on: ubuntu-latest diff --git a/.github/workflows/spec-update.yml b/.github/workflows/spec-update.yml index 87100ae462fac..008ad8f58bdff 100644 --- a/.github/workflows/spec-update.yml +++ b/.github/workflows/spec-update.yml @@ -8,6 +8,8 @@ on: jobs: update-spec: + # this workflow will always fail in forks; bail if this isn't running in the upstream + if: github.repository == 'aws/aws-cdk' name: Update AWS Service Spec packages permissions: contents: read diff --git a/ROADMAP.md b/ROADMAP.md index 57e75eb0eaa34..96f53bd34dda2 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,48 +1,64 @@ # AWS CDK Roadmap -The [AWS CDK Roadmap] lets developers know about our upcoming features and priorities to help them plan how to best leverage the CDK and identify opportunities to contribute to the project. The roadmap provides a high-level view of our work in progress across the [aws-cdk], [aws-cdk-rfcs], and [jsii] repositories, and creates an opportunity for customers to engage in a conversation with AWS CDK engineers to give us direct feedback. +The [AWS CDK Roadmap] lets developers know about our upcoming features and priorities to help them +plan how to best leverage the CDK and identify opportunities to contribute to the project. The roadmap +provides a high-level view of our work in progress across the [aws-cdk], [aws-cdk-rfcs], and [jsii] +repositories, and creates an opportunity for customers to engage in a conversation with AWS CDK engineers to +give us direct feedback. -[AWS CDK Roadmap]: https://github.com/orgs/aws/projects/7 +[AWS CDK Roadmap]: https://github.com/orgs/aws/projects/88 [aws-cdk]: https://github.com/aws/aws-cdk [aws-cdk-rfcs]: https://github.com/aws/aws-cdk-rfcs [jsii]: https://github.com/aws/jsii -## Roadmap FAQs +## Tenets +The core values for CDK on how to prioritize work, keep engaged with the community and deliver what matters. +1. **Be transparent** -**Q: How do you manage the roadmap?** +The AWS CDK team’s current work should be easily visible. + +2. **Listen to customers** + +Allow them to participate in design decisions and to vote on and propose new AWS CDK features. We will periodically re-prioritize the roadmap based on customer feedback. -A: We know that our customers are making decisions and plans based on what we -are developing, and we want to provide the information they need to be successful. Our roadmap management tenets are: +3. **Stay up-to-date** -* **Be transparent** with customers about the AWS CDK team’s work in progress -* **Listen to customers,** allowing them to participate in design decisions and to vote on and propose new AWS CDK - features. We will periodically re-prioritize the roadmap based on customer feedback -* **Stay up-to-date,** or we will lose customer trust -* **Provide the right level of detail** so customers can easily see what we’re working on at a glance, without being - overwhelmed by minutiae -* **Guide the community** on what AWS CDK constructs or features to contribute without the risk of conflicting with work - already in progress +Be informed and incorporate best practices. -**Q: What do the roadmap project board columns mean?** +4. **Provide the right level of detail** -A: There are four columns on the roadmap project board: +The overview should indicate all work in progress at a glance, while allowing a deep dive into the details via provided references. -* **Researching** - We’re thinking about it, but cannot commit if, or when, we will work on items in this list. +5. **Guide the community** + +Align on what can be worked on that is not currently handled by the team. +Offer help and unblock contributors in their efforts. + +## Roadmap FAQs +**Q: How do you manage the roadmap?** + +A: CDK customers are making decisions and plans based on what we are developing. We strive to provide the +required information, when that is not sufficient, we take note of the feedback we receive and iterate on how +to bring improvements to our current processes and available information. + +**Q: How do you mark work in progress?** + +A: For the [aws-cdk] repository, any issue that is currently worked on will have the `CDK Construct Squad` project +listed, with the current status. + +* **Needs Review** - We’re thinking about it, but cannot commit if, or when, we will work on items in this list. This means we are still designing the feature and evaluating how it might work. This is the phase when we collect customer use cases and feedback on how they want to see something implemented. There is no firm commitment to deliver - functionality listed in the Researching column, and there might be situations that require us to move items from the - roadmap back to the backlog. -* **We’re working on it** - In progress, but further out. We have made an implied commitment to work on items in this - bucket, they have some level of design spec’ed out, and a developer assigned to them. Items might linger in this - bucket as we work through the implementation details, or scope stuff out. Think several months out until a developer - preview release, give or take. -* **Developer preview** - It’s available now as a release candidate. Items will spend extended periods of time in - developer preview as we conduct user acceptance testing and accumulate sufficient usage to declare the API stable and - ready for general availability. We will only make breaking changes to developer preview modules when we need to address unforeseen use cases or issues. Not all - features, such as enhancements to the CDK CLI, will have a developer preview phase. In these cases the tracking issue - is moved directly to the Shipped bucket when released. -* **Shipped** - It’s available now, fully supported by AWS, and we guarantee the API is stable and safe to use in - production. + functionality listed in the Needs Review column, and there might be situations where we remove items from the Needs + Review column. +* **Backlog** - We want to do this, but no one has picked it up yet. We have made an implied commitment to work on items + in this bucket, they have some level of design spec’ed out. Items might linger in this bucket as we work through the implementation details, or scope stuff out. Think several months out until a developer preview release, give or take. +* **In Progress** - Someone on the CDK team is actively working on this. If all goes well, issues in this bucket should + be released in the coming weeks. +* **In review** - It’s implementation is done and we are reviewing the code. +* **Done** - It’s available now, fully supported by AWS. + +For the [aws-cdk-rfcs], the README file contains the overview and statuses. They can also be checked per RFC by selecting any of the relevant [issues](https://github.com/aws/aws-cdk-rfcs/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) and seeing how far along is its `Workflow`. **Q: How do items on the roadmap move across the project board?** @@ -71,7 +87,7 @@ A: We create a tracking issue for each CDK feature, AWS Construct Library module **Q: How can I provide feedback on the roadmap or ask for more information about a feature?** -A: Please open an issue! +A: Please open an issue! Or engage by 👍 existing ones. **Q: How can I request a feature be added to the roadmap?** @@ -79,7 +95,7 @@ A: Please open an issue! Community submitted issues will be tagged “feature-re **Q: Can I “+1” tracking issues and feature requests?** -A: We strongly encourage you to do so, as it helps us understand which issues will have the broadest impact. You can navigate to the issue details page and add a reaction. There are six types of reactions (thumbs up “+1”, thumbs down “-1”, confused, heart, watching, laugh, and hooray) you can use to help us decide which items will benefit you most. +A: We strongly encourage you to do so, as it helps us understand which issues will have the broadest impact. You can navigate to the issue details page and add a reaction. There are six types of reactions (👍 +1, 👎 -1, 😕 confused, ❤️ heart, 👀 watching, 😄 smile, and 🎉 celebration) you can use to help us decide which items will benefit you most. **Q: Will you accept a pull request to the aws-cdk repo?** diff --git a/allowed-breaking-changes.txt b/allowed-breaking-changes.txt index 7568e050d7ecd..99fbbed4cc359 100644 --- a/allowed-breaking-changes.txt +++ b/allowed-breaking-changes.txt @@ -164,3 +164,12 @@ removed:aws-cdk-lib.triggers.TriggerProps.timeout change-return-type:aws-cdk-lib.aws_ec2.SecurityGroup.determineRuleScope # broken only in non-JS/TS, where that was not previously usable strengthened:aws-cdk-lib.aws_s3_deployment.BucketDeploymentProps + +# Fix for non-working property +# loadBalancerName is used to idenitfy a Classic Load Balancer +# However TaskSet only works with modern Application or Network LBs +removed:aws-cdk-lib.aws_ecs.CfnTaskSet.LoadBalancerProperty.loadBalancerName + +# Introduction of a new feature +# Previously only BlueGreenUpdatePolicy could be set, now BlueGreenUpdatePolicy or new RollingUpdatePolicy can be provided +weakened:aws-cdk-lib.aws_sagemaker.CfnEndpoint.DeploymentConfigProperty diff --git a/packages/@aws-cdk/aws-batch-alpha/test/integ.batch-unique-name.js.snapshot/cdk.out b/packages/@aws-cdk/aws-batch-alpha/test/integ.batch-unique-name.js.snapshot/cdk.out index f0b901e7c06e5..7df7694e7a5a5 100644 --- a/packages/@aws-cdk/aws-batch-alpha/test/integ.batch-unique-name.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-batch-alpha/test/integ.batch-unique-name.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"32.0.0"} \ No newline at end of file +{"version":"32.0.0"} diff --git a/packages/@aws-cdk/aws-glue-alpha/README.md b/packages/@aws-cdk/aws-glue-alpha/README.md index 8044d470c0b4d..64ac86f8c6b9b 100644 --- a/packages/@aws-cdk/aws-glue-alpha/README.md +++ b/packages/@aws-cdk/aws-glue-alpha/README.md @@ -223,7 +223,25 @@ new glue.Table(this, 'MyTable', { }); ``` -By default, an S3 bucket will be created to store the table's data and stored in the bucket root. You can also manually pass the `bucket` and `s3Prefix`: +Glue tables can be configured to contain user-defined properties, to describe the physical storage of table data, through the `storageParameters` property: + +```ts +declare const myDatabase: glue.Database; +new glue.Table(this, 'MyTable', { + storageParameters: [ + glue.StorageParameter.skipHeaderLineCount(1), + glue.StorageParameter.compressionType(glue.CompressionType.GZIP), + glue.StorageParameter.custom('separatorChar', ',') + ], + // ... + database: myDatabase, + columns: [{ + name: 'col1', + type: glue.Schema.STRING, + }], + dataFormat: glue.DataFormat.JSON, +}); +``` ### Partition Keys diff --git a/packages/@aws-cdk/aws-glue-alpha/lib/index.ts b/packages/@aws-cdk/aws-glue-alpha/lib/index.ts index 8a416993bb5ba..c6a611242c925 100644 --- a/packages/@aws-cdk/aws-glue-alpha/lib/index.ts +++ b/packages/@aws-cdk/aws-glue-alpha/lib/index.ts @@ -1,12 +1,13 @@ // AWS::Glue CloudFormation Resources: +export * from './code'; export * from './connection'; export * from './data-format'; export * from './data-quality-ruleset'; export * from './database'; export * from './job'; export * from './job-executable'; -export * from './code'; export * from './schema'; export * from './security-configuration'; -export * from './table'; \ No newline at end of file +export * from './storage-parameter'; +export * from './table'; diff --git a/packages/@aws-cdk/aws-glue-alpha/lib/storage-parameter.ts b/packages/@aws-cdk/aws-glue-alpha/lib/storage-parameter.ts new file mode 100644 index 0000000000000..50b1ad934d712 --- /dev/null +++ b/packages/@aws-cdk/aws-glue-alpha/lib/storage-parameter.ts @@ -0,0 +1,423 @@ +/** + * The compression type. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"compression_type"_ + */ +export enum CompressionType { + /** + * No compression. + */ + NONE = 'none', + + /** + * Burrows-Wheeler compression. + */ + BZIP2 = 'bzip2', + + /** + * Deflate compression. + */ + GZIP = 'gzip', + + /** + * Compression algorithm focused on high compression and decompression speeds, rather than the maximum possible compression. + */ + SNAPPY = 'snappy', +} + +/** + * Specifies the action to perform when query results contain invalid UTF-8 character values. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"invalid_char_handling"_ + */ +export enum InvalidCharHandlingAction { + /** + * Doesn't perform invalid character handling. + */ + DISABLED = 'DISABLED', + + /** + * Cancels queries that return data containing invalid UTF-8 values. + */ + FAIL = 'FAIL', + + /** + * Replaces invalid UTF-8 values with null. + */ + SET_TO_NULL = 'SET_TO_NULL', + + /** + * Replaces each value in the row with null. + */ + DROP_ROW = 'DROP_ROW', + + /** + * Replaces the invalid character with the replacement character you specify using `REPLACEMENT_CHAR`. + */ + REPLACE = 'REPLACE', +} + +/** + * Specifies the action to perform when ORC data contains an integer (for example, BIGINT or int64) that is larger than the column definition (for example, SMALLINT or int16). + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"numeric_overflow_handling"_ + */ +export enum NumericOverflowHandlingAction { + /** + * Invalid character handling is turned off. + */ + DISABLED = 'DISABLED', + + /** + * Cancel the query when the data includes invalid characters. + */ + FAIL = 'FAIL', + + /** + * Set invalid characters to null. + */ + SET_TO_NULL = 'SET_TO_NULL', + + /** + * Set each value in the row to null. + */ + DROP_ROW = 'DROP_ROW', +} + +/** + * Specifies how to handle data being loaded that exceeds the length of the data type defined for columns containing VARBYTE data. By default, Redshift Spectrum sets the value to null for data that exceeds the width of the column. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"surplus_bytes_handling"_ + */ +export enum SurplusBytesHandlingAction { + /** + * Replaces data that exceeds the column width with null. + */ + SET_TO_NULL = 'SET_TO_NULL', + + /** + * Doesn't perform surplus byte handling. + */ + DISABLED = 'DISABLED', + + /** + * Cancels queries that return data exceeding the column width. + */ + FAIL = 'FAIL', + + /** + * Drop all rows that contain data exceeding column width. + */ + DROP_ROW = 'DROP_ROW', + + /** + * Removes the characters that exceed the maximum number of characters defined for the column. + */ + TRUNCATE = 'TRUNCATE', +} + +/** + * Specifies how to handle data being loaded that exceeds the length of the data type defined for columns containing VARCHAR, CHAR, or string data. By default, Redshift Spectrum sets the value to null for data that exceeds the width of the column. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"surplus_char_handling"_ + */ +export enum SurplusCharHandlingAction { + /** + * Replaces data that exceeds the column width with null. + */ + SET_TO_NULL = 'SET_TO_NULL', + + /** + * Doesn't perform surplus character handling. + */ + DISABLED = 'DISABLED', + + /** + * Cancels queries that return data exceeding the column width. + */ + FAIL = 'FAIL', + + /** + * Replaces each value in the row with null. + */ + DROP_ROW = 'DROP_ROW', + + /** + * Removes the characters that exceed the maximum number of characters defined for the column. + */ + TRUNCATE = 'TRUNCATE', +} + +/** + * Identifies if the file contains less or more values for a row than the number of columns specified in the external table definition. This property is only available for an uncompressed text file format. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"column_count_mismatch_handling"_ + */ +export enum ColumnCountMismatchHandlingAction { + /** + * Column count mismatch handling is turned off. + */ + DISABLED = 'DISABLED', + + /** + * Fail the query if the column count mismatch is detected. + */ + FAIL = 'FAIL', + + /** + * Fill missing values with NULL and ignore the additional values in each row. + */ + SET_TO_NULL = 'SET_TO_NULL', + + /** + * Drop all rows that contain column count mismatch error from the scan. + */ + DROP_ROW = 'DROP_ROW', +} + +/** + * Specifies how to handle data being loaded that exceeds the length of the data type defined for columns containing VARCHAR, CHAR, or string data. By default, Redshift Spectrum sets the value to null for data that exceeds the width of the column. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"surplus_char_handling"_ + */ +export enum WriteParallel { + /** + * Write data in parallel. + */ + ON = 'on', + + /** + * Write data serially. + */ + OFF = 'off', +} + +/** + * Specifies how to map columns when the table uses ORC data format. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ > _"orc.schema.resolution"_ + */ +export enum OrcColumnMappingType { + /** + * Map columns by name. + */ + NAME = 'name', + + /** + * Map columns by position. + */ + POSITION = 'position', +} + +/** + * The storage parameter keys that are currently known, this list is not exhaustive and other keys may be used. + */ +export enum StorageParameters { + /** + * The number of rows to skip at the top of a CSV file when the table is being created. + */ + SKIP_HEADER_LINE_COUNT = 'skip.header.line.count', + + /** + * Determines whether data handling is on for the table. + */ + DATA_CLEANSING_ENABLED = 'data_cleansing_enabled', + + /** + * The type of compression used on the table, when the file name does not contain an extension. This value overrides the compression type specified through the extension. + */ + COMPRESSION_TYPE = 'compression_type', + + /** + * Specifies the action to perform when query results contain invalid UTF-8 character values. + */ + INVALID_CHAR_HANDLING = 'invalid_char_handling', + + /** + * Specifies the replacement character to use when you set `INVALID_CHAR_HANDLING` to `REPLACE`. + */ + REPLACEMENT_CHAR = 'replacement_char', + + /** + * Specifies the action to perform when ORC data contains an integer (for example, BIGINT or int64) that is larger than the column definition (for example, SMALLINT or int16). + */ + NUMERIC_OVERFLOW_HANDLING = 'numeric_overflow_handling', + + /** + * Specifies how to handle data being loaded that exceeds the length of the data type defined for columns containing VARBYTE data. By default, Redshift Spectrum sets the value to null for data that exceeds the width of the column. + */ + SURPLUS_BYTES_HANDLING = 'surplus_bytes_handling', + + /** + * Specifies how to handle data being loaded that exceeds the length of the data type defined for columns containing VARCHAR, CHAR, or string data. By default, Redshift Spectrum sets the value to null for data that exceeds the width of the column. + */ + SURPLUS_CHAR_HANDLING = 'surplus_char_handling', + + /** + * Identifies if the file contains less or more values for a row than the number of columns specified in the external table definition. This property is only available for an uncompressed text file format. + */ + COLUMN_COUNT_MISMATCH_HANDLING = 'column_count_mismatch_handling', + + /** + * A property that sets the numRows value for the table definition. To explicitly update an external table's statistics, set the numRows property to indicate the size of the table. Amazon Redshift doesn't analyze external tables to generate the table statistics that the query optimizer uses to generate a query plan. If table statistics aren't set for an external table, Amazon Redshift generates a query execution plan based on an assumption that external tables are the larger tables and local tables are the smaller tables. + */ + NUM_ROWS = 'num_rows', + + /** + * A property that sets number of rows to skip at the beginning of each source file. + */ + SERIALIZATION_NULL_FORMAT = 'serialization.null.format', + + /** + * A property that sets the column mapping type for tables that use ORC data format. This property is ignored for other data formats. + */ + ORC_SCHEMA_RESOLUTION = 'orc.schema.resolution', + + /** + * A property that sets whether CREATE EXTERNAL TABLE AS should write data in parallel. When 'write.parallel' is set to off, CREATE EXTERNAL TABLE AS writes to one or more data files serially onto Amazon S3. This table property also applies to any subsequent INSERT statement into the same external table. + */ + WRITE_PARALLEL = 'write.parallel', + + /** + * A property that sets the maximum size (in MB) of each file written to Amazon S3 by CREATE EXTERNAL TABLE AS. The size must be a valid integer between 5 and 6200. The default maximum file size is 6,200 MB. This table property also applies to any subsequent INSERT statement into the same external table. + */ + WRITE_MAX_FILESIZE_MB = 'write.maxfilesize.mb', + + /** + * You can specify an AWS Key Management Service key to enable Server–Side Encryption (SSE) for Amazon S3 objects. + */ + WRITE_KMS_KEY_ID = 'write.kms.key.id', +} + +/** + * A storage parameter. The list of storage parameters available is not exhaustive and other keys may be used. + * + * If you would like to specify a storage parameter that is not available as a static member of this class, use the `StorageParameter.custom` method. + * + * The list of storage parameters currently known within the CDK is listed. + * + * @see https://docs.aws.amazon.com/glue/latest/dg/table-properties-crawler.html + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ + */ +export class StorageParameter { + /** + * The number of rows to skip at the top of a CSV file when the table is being created. + */ + public static skipHeaderLineCount(value: number): StorageParameter { + return new StorageParameter('skip.header.line.count', value.toString()); + } + + /** + * Determines whether data handling is on for the table. + */ + public static dataCleansingEnabled(value: boolean): StorageParameter { + return new StorageParameter('data_cleansing_enabled', value.toString()); + } + + /** + * The type of compression used on the table, when the file name does not contain an extension. This value overrides the compression type specified through the extension. + */ + public static compressionType(value: CompressionType): StorageParameter { + return new StorageParameter('compression_type', value); + } + + /** + * Specifies the action to perform when query results contain invalid UTF-8 character values. + */ + public static invalidCharHandling(value: InvalidCharHandlingAction): StorageParameter { + return new StorageParameter('invalid_char_handling', value); + } + + /** + * Specifies the replacement character to use when you set `INVALID_CHAR_HANDLING` to `REPLACE`. + */ + public static replacementChar(value: string): StorageParameter { + return new StorageParameter('replacement_char', value); + } + + /** + * Specifies the action to perform when ORC data contains an integer (for example, BIGINT or int64) that is larger than the column definition (for example, SMALLINT or int16). + */ + public static numericOverflowHandling(value: NumericOverflowHandlingAction): StorageParameter { + return new StorageParameter('numeric_overflow_handling', value); + } + + /** + * Specifies how to handle data being loaded that exceeds the length of the data type defined for columns containing VARBYTE data. By default, Redshift Spectrum sets the value to null for data that exceeds the width of the column. + */ + public static surplusBytesHandling(value: SurplusBytesHandlingAction): StorageParameter { + return new StorageParameter('surplus_bytes_handling', value); + } + + /** + * Specifies how to handle data being loaded that exceeds the length of the data type defined for columns containing VARCHAR, CHAR, or string data. By default, Redshift Spectrum sets the value to null for data that exceeds the width of the column. + */ + public static surplusCharHandling(value: SurplusCharHandlingAction): StorageParameter { + return new StorageParameter('surplus_char_handling', value); + } + + /** + * Identifies if the file contains less or more values for a row than the number of columns specified in the external table definition. This property is only available for an uncompressed text file format. + */ + public static columnCountMismatchHandling(value: ColumnCountMismatchHandlingAction): StorageParameter { + return new StorageParameter('column_count_mismatch_handling', value); + } + + /** + * A property that sets the numRows value for the table definition. To explicitly update an external table's statistics, set the numRows property to indicate the size of the table. Amazon Redshift doesn't analyze external tables to generate the table statistics that the query optimizer uses to generate a query plan. If table statistics aren't set for an external table, Amazon Redshift generates a query execution plan based on an assumption that external tables are the larger tables and local tables are the smaller tables. + */ + public static numRows(value: number): StorageParameter { + return new StorageParameter('num_rows', value.toString()); + } + + /** + * A property that sets number of rows to skip at the beginning of each source file. + */ + public static serializationNullFormat(value: string): StorageParameter { + return new StorageParameter('serialization.null.format', value); + } + + /** + * A property that sets the column mapping type for tables that use ORC data format. This property is ignored for other data formats. If this property is omitted, columns are mapped by `OrcColumnMappingType.NAME` by default. + * + * @default OrcColumnMappingType.NAME + */ + public static orcSchemaResolution(value: OrcColumnMappingType): StorageParameter { + return new StorageParameter('orc.schema.resolution', value); + } + + /** + * A property that sets whether CREATE EXTERNAL TABLE AS should write data in parallel. When 'write.parallel' is set to off, CREATE EXTERNAL TABLE AS writes to one or more data files serially onto Amazon S3. This table property also applies to any subsequent INSERT statement into the same external table. + * + * @default WriteParallel.ON + */ + public static writeParallel(value: WriteParallel): StorageParameter { + return new StorageParameter('write.parallel', value); + } + + /** + * A property that sets the maximum size (in MB) of each file written to Amazon S3 by CREATE EXTERNAL TABLE AS. The size must be a valid integer between 5 and 6200. The default maximum file size is 6,200 MB. This table property also applies to any subsequent INSERT statement into the same external table. + */ + public static writeMaxFileSizeMb(value: number): StorageParameter { + return new StorageParameter('write.maxfilesize.mb', value.toString()); + } + + /** + * You can specify an AWS Key Management Service key to enable Server–Side Encryption (SSE) for Amazon S3 objects. + */ + public static writeKmsKeyId(value: string): StorageParameter { + return new StorageParameter('write.kms.key.id', value); + } + + /** + * A custom storage parameter. + * @param key - The key of the storage parameter. + * @param value - The value of the storage parameter. + */ + public static custom(key: string, value: any): StorageParameter { + return new StorageParameter(key, value.toString()); + } + + protected constructor(public readonly key: string, public readonly value: string) {} +} diff --git a/packages/@aws-cdk/aws-glue-alpha/lib/table.ts b/packages/@aws-cdk/aws-glue-alpha/lib/table.ts index ff36dce8a0f90..f62e6af2010a4 100644 --- a/packages/@aws-cdk/aws-glue-alpha/lib/table.ts +++ b/packages/@aws-cdk/aws-glue-alpha/lib/table.ts @@ -1,3 +1,4 @@ +import { CfnTable } from 'aws-cdk-lib/aws-glue'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as kms from 'aws-cdk-lib/aws-kms'; import * as s3 from 'aws-cdk-lib/aws-s3'; @@ -7,8 +8,8 @@ import { AwsCustomResource } from 'aws-cdk-lib/custom-resources'; import { Construct } from 'constructs'; import { DataFormat } from './data-format'; import { IDatabase } from './database'; -import { CfnTable } from 'aws-cdk-lib/aws-glue'; import { Column } from './schema'; +import { StorageParameter } from './storage-parameter'; /** * Properties of a Partition Index. @@ -181,6 +182,41 @@ export interface TableProps { * @default - The parameter is not defined */ readonly enablePartitionFiltering?: boolean; + + /** + * The user-supplied properties for the description of the physical storage of this table. These properties help describe the format of the data that is stored within the crawled data sources. + * + * The key/value pairs that are allowed to be submitted are not limited, however their functionality is not guaranteed. + * + * Some keys will be auto-populated by glue crawlers, however, you can override them by specifying the key and value in this property. + * + * @see https://docs.aws.amazon.com/glue/latest/dg/table-properties-crawler.html + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE-parameters - under _"TABLE PROPERTIES"_ + * + * @example + * + * declare const glueDatabase: glue.IDatabase; + * const table = new glue.Table(this, 'Table', { + * storageParameters: [ + * glue.StorageParameter.skipHeaderLineCount(1), + * glue.StorageParameter.compressionType(glue.CompressionType.GZIP), + * glue.StorageParameter.custom('foo', 'bar'), // Will have no effect + * glue.StorageParameter.custom('separatorChar', ','), // Will describe the separator char used in the data + * glue.StorageParameter.custom(glue.StorageParameters.WRITE_PARALLEL, 'off'), + * ], + * // ... + * database: glueDatabase, + * columns: [{ + * name: 'col1', + * type: glue.Schema.STRING, + * }], + * dataFormat: glue.DataFormat.CSV, + * }); + * + * @default - The parameter is not defined + */ + readonly storageParameters?: StorageParameter[]; } /** @@ -273,6 +309,11 @@ export class Table extends Resource implements ITable { */ public readonly partitionIndexes?: PartitionIndex[]; + /** + * The tables' storage descriptor properties. + */ + public readonly storageParameters?: StorageParameter[]; + /** * Partition indexes must be created one at a time. To avoid * race conditions, we store the resource and add dependencies @@ -295,6 +336,7 @@ export class Table extends Resource implements ITable { validateSchema(props.columns, props.partitionKeys); this.columns = props.columns; this.partitionKeys = props.partitionKeys; + this.storageParameters = props.storageParameters; this.compressed = props.compressed ?? false; const { bucket, encryption, encryptionKey } = createBucket(this, props); @@ -328,6 +370,14 @@ export class Table extends Resource implements ITable { serdeInfo: { serializationLibrary: props.dataFormat.serializationLibrary.className, }, + parameters: props.storageParameters ? props.storageParameters.reduce((acc, param) => { + if (param.key in acc) { + throw new Error(`Duplicate storage parameter key: ${param.key}`); + } + const key = param.key; + acc[key] = param.value; + return acc; + }, {} as { [key: string]: string }) : undefined, }, tableType: 'EXTERNAL_TABLE', diff --git a/packages/@aws-cdk/aws-glue-alpha/package.json b/packages/@aws-cdk/aws-glue-alpha/package.json index 0d31e5e201dcd..ef6e54a932b81 100644 --- a/packages/@aws-cdk/aws-glue-alpha/package.json +++ b/packages/@aws-cdk/aws-glue-alpha/package.json @@ -82,15 +82,15 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/integ-runner": "0.0.0", - "@aws-cdk/pkglint": "0.0.0", "@aws-cdk/integ-tests-alpha": "0.0.0", + "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^29.5.3", "aws-cdk-lib": "0.0.0", "constructs": "^10.0.0", "jest": "^29.6.2" }, - "dependencies": {}, "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { "aws-cdk-lib": "^0.0.0", diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.assets.json b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.assets.json index e1b6a011823d6..d714c2d54aaba 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.assets.json +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.assets.json @@ -1,7 +1,7 @@ { - "version": "31.0.0", + "version": "33.0.0", "files": { - "1b05206385b50de7e074070a25b271988c0055f2fde760f5c119af3fef3a1bcb": { + "dc6c1c5f05a8e365822e6d61c41b6fc6afd58d20a2784614b906ae1587c68754": { "source": { "path": "aws-cdk-glue.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "1b05206385b50de7e074070a25b271988c0055f2fde760f5c119af3fef3a1bcb.json", + "objectKey": "dc6c1c5f05a8e365822e6d61c41b6fc6afd58d20a2784614b906ae1587c68754.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.template.json b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.template.json index 45af51d9b9a02..f4415b64a1333 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.template.json +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/aws-cdk-glue.template.json @@ -2,8 +2,8 @@ "Resources": { "DataBucketE3889A50": { "Type": "AWS::S3::Bucket", - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "MyDatabase1E2517DB": { "Type": "AWS::Glue::Database", @@ -328,8 +328,8 @@ "Version": "2012-10-17" } }, - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "MyEncryptedTableBucket7B28486D": { "Type": "AWS::S3::Bucket", @@ -423,22 +423,6 @@ } } }, - "MyPartitionFilteredTableBucket6ACAA137": { - "Type": "AWS::S3::Bucket", - "Properties": { - "BucketEncryption": { - "ServerSideEncryptionConfiguration": [ - { - "ServerSideEncryptionByDefault": { - "SSEAlgorithm": "AES256" - } - } - ] - } - }, - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" - }, "MyPartitionFilteredTable324BA27A": { "Type": "AWS::Glue::Table", "Properties": { @@ -488,7 +472,7 @@ [ "s3://", { - "Ref": "MyPartitionFilteredTableBucket6ACAA137" + "Ref": "DataBucketE3889A50" }, "/" ] @@ -504,6 +488,77 @@ } } }, + "MyTableWithStorageDescriptorParametersTable1A347345": { + "Type": "AWS::Glue::Table", + "Properties": { + "CatalogId": { + "Ref": "AWS::AccountId" + }, + "DatabaseName": { + "Ref": "MyDatabase1E2517DB" + }, + "TableInput": { + "Description": "table_with_storage_descriptor_parameters generated by CDK", + "Name": "table_with_storage_descriptor_parameters", + "Parameters": { + "classification": "json", + "has_encrypted_data": true + }, + "StorageDescriptor": { + "Columns": [ + { + "Name": "col1", + "Type": "string" + }, + { + "Comment": "col2 comment", + "Name": "col2", + "Type": "string" + }, + { + "Name": "col3", + "Type": "array" + }, + { + "Name": "col4", + "Type": "map" + }, + { + "Name": "col5", + "Type": "struct" + } + ], + "Compressed": false, + "InputFormat": "org.apache.hadoop.mapred.TextInputFormat", + "Location": { + "Fn::Join": [ + "", + [ + "s3://", + { + "Ref": "DataBucketE3889A50" + }, + "/" + ] + ] + }, + "OutputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", + "Parameters": { + "skip.header.line.count": "1", + "compression_type": "gzip", + "foo": "bar", + "separatorChar": ",", + "write.parallel": "off" + }, + "SerdeInfo": { + "SerializationLibrary": "org.openx.data.jsonserde.JsonSerDe" + }, + "StoredAsSubDirectories": false + }, + "TableType": "EXTERNAL_TABLE" + } + } + }, "MyUserDC45028B": { "Type": "AWS::IAM::User" }, diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.assets.json b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.assets.json new file mode 100644 index 0000000000000..670371bb340e7 --- /dev/null +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.assets.json @@ -0,0 +1,19 @@ +{ + "version": "33.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.template.json b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/cdk.out b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/cdk.out index 7925065efbcc4..560dae10d018f 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"31.0.0"} \ No newline at end of file +{"version":"33.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/integ.json b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/integ.json index 46daab575ad89..ab7e38c81b5c6 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/integ.json @@ -1,14 +1,12 @@ { - "version": "31.0.0", + "version": "33.0.0", "testCases": { - "integ.table": { + "aws-cdk-glue-table-integ/DefaultTest": { "stacks": [ "aws-cdk-glue" ], - "diffAssets": false, - "stackUpdateWorkflow": true + "assertionStack": "aws-cdk-glue-table-integ/DefaultTest/DeployAssert", + "assertionStackName": "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70" } - }, - "synthContext": {}, - "enableLookups": false + } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/manifest.json b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/manifest.json index 2f3c8c9dbc41a..02bab428fcf54 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "31.0.0", + "version": "33.0.0", "artifacts": { "aws-cdk-glue.assets": { "type": "cdk:asset-manifest", @@ -17,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1b05206385b50de7e074070a25b271988c0055f2fde760f5c119af3fef3a1bcb.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dc6c1c5f05a8e365822e6d61c41b6fc6afd58d20a2784614b906ae1587c68754.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -87,16 +87,16 @@ "data": "MyEncryptedTable981A88C6" } ], - "/aws-cdk-glue/MyPartitionFilteredTable/Bucket/Resource": [ + "/aws-cdk-glue/MyPartitionFilteredTable/Table": [ { "type": "aws:cdk:logicalId", - "data": "MyPartitionFilteredTableBucket6ACAA137" + "data": "MyPartitionFilteredTable324BA27A" } ], - "/aws-cdk-glue/MyPartitionFilteredTable/Table": [ + "/aws-cdk-glue/MyTableWithStorageDescriptorParameters/Table": [ { "type": "aws:cdk:logicalId", - "data": "MyPartitionFilteredTable324BA27A" + "data": "MyTableWithStorageDescriptorParametersTable1A347345" } ], "/aws-cdk-glue/MyUser/Resource": [ @@ -134,10 +134,66 @@ "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } + ], + "MyPartitionFilteredTableBucket6ACAA137": [ + { + "type": "aws:cdk:logicalId", + "data": "MyPartitionFilteredTableBucket6ACAA137", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } ] }, "displayName": "aws-cdk-glue" }, + "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "awscdkgluetableintegDefaultTestDeployAssert8BFB5B70.assets" + ], + "metadata": { + "/aws-cdk-glue-table-integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-glue-table-integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-glue-table-integ/DefaultTest/DeployAssert" + }, "Tree": { "type": "cdk:tree", "properties": { diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/tree.json b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/tree.json index 41c0de2b3b7a1..71c545fff8226 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.js.snapshot/tree.json @@ -20,13 +20,13 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -49,13 +49,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.CfnDatabase", + "fqn": "aws-cdk-lib.aws_glue.CfnDatabase", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.Database", + "fqn": "@aws-cdk/aws-glue-alpha.Database", "version": "0.0.0" } }, @@ -137,13 +137,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.CfnTable", + "fqn": "aws-cdk-lib.aws_glue.CfnTable", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.Table", + "fqn": "@aws-cdk/aws-glue-alpha.Table", "version": "0.0.0" } }, @@ -225,13 +225,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.CfnTable", + "fqn": "aws-cdk-lib.aws_glue.CfnTable", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.Table", + "fqn": "@aws-cdk/aws-glue-alpha.Table", "version": "0.0.0" } }, @@ -313,13 +313,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.CfnTable", + "fqn": "aws-cdk-lib.aws_glue.CfnTable", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.Table", + "fqn": "@aws-cdk/aws-glue-alpha.Table", "version": "0.0.0" } }, @@ -401,13 +401,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.CfnTable", + "fqn": "aws-cdk-lib.aws_glue.CfnTable", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.Table", + "fqn": "@aws-cdk/aws-glue-alpha.Table", "version": "0.0.0" } }, @@ -452,13 +452,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnKey", + "fqn": "aws-cdk-lib.aws_kms.CfnKey", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Key", + "fqn": "aws-cdk-lib.aws_kms.Key", "version": "0.0.0" } }, @@ -494,13 +494,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -578,13 +578,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.CfnTable", + "fqn": "aws-cdk-lib.aws_glue.CfnTable", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.Table", + "fqn": "@aws-cdk/aws-glue-alpha.Table", "version": "0.0.0" } }, @@ -592,41 +592,92 @@ "id": "MyPartitionFilteredTable", "path": "aws-cdk-glue/MyPartitionFilteredTable", "children": { - "Bucket": { - "id": "Bucket", - "path": "aws-cdk-glue/MyPartitionFilteredTable/Bucket", - "children": { - "Resource": { - "id": "Resource", - "path": "aws-cdk-glue/MyPartitionFilteredTable/Bucket/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::S3::Bucket", - "aws:cdk:cloudformation:props": { - "bucketEncryption": { - "serverSideEncryptionConfiguration": [ - { - "serverSideEncryptionByDefault": { - "sseAlgorithm": "AES256" - } - } + "Table": { + "id": "Table", + "path": "aws-cdk-glue/MyPartitionFilteredTable/Table", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Glue::Table", + "aws:cdk:cloudformation:props": { + "catalogId": { + "Ref": "AWS::AccountId" + }, + "databaseName": { + "Ref": "MyDatabase1E2517DB" + }, + "tableInput": { + "name": "partition_filtered_table", + "description": "partition_filtered_table generated by CDK", + "parameters": { + "classification": "json", + "has_encrypted_data": true, + "partition_filtering.enabled": true + }, + "storageDescriptor": { + "location": { + "Fn::Join": [ + "", + [ + "s3://", + { + "Ref": "DataBucketE3889A50" + }, + "/" + ] ] + }, + "compressed": false, + "storedAsSubDirectories": false, + "columns": [ + { + "name": "col1", + "type": "string" + }, + { + "name": "col2", + "type": "string", + "comment": "col2 comment" + }, + { + "name": "col3", + "type": "array" + }, + { + "name": "col4", + "type": "map" + }, + { + "name": "col5", + "type": "struct" + } + ], + "inputFormat": "org.apache.hadoop.mapred.TextInputFormat", + "outputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", + "serdeInfo": { + "serializationLibrary": "org.openx.data.jsonserde.JsonSerDe" } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", - "version": "0.0.0" + }, + "tableType": "EXTERNAL_TABLE" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_glue.CfnTable", "version": "0.0.0" } - }, + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-glue-alpha.Table", + "version": "0.0.0" + } + }, + "MyTableWithStorageDescriptorParameters": { + "id": "MyTableWithStorageDescriptorParameters", + "path": "aws-cdk-glue/MyTableWithStorageDescriptorParameters", + "children": { "Table": { "id": "Table", - "path": "aws-cdk-glue/MyPartitionFilteredTable/Table", + "path": "aws-cdk-glue/MyTableWithStorageDescriptorParameters/Table", "attributes": { "aws:cdk:cloudformation:type": "AWS::Glue::Table", "aws:cdk:cloudformation:props": { @@ -637,12 +688,11 @@ "Ref": "MyDatabase1E2517DB" }, "tableInput": { - "name": "partition_filtered_table", - "description": "partition_filtered_table generated by CDK", + "name": "table_with_storage_descriptor_parameters", + "description": "table_with_storage_descriptor_parameters generated by CDK", "parameters": { "classification": "json", - "has_encrypted_data": true, - "partition_filtering.enabled": true + "has_encrypted_data": true }, "storageDescriptor": { "location": { @@ -651,7 +701,7 @@ [ "s3://", { - "Ref": "MyPartitionFilteredTableBucket6ACAA137" + "Ref": "DataBucketE3889A50" }, "/" ] @@ -686,6 +736,13 @@ "outputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", "serdeInfo": { "serializationLibrary": "org.openx.data.jsonserde.JsonSerDe" + }, + "parameters": { + "skip.header.line.count": "1", + "compression_type": "gzip", + "foo": "bar", + "separatorChar": ",", + "write.parallel": "off" } }, "tableType": "EXTERNAL_TABLE" @@ -693,13 +750,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.CfnTable", + "fqn": "aws-cdk-lib.aws_glue.CfnTable", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-glue.Table", + "fqn": "@aws-cdk/aws-glue-alpha.Table", "version": "0.0.0" } }, @@ -715,7 +772,7 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnUser", + "fqn": "aws-cdk-lib.aws_iam.CfnUser", "version": "0.0.0" } }, @@ -889,19 +946,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.User", + "fqn": "aws-cdk-lib.aws_iam.User", "version": "0.0.0" } }, @@ -917,7 +974,7 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnUser", + "fqn": "aws-cdk-lib.aws_iam.CfnUser", "version": "0.0.0" } }, @@ -1082,19 +1139,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.User", + "fqn": "aws-cdk-lib.aws_iam.User", "version": "0.0.0" } }, @@ -1102,22 +1159,76 @@ "id": "BootstrapVersion", "path": "aws-cdk-glue/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.270" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "aws-cdk-glue/CheckBootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.270" + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.270" + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "aws-cdk-glue-table-integ": { + "id": "aws-cdk-glue-table-integ", + "path": "aws-cdk-glue-table-integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "aws-cdk-glue-table-integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-glue-table-integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.69" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "aws-cdk-glue-table-integ/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-glue-table-integ/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-glue-table-integ/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" } }, "Tree": { @@ -1125,13 +1236,13 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.270" + "version": "10.2.69" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.270" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.ts b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.ts index 8ad11dfbe580d..5633ccac75c1f 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/integ.table.ts +++ b/packages/@aws-cdk/aws-glue-alpha/test/integ.table.ts @@ -1,15 +1,18 @@ #!/usr/bin/env node +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as kms from 'aws-cdk-lib/aws-kms'; import * as s3 from 'aws-cdk-lib/aws-s3'; -import * as cdk from 'aws-cdk-lib'; import * as glue from '../lib'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-glue'); -const bucket = new s3.Bucket(stack, 'DataBucket'); +const bucket = new s3.Bucket(stack, 'DataBucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); const database = new glue.Database(stack, 'MyDatabase', { databaseName: 'my_database', @@ -84,17 +87,35 @@ const encryptedTable = new glue.Table(stack, 'MyEncryptedTable', { partitionKeys, dataFormat: glue.DataFormat.JSON, encryption: glue.TableEncryption.KMS, - encryptionKey: new kms.Key(stack, 'MyKey'), + encryptionKey: new kms.Key(stack, 'MyKey', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + }), }); new glue.Table(stack, 'MyPartitionFilteredTable', { database, + bucket, tableName: 'partition_filtered_table', columns, dataFormat: glue.DataFormat.JSON, enablePartitionFiltering: true, }); +new glue.Table(stack, 'MyTableWithStorageDescriptorParameters', { + database, + bucket, + tableName: 'table_with_storage_descriptor_parameters', + columns, + dataFormat: glue.DataFormat.JSON, + storageParameters: [ + glue.StorageParameter.skipHeaderLineCount(1), + glue.StorageParameter.compressionType(glue.CompressionType.GZIP), + glue.StorageParameter.custom('foo', 'bar'), // Will have no effect + glue.StorageParameter.custom('separatorChar', ','), // Will describe the separator char used in the data + glue.StorageParameter.custom(glue.StorageParameters.WRITE_PARALLEL, 'off'), + ], +}); + const user = new iam.User(stack, 'MyUser'); csvTable.grantReadWrite(user); encryptedTable.grantReadWrite(user); @@ -104,4 +125,8 @@ avroTable.grantReadWrite(anotherUser); jsonTable.grantReadWrite(anotherUser); parquetTable.grantReadWrite(anotherUser); +new integ.IntegTest(app, 'aws-cdk-glue-table-integ', { + testCases: [stack], +}); + app.synth(); diff --git a/packages/@aws-cdk/aws-glue-alpha/test/table.test.ts b/packages/@aws-cdk/aws-glue-alpha/test/table.test.ts index 09cd78779cfcb..487a5c5343e14 100644 --- a/packages/@aws-cdk/aws-glue-alpha/test/table.test.ts +++ b/packages/@aws-cdk/aws-glue-alpha/test/table.test.ts @@ -1,11 +1,11 @@ -import { Template, Match } from 'aws-cdk-lib/assertions'; +import * as cdk from 'aws-cdk-lib'; +import { Match, Template } from 'aws-cdk-lib/assertions'; +import { CfnTable } from 'aws-cdk-lib/aws-glue'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as kms from 'aws-cdk-lib/aws-kms'; import * as s3 from 'aws-cdk-lib/aws-s3'; -import * as cdk from 'aws-cdk-lib'; import * as glue from '../lib'; import { PartitionIndex } from '../lib'; -import { CfnTable } from 'aws-cdk-lib/aws-glue'; test('unpartitioned JSON table', () => { const app = new cdk.App(); @@ -1478,6 +1478,27 @@ describe('validate', () => { encryption: glue.TableEncryption.CLIENT_SIDE_KMS, })).not.toThrow(); }); + + test('unique storage descriptor parameters', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Stack'); + const database = new glue.Database(stack, 'Database'); + + expect(() => new glue.Table(stack, 'Table', { + database, + columns: [{ + name: 'col', + type: glue.Schema.STRING, + }], + dataFormat: glue.DataFormat.JSON, + storageParameters: [ + glue.StorageParameter.skipHeaderLineCount(2), + glue.StorageParameter.compressionType(glue.CompressionType.GZIP), + glue.StorageParameter.custom('foo', 'bar'), + glue.StorageParameter.custom(glue.StorageParameters.COMPRESSION_TYPE, 'true'), + ], + })).toThrowError('Duplicate storage parameter key: compression_type'); + }); }); test('Table.fromTableArn', () => { @@ -1600,6 +1621,39 @@ test('can specify a physical name', () => { }); }); +test('storage descriptor parameters', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Stack'); + const database = new glue.Database(stack, 'Database'); + new glue.Table(stack, 'Table', { + database, + columns: [{ + name: 'col', + type: glue.Schema.STRING, + }], + dataFormat: glue.DataFormat.JSON, + storageParameters: [ + glue.StorageParameter.skipHeaderLineCount(2), + glue.StorageParameter.compressionType(glue.CompressionType.GZIP), + glue.StorageParameter.custom('foo', 'bar'), + glue.StorageParameter.custom('separatorChar', ','), + ], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { + TableInput: { + StorageDescriptor: { + Parameters: { + 'skip.header.line.count': '2', + 'separatorChar': ',', + 'foo': 'bar', + 'compression_type': 'gzip', + }, + }, + }, + }); +}); + function createTable(props: Pick>): void { const stack = new cdk.Stack(); new glue.Table(stack, 'table', { diff --git a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts index 603fab563897f..cfc0b406eb4d9 100644 --- a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts +++ b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts @@ -314,7 +314,7 @@ export interface GraphqlApiProps { /** * GraphQL schema definition. Specify how you want to define your schema. * - * Schema.fromFile(filePath: string) allows schema definition through schema.graphql file + * SchemaFile.fromAsset(filePath: string) allows schema definition through schema.graphql file * * @default - schema will be generated code-first (i.e. addType, addObjectType, etc.) * diff --git a/packages/aws-cdk-lib/aws-certificatemanager/lib/certificate.ts b/packages/aws-cdk-lib/aws-certificatemanager/lib/certificate.ts index 4590db59879cf..37b5eb55b3511 100644 --- a/packages/aws-cdk-lib/aws-certificatemanager/lib/certificate.ts +++ b/packages/aws-cdk-lib/aws-certificatemanager/lib/certificate.ts @@ -94,9 +94,9 @@ export interface CertificateProps { readonly transparencyLoggingEnabled?: boolean; /** - * The Certifcate name. + * The Certificate name. * - * Since the Certifcate resource doesn't support providing a physical name, the value provided here will be recorded in the `Name` tag + * Since the Certificate resource doesn't support providing a physical name, the value provided here will be recorded in the `Name` tag * * @default the full, absolute path of this construct */ diff --git a/packages/aws-cdk-lib/aws-certificatemanager/test/certificate.test.ts b/packages/aws-cdk-lib/aws-certificatemanager/test/certificate.test.ts index baf03efaa0de4..6e383f30bb418 100644 --- a/packages/aws-cdk-lib/aws-certificatemanager/test/certificate.test.ts +++ b/packages/aws-cdk-lib/aws-certificatemanager/test/certificate.test.ts @@ -407,7 +407,7 @@ describe('Transparency logging settings', () => { }); }); -describe('Certifcate Name setting', () => { +describe('Certificate Name setting', () => { test('the Name tag is defaulted to path', () => { const stack = new Stack(undefined, 'TestStack'); diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/web-distribution.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/web-distribution.ts index e748cc05501b4..1ad9572233286 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/web-distribution.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/web-distribution.ts @@ -555,7 +555,7 @@ export class ViewerCertificate { } /** - * Generate a viewer certifcate configuration using + * Generate a viewer certificate configuration using * the CloudFront default certificate (e.g. d111111abcdef8.cloudfront.net) * and a `SecurityPolicyProtocol.TLS_V1` security policy. * diff --git a/packages/aws-cdk-lib/cloud-assembly-schema/scripts/update-schema.ts b/packages/aws-cdk-lib/cloud-assembly-schema/scripts/update-schema.ts index 14dc45877c292..cb02b1906c4a9 100644 --- a/packages/aws-cdk-lib/cloud-assembly-schema/scripts/update-schema.ts +++ b/packages/aws-cdk-lib/cloud-assembly-schema/scripts/update-schema.ts @@ -14,10 +14,32 @@ function log(message: string) { */ const SCHEMA_DIR = path.resolve(__dirname, '../schema'); -const SCHEMA_DEFINITIONS: { [schemaName: string]: { rootTypeName: string } } = { - 'assets': { rootTypeName: 'AssetManifest' }, - 'cloud-assembly': { rootTypeName: 'AssemblyManifest' }, - 'integ': { rootTypeName: 'IntegManifest' }, +const SCHEMA_DEFINITIONS: { + [schemaName: string]: { + /** + * The name of the root type. + */ + rootTypeName: string; + /** + * Files loaded to generate the schema. + * Should be relative to `cloud-assembly-schema/lib`. + * Usually this is just the file containing the root type. + */ + files: string[]; + } +} = { + 'assets': { + rootTypeName: 'AssetManifest', + files: [path.join('assets', 'schema.ts')], + }, + 'cloud-assembly': { + rootTypeName: 'AssemblyManifest', + files: [path.join('cloud-assembly', 'schema.ts')], + }, + 'integ': { + rootTypeName: 'IntegManifest', + files: [path.join('integ-tests', 'schema.ts')], + }, }; export const SCHEMAS = Object.keys(SCHEMA_DEFINITIONS); @@ -59,14 +81,13 @@ export function generateSchema(schemaName: string, saveToFile: boolean = true) { topRef: true, noExtraProps: false, out, - skipLibCheck: true, }; const compilerOptions = { strictNullChecks: true, }; - const program = tjs.getProgramFromFiles([path.join(__dirname, '../lib/index.d.ts')], compilerOptions); + const program = tjs.getProgramFromFiles(spec.files.map(file =>path.join(__dirname, '..', 'lib', file)), compilerOptions); const schema = tjs.generateSchema(program, spec.rootTypeName, settings); augmentDescription(schema); @@ -126,5 +147,5 @@ function augmentDescription(schema: any) { * compatibility checks. */ function addAnyMetadataEntry(schema: any) { - schema.definitions.MetadataEntry?.properties.data.anyOf.push({ description: 'Free form data.' }); + schema?.definitions?.MetadataEntry?.properties.data.anyOf.push({ description: 'Free form data.' }); } diff --git a/tools/@aws-cdk/prlint/lint.ts b/tools/@aws-cdk/prlint/lint.ts index 43208bcbb1eb6..91501eb95e759 100644 --- a/tools/@aws-cdk/prlint/lint.ts +++ b/tools/@aws-cdk/prlint/lint.ts @@ -358,7 +358,7 @@ export class PullRequestLinter { ); const communityRequestedChanges = reviews.data.some( review => this.getTrustedCommunityMembers().includes(review.user?.login ?? '') - && review.state !== 'APPROVED', // community members cannot request changes + && review.state === 'COMMENTED', // community members can only approve or comment ); const communityApproved = reviews.data.some( review => this.getTrustedCommunityMembers().includes(review.user?.login ?? '') diff --git a/tools/@aws-cdk/prlint/test/lint.test.ts b/tools/@aws-cdk/prlint/test/lint.test.ts index 3fb5a595a1b6b..c693af201bc47 100644 --- a/tools/@aws-cdk/prlint/test/lint.test.ts +++ b/tools/@aws-cdk/prlint/test/lint.test.ts @@ -743,7 +743,7 @@ describe('integration tests required on features', () => { mockListReviews.mockImplementation(() => { return { data: [ - { id: 1111122223, user: { login: 'pahud' }, state: 'COMMENT' }, + { id: 1111122223, user: { login: 'pahud' }, state: 'COMMENTED' }, ], }; }); diff --git a/tools/@aws-cdk/spec2cdk/package.json b/tools/@aws-cdk/spec2cdk/package.json index 1eb0dee630fc8..ce472624c5189 100644 --- a/tools/@aws-cdk/spec2cdk/package.json +++ b/tools/@aws-cdk/spec2cdk/package.json @@ -32,8 +32,8 @@ }, "license": "Apache-2.0", "dependencies": { - "@aws-cdk/aws-service-spec": "^0.0.4", - "@aws-cdk/service-spec-types": "^0.0.4", + "@aws-cdk/aws-service-spec": "^0.0.5", + "@aws-cdk/service-spec-types": "^0.0.5", "@cdklabs/tskb": "^0.0.1", "@cdklabs/typewriter": "^0.0.1", "camelcase": "^6", diff --git a/yarn.lock b/yarn.lock index d0a8efabb45e2..92e5e0b403a3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,12 +55,12 @@ resolved "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.166.tgz#467507db141cd829ff8aa9d6ea5519310a4276b8" integrity sha512-j0xnccpUQHXJKPgCwQcGGNu4lRiC1PptYfdxBIH1L4dRK91iBxtSQHESRQX+yB47oGLaF/WfNN/aF3WXwlhikg== -"@aws-cdk/aws-service-spec@^0.0.4": - version "0.0.4" - resolved "https://registry.npmjs.org/@aws-cdk/aws-service-spec/-/aws-service-spec-0.0.4.tgz#f5af2fac4dfcd1a9a887b1d52bceafcae1e731d8" - integrity sha512-pkAMbkwBfQftlrhocKTTZfnJDbgvyR4lJTHXkI8lDBomdR8/9Dcyo1vX/etBnM7fu3lbNBayBc4YHFgpiyOQYQ== +"@aws-cdk/aws-service-spec@^0.0.5": + version "0.0.5" + resolved "https://registry.npmjs.org/@aws-cdk/aws-service-spec/-/aws-service-spec-0.0.5.tgz#db431bf58bcd5792302fd4ef81ef649020bcb08a" + integrity sha512-iU1l0QNTZQfjNSKOP9SnemeCxyME2ItFqctRCyPWaJe0m+6YPNuU0PS1Dwelf9SgA6fe2wK4fJlP5pA2I8PDgg== dependencies: - "@aws-cdk/service-spec-types" "^0.0.4" + "@aws-cdk/service-spec-types" "^0.0.5" "@cdklabs/tskb" "^0.0.1" "@aws-cdk/lambda-layer-kubectl-v24@^2.0.242": @@ -68,10 +68,10 @@ resolved "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl-v24/-/lambda-layer-kubectl-v24-2.0.242.tgz#4273a5ad7714f933a7eba155eb9280823086db71" integrity sha512-7/wIOo685tmrEe4hh6zqDELhBZh5OQGf3Hd2FU2Vnwy2ZubW8qTmEw5gqJCsCrGKeYDoa1BcVhDRZ/nzjkaqyA== -"@aws-cdk/service-spec-types@^0.0.4": - version "0.0.4" - resolved "https://registry.npmjs.org/@aws-cdk/service-spec-types/-/service-spec-types-0.0.4.tgz#a1c9c256144a5645002c4e0461cdaac724ea2fd0" - integrity sha512-1lP0BntXheMmKumAQhHmXqAR/U90BJJ5/L9azFmxqU9zqG7uAwVyZz2vRMQlWGpdMIsnkFTd9pfgghjnaYYrtg== +"@aws-cdk/service-spec-types@^0.0.5": + version "0.0.5" + resolved "https://registry.npmjs.org/@aws-cdk/service-spec-types/-/service-spec-types-0.0.5.tgz#dc94f7dcdf733d8dde7ec64fbe8aad2c0eb5c49d" + integrity sha512-qOktXW7SWzAymWnDsV97l/HHBl6WaYxxjlyfIvMr5o1sDFzusyoRQVrgKrlsZ75iGYV7PlGTLLcI3Zkhz42bhQ== dependencies: "@cdklabs/tskb" "^0.0.1"