Skip to content

Commit

Permalink
Merge branch 'main' into cf-grpc
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Feb 20, 2025
2 parents c64d888 + b06daf8 commit 43afbf2
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 6 deletions.
10 changes: 10 additions & 0 deletions packages/@aws-cdk/aws-glue-alpha/lib/jobs/pyspark-etl-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ export interface PySparkEtlJobProps extends JobProperties {
*/
readonly extraFiles?: Code[];

/**
* Extra Jars S3 URL (optional)
* S3 URL where additional jar dependencies are located
* @default - no extra jar files
*/
readonly extraJars?: Code[];

/**
* Specifies whether job run queuing is enabled for the job runs for this job.
* A value of true means job run queuing is enabled for the job runs.
Expand Down Expand Up @@ -159,6 +166,9 @@ export class PySparkEtlJob extends Job {
if (props.extraFiles && props.extraFiles.length > 0) {
args['--extra-files'] = props.extraFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
}
if (props.extraJars && props.extraJars?.length > 0) {
args['--extra-jars'] = props.extraJars.map(code => this.codeS3ObjectUrl(code)).join(',');
}

return args;
}
Expand Down
10 changes: 10 additions & 0 deletions packages/@aws-cdk/aws-glue-alpha/lib/jobs/pyspark-flex-etl-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ export interface PySparkFlexEtlJobProps extends JobProperties {
*/
readonly extraFiles?: Code[];

/**
* Extra Jars S3 URL (optional)
* S3 URL where additional jar dependencies are located
* @default - no extra jar files
*/
readonly extraJars?: Code[];

}

/**
Expand Down Expand Up @@ -160,6 +167,9 @@ export class PySparkFlexEtlJob extends Job {
if (props.extraFiles && props.extraFiles.length > 0) {
args['--extra-files'] = props.extraFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
}
if (props.extraJars && props.extraJars?.length > 0) {
args['--extra-jars'] = props.extraJars.map(code => this.codeS3ObjectUrl(code)).join(',');
}

return args;
}
Expand Down
10 changes: 10 additions & 0 deletions packages/@aws-cdk/aws-glue-alpha/lib/jobs/pyspark-streaming-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ export interface PySparkStreamingJobProps extends JobProperties {
*/
readonly extraFiles?: Code[];

/**
* Extra Jars S3 URL (optional)
* S3 URL where additional jar dependencies are located
* @default - no extra jar files
*/
readonly extraJars?: Code[];

/**
* Specifies whether job run queuing is enabled for the job runs for this job.
* A value of true means job run queuing is enabled for the job runs.
Expand Down Expand Up @@ -159,6 +166,9 @@ export class PySparkStreamingJob extends Job {
if (props.extraFiles && props.extraFiles.length > 0) {
args['--extra-files'] = props.extraFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
}
if (props.extraJars && props.extraJars?.length > 0) {
args['--extra-jars'] = props.extraJars.map(code => this.codeS3ObjectUrl(code)).join(',');
}

return args;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ describe('Job', () => {
});
});

describe('Create PySpark ETL Job with extraPythonFiles and extraFiles', () => {
describe('Create PySpark ETL Job with extraPythonFiles, extraFiles and extraJars', () => {
beforeEach(() => {
job = new glue.PySparkEtlJob(stack, 'PySparkETLJob', {
role,
Expand All @@ -381,6 +381,11 @@ describe('Job', () => {
s3.Bucket.fromBucketName(stack, 'extraFilesBucket', 'extra-files-bucket'),
'prefix/file.txt'),
],
extraJars: [
glue.Code.fromBucket(
s3.Bucket.fromBucketName(stack, 'extraJarsBucket', 'extra-jars-bucket'),
'prefix/file.jar'),
],
});
});

Expand Down Expand Up @@ -408,6 +413,7 @@ describe('Job', () => {
'--enable-continuous-cloudwatch-log': 'true',
'--extra-py-files': 's3://extra-python-files-bucket/prefix/file.py',
'--extra-files': 's3://extra-files-bucket/prefix/file.txt',
'--extra-jars': 's3://extra-jars-bucket/prefix/file.jar',
}),
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ describe('Job', () => {
});
});

describe('Create PySpark Streaming Job with extraPythonFiles and extraFiles', () => {
describe('Create PySpark Streaming Job with extraPythonFiles, extraFiles and extraJars', () => {
beforeEach(() => {
job = new glue.PySparkStreamingJob(stack, 'PySparkStreamingJob', {
role,
Expand All @@ -393,6 +393,11 @@ describe('Job', () => {
s3.Bucket.fromBucketName(stack, 'extraFilesBucket', 'extra-files-bucket'),
'prefix/file.txt'),
],
extraJars: [
glue.Code.fromBucket(
s3.Bucket.fromBucketName(stack, 'extraJarsBucket', 'extra-jars-bucket'),
'prefix/file.jar'),
],
});
});

Expand Down Expand Up @@ -420,6 +425,7 @@ describe('Job', () => {
'--enable-continuous-cloudwatch-log': 'true',
'--extra-py-files': 's3://extra-python-files-bucket/prefix/file.py',
'--extra-files': 's3://extra-files-bucket/prefix/file.txt',
'--extra-jars': 's3://extra-jars-bucket/prefix/file.jar',
}),
});
});
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-apigateway/lib/cors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export interface CorsOptions {
* `[ * ]`.
*
* Responses will include the `Access-Control-Allow-Origin` response header.
* If `Cors.ALL_ORIGINS` is specified, the `Vary: Origin` response header will
* also be included.
* If specific origins are specified (not `Cors.ALL_ORIGINS`), the `Vary: Origin`
* response header will also be included.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*/
Expand Down
2 changes: 2 additions & 0 deletions packages/aws-cdk-lib/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ new CustomResource(this, 'MyMagicalResource', {
resourceType: 'Custom::MyCustomResource', // must start with 'Custom::'

// the resource properties
// properties like serviceToken or serviceTimeout are ported into properties automatically
// try not to use key names similar to these or there will be a risk of overwriting those values
properties: {
Property1: 'foo',
Property2: 'bar',
Expand Down
23 changes: 21 additions & 2 deletions packages/aws-cdk-lib/core/lib/custom-resource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Construct } from 'constructs';
import { Annotations } from './annotations';
import { CfnResource } from './cfn-resource';
import { Duration } from './duration';
import { addConstructMetadata, MethodMetadata } from './metadata-resource';
Expand Down Expand Up @@ -54,6 +55,8 @@ export interface CustomResourceProps {
* serviceToken: myTopic.topicArn,
* });
* ```
*
* Maps to [ServiceToken](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#cfn-cloudformation-customresource-servicetoken) property for the `AWS::CloudFormation::CustomResource` resource
*/
readonly serviceToken: string;

Expand All @@ -62,13 +65,19 @@ export interface CustomResourceProps {
*
* The value must be between 1 second and 3600 seconds.
*
* Maps to [ServiceTimeout](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#cfn-cloudformation-customresource-servicetimeout) property for the `AWS::CloudFormation::CustomResource` resource
*
* @default Duration.seconds(3600)
*/
readonly serviceTimeout?: Duration;

/**
* Properties to pass to the Lambda
*
* Values in this `properties` dictionary can possibly overwrite other values in `CustomResourceProps`
* E.g. `ServiceToken` and `ServiceTimeout`
* It is recommended to avoid using same keys that exist in `CustomResourceProps`
*
* @default - No properties.
*/
readonly properties?: { [key: string]: any };
Expand Down Expand Up @@ -154,11 +163,21 @@ export class CustomResource extends Resource {
}
}

const constructPropertiesPassed = {
ServiceToken: props.serviceToken,
ServiceTimeout: props.serviceTimeout?.toSeconds().toString(),
};

const hasCommonKeys = Object.keys(properties).some(key => key in constructPropertiesPassed);

if (hasCommonKeys) {
Annotations.of(this).addWarningV2('@aws-cdk/core:customResourcePropConflict', `The following keys will be overwritten as they exist in the 'properties' prop. Keys found: ${Object.keys(properties).filter(key => key in constructPropertiesPassed)}`);
}

this.resource = new CfnResource(this, 'Default', {
type,
properties: {
ServiceToken: props.serviceToken,
ServiceTimeout: props.serviceTimeout?.toSeconds().toString(),
...constructPropertiesPassed,
...properties,
},
});
Expand Down
17 changes: 17 additions & 0 deletions packages/aws-cdk-lib/core/test/custom-resource.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { toCloudFormation } from './util';
import { Annotations } from '../../assertions';
import { CustomResource, Duration, RemovalPolicy, Stack } from '../lib';

describe('custom resource', () => {
Expand Down Expand Up @@ -212,4 +213,20 @@ describe('custom resource', () => {
});
}).toThrow(`serviceTimeout must either be between 1 and 3600 seconds, got ${invalidSeconds}`);
});

test('send warning if customResource construct property key is added to properties', () => {
// GIVEN
const stack = new Stack();

// WHEN
new CustomResource(stack, 'MyCustomResource', {
serviceToken: 'MyServiceToken',
properties: {
ServiceToken: 'RepeatedToken', // this is repeated because serviceToken prop above will resolve as property ServiceToken
},
});

// THEN
Annotations.fromStack(stack).hasWarning('/Default/MyCustomResource', 'The following keys will be overwritten as they exist in the \'properties\' prop. Keys found: ServiceToken [ack: @aws-cdk/core:customResourcePropConflict]');
});
});

0 comments on commit 43afbf2

Please sign in to comment.