Skip to content

Commit

Permalink
refactor(core): move expiration from s3-deployments into core (#10192)
Browse files Browse the repository at this point in the history
Move `Expires` class from s3-deployments to core. Rename to `Expiration`

**BREAKING CHANGE**: s3-deployments property `expires` takes `cdk.Expiration` instead of  `Expires`
- **s3-deployments**: `BucketDeploymentProps.expires` now takes in type `cdk.Expiration`

**Note**: PR separated from #9122

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
BryanPan342 authored Sep 8, 2020
1 parent 5f36f6b commit 0e6e3c3
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 11 deletions.
9 changes: 5 additions & 4 deletions packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';
import { ISource, SourceConfig } from './source';

const now = Date.now();
const handlerCodeBundle = path.join(__dirname, '..', 'lambda', 'bundle.zip');
const handlerSourceDirectory = path.join(__dirname, '..', 'lambda', 'src');

Expand Down Expand Up @@ -129,7 +128,7 @@ export interface BucketDeploymentProps {
* @default - The objects in the distribution will not expire.
* @see https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#SysMetadata
*/
readonly expires?: Expires;
readonly expires?: cdk.Expiration;
/**
* System-defined x-amz-server-side-encryption metadata to be set on all objects in the deployment.
* @default - Server side encryption is not used.
Expand Down Expand Up @@ -271,7 +270,7 @@ function mapSystemMetadata(metadata: BucketDeploymentProps) {
const res: { [key: string]: string } = {};

if (metadata.cacheControl) { res['cache-control'] = metadata.cacheControl.map(c => c.value).join(', '); }
if (metadata.expires) { res.expires = metadata.expires.value; }
if (metadata.expires) { res.expires = metadata.expires.date.toUTCString(); }
if (metadata.contentDisposition) { res['content-disposition'] = metadata.contentDisposition; }
if (metadata.contentEncoding) { res['content-encoding'] = metadata.contentEncoding; }
if (metadata.contentLanguage) { res['content-language'] = metadata.contentLanguage; }
Expand Down Expand Up @@ -330,6 +329,8 @@ export enum StorageClass {
/**
* Used for HTTP expires header, which influences downstream caches. Does NOT influence deletion of the object.
* @see https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#SysMetadata
*
* @deprecated use core.Expiration
*/
export class Expires {
/**
Expand All @@ -348,7 +349,7 @@ export class Expires {
* Expire once the specified duration has passed since deployment time
* @param t the duration to wait before expiring
*/
public static after(t: cdk.Duration) { return Expires.atDate(new Date(now + t.toMilliseconds())); }
public static after(t: cdk.Duration) { return Expires.atDate(new Date(Date.now() + t.toMilliseconds())); }

public static fromString(s: string) { return new Expires(s); }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ test('system metadata is correctly transformed', () => {
serverSideEncryptionCustomerAlgorithm: 'rot13',
websiteRedirectLocation: 'example',
cacheControl: [s3deploy.CacheControl.setPublic(), s3deploy.CacheControl.maxAge(cdk.Duration.hours(1))],
expires: s3deploy.Expires.after(cdk.Duration.hours(12)),
expires: cdk.Expiration.after(cdk.Duration.hours(12)),
});

// THEN
Expand All @@ -331,19 +331,18 @@ test('system metadata is correctly transformed', () => {
'sse': 'aws:kms',
'sse-kms-key-id': 'mykey',
'cache-control': 'public, max-age=3600',
'expires': s3deploy.Expires.after(cdk.Duration.hours(12)).value,
'expires': cdk.Expiration.after(cdk.Duration.hours(12)).date.toUTCString(),
'sse-c-copy-source': 'rot13',
'website-redirect': 'example',
},
});
});

test('expires type has correct values', () => {
expect(s3deploy.Expires.atDate(new Date('Sun, 26 Jan 2020 00:53:20 GMT')).value).toEqual('Sun, 26 Jan 2020 00:53:20 GMT');
expect(s3deploy.Expires.atTimestamp(1580000000000).value).toEqual('Sun, 26 Jan 2020 00:53:20 GMT');
expect(Math.abs(new Date(s3deploy.Expires.after(cdk.Duration.minutes(10)).value).getTime() - (Date.now() + 600000)) < 15000).toBeTruthy();
expect(s3deploy.Expires.fromString('Tue, 04 Feb 2020 08:45:33 GMT').value).toEqual('Tue, 04 Feb 2020 08:45:33 GMT');

expect(cdk.Expiration.atDate(new Date('Sun, 26 Jan 2020 00:53:20 GMT')).date.toUTCString()).toEqual('Sun, 26 Jan 2020 00:53:20 GMT');
expect(cdk.Expiration.atTimestamp(1580000000000).date.toUTCString()).toEqual('Sun, 26 Jan 2020 00:53:20 GMT');
expect(Math.abs(new Date(cdk.Expiration.after(cdk.Duration.minutes(10)).date.toUTCString()).getTime() - (Date.now() + 600000)) < 15000).toBeTruthy();
expect(cdk.Expiration.fromString('Tue, 04 Feb 2020 08:45:33 GMT').date.toUTCString()).toEqual('Tue, 04 Feb 2020 08:45:33 GMT');
});

test('cache control type has correct values', () => {
Expand Down
63 changes: 63 additions & 0 deletions packages/@aws-cdk/core/lib/expiration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Duration } from './duration';
/**
* Represents a date of expiration.
*
* The amount can be specified either as a Date object, timestamp, Duration or string.
*/
export class Expiration {
/**
* Expire at the specified date
* @param d date to expire at
*/
public static atDate(d: Date) { return new Expiration(d); }

/**
* Expire at the specified timestamp
* @param t timestamp in unix milliseconds
*/
public static atTimestamp(t: number) { return Expiration.atDate(new Date(t)); }

/**
* Expire once the specified duration has passed since deployment time
* @param t the duration to wait before expiring
*/
public static after(t: Duration) { return Expiration.atDate(new Date(Date.now() + t.toMilliseconds())); }

/**
* Expire at specified date, represented as a string
*
* @param s the string that represents date to expire at
*/
public static fromString(s: string) { return new Expiration(new Date(s)); }

/**
* Expiration value as a Date object
*/
public readonly date: Date;

private constructor(date: Date) {
this.date = date;
}

/**
* Exipration Value in a formatted Unix Epoch Time in seconds
*/
public toEpoch(): number {
return Math.round(this.date.getTime() / 1000);
}
/**
* Check if Exipiration expires before input
* @param t the duration to check against
*/
public isBefore(t: Duration): boolean {
return this.date < new Date(Date.now() + t.toMilliseconds());
}

/**
* Check if Exipiration expires after input
* @param t the duration to check against
*/
public isAfter( t: Duration ): boolean {
return this.date > new Date(Date.now() + t.toMilliseconds());
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/core/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export * from './cfn-json';
export * from './removal-policy';
export * from './arn';
export * from './duration';
export * from './expiration';
export * from './size';
export * from './stack-trace';

Expand Down
49 changes: 49 additions & 0 deletions packages/@aws-cdk/core/test/test.expiration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as nodeunit from 'nodeunit';
import { Duration, Expiration } from '../lib';

export = nodeunit.testCase({
'from string'(test: nodeunit.Test) {
const date = new Date('Sun, 26 Jan 2020 00:53:20 GMT');
test.equal(Expiration.fromString('Sun, 26 Jan 2020 00:53:20 GMT').date.getDate(), date.getDate());
test.done();
},

'at specified date'(test: nodeunit.Test) {
const date = new Date('Sun, 26 Jan 2020 00:53:20 GMT');
test.equal(Expiration.atDate(new Date('Sun, 26 Jan 2020 00:53:20 GMT')).date.toUTCString(), 'Sun, 26 Jan 2020 00:53:20 GMT');
test.equal(Expiration.atDate(new Date(1580000000000)).date.toUTCString(), 'Sun, 26 Jan 2020 00:53:20 GMT');
test.equal(Expiration.atDate(new Date(date)).date.toUTCString(), 'Sun, 26 Jan 2020 00:53:20 GMT');
test.done();
},

'at time stamp'(test: nodeunit.Test) {
test.equal(Expiration.atDate(new Date(1580000000000)).date.toUTCString(), 'Sun, 26 Jan 2020 00:53:20 GMT');
test.done();
},

'after'(test: nodeunit.Test) {
test.ok(Math.abs(new Date(Expiration.after(Duration.minutes(10)).date.toUTCString()).getTime() - (Date.now() + 600000)) < 15000);
test.done();
},

'toEpoch returns correct value'(test: nodeunit.Test) {
const date = new Date('Sun, 26 Jan 2020 00:53:20 GMT');
test.equal(Expiration.atDate(date).toEpoch(), 1580000000);
test.done();
},

'isBefore'(test: nodeunit.Test) {
const expire = Expiration.after(Duration.days(2));
test.ok(!expire.isBefore(Duration.days(1)));
test.ok(expire.isBefore(Duration.days(3)));
test.done();
},

'isAfter'(test: nodeunit.Test) {
const expire = Expiration.after(Duration.days(2));
test.ok(expire.isAfter(Duration.days(1)));
test.ok(!expire.isAfter(Duration.days(3)));
test.done();
},

});

0 comments on commit 0e6e3c3

Please sign in to comment.