Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core): move expiration from s3-deployments into core #10192

Merged
merged 13 commits into from
Sep 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
},

});