Skip to content

Commit

Permalink
feat: add option to configure file name prefix in s3 persistence apda…
Browse files Browse the repository at this point in the history
…ter(#467)
  • Loading branch information
tianrenz committed Sep 27, 2018
1 parent ff34631 commit 10780e0
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import { PersistenceAdapter } from 'ask-sdk-core';
import { RequestEnvelope } from 'ask-sdk-model';
import { S3 } from 'aws-sdk';
import * as path from 'path';
import { createAskSdkError } from '../../utils/AskSdkUtils';
import {
ObjectKeyGenerator,
Expand All @@ -27,15 +28,18 @@ export class S3PersistenceAdapter implements PersistenceAdapter {
protected bucketName : string;
protected s3Client : S3;
protected objectKeyGenerator : ObjectKeyGenerator;
protected pathPrefix : string;

constructor(config : {
bucketName : string,
s3Client? : S3,
objectKeyGenerator? : ObjectKeyGenerator,
pathPrefix? : string,
}) {
this.bucketName = config.bucketName;
this.s3Client = config.s3Client ? config.s3Client : new S3({apiVersion : 'latest'});
this.objectKeyGenerator = config.objectKeyGenerator ? config.objectKeyGenerator : ObjectKeyGenerators.userId;
this.pathPrefix = config.pathPrefix ? config.pathPrefix : '';
}

/**
Expand All @@ -44,7 +48,7 @@ export class S3PersistenceAdapter implements PersistenceAdapter {
* @returns {Promise<Object.<string, any>>}
*/
public async getAttributes(requestEnvelope : RequestEnvelope) : Promise<{[key : string] : string}> {
const objectId = this.objectKeyGenerator(requestEnvelope);
const objectId = path.join(this.pathPrefix, this.objectKeyGenerator(requestEnvelope));

const getParams : S3.GetObjectRequest = {
Bucket : this.bucketName,
Expand Down Expand Up @@ -86,7 +90,7 @@ export class S3PersistenceAdapter implements PersistenceAdapter {
* @return {Promise<void>}
*/
public async saveAttributes(requestEnvelope : RequestEnvelope, attributes : {[key : string] : string}) : Promise<void> {
const objectId = this.objectKeyGenerator(requestEnvelope);
const objectId = path.join(this.pathPrefix, this.objectKeyGenerator(requestEnvelope));

const putParams : S3.PutObjectRequest = {
Bucket : this.bucketName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ describe('S3PersistenceAdapter', () => {
const nonJsonObjectKey = 'nonJsonObjectKey';
const nonJsonObjectAttributes = 'This is a non json string';

const pathPrefixObjectKey = 'folder/userId';
const pathPrefixObjectAttributes = {
pathPrefixKey : 'pathPrefixValue',
};

const bucketInvalidError = new Error('The specified bucket is not valid.');
Object.defineProperty(bucketInvalidError, 'code', {
value : 'InvalidBucketName',
Expand All @@ -61,6 +66,8 @@ describe('S3PersistenceAdapter', () => {
callback(null, {Body : Buffer.from(JSON.stringify(defaultAttributes))});
} else if (params.Key === customObjectKey) {
callback(null, {Body : Buffer.from(JSON.stringify(customAttributes))});
} else if (params.Key === pathPrefixObjectKey) {
callback(null, {Body : Buffer.from(JSON.stringify(pathPrefixObjectAttributes))})
} else if (params.Key === nonJsonObjectKey) {
callback(null, {Body : Buffer.from(nonJsonObjectAttributes)});
} else if (params.Key === emptyBodyKey) {
Expand Down Expand Up @@ -94,12 +101,19 @@ describe('S3PersistenceAdapter', () => {
s3Client : new AWS.S3(),
objectKeyGenerator : ObjectKeyGenerators.deviceId,
});
const pathPrefixPersistenceAdapter = new S3PersistenceAdapter({
bucketName,
pathPrefix : 'folder',
})

const defaultResult = await defaultPersistenceAdapter.getAttributes(requestEnvelope);
expect(defaultResult.defaultKey).eq('defaultValue');

const customResult = await customPersistenceAdapter.getAttributes(requestEnvelope);
expect(customResult.customKey).eq('customValue');

const pathPrefixResult = await pathPrefixPersistenceAdapter.getAttributes(requestEnvelope);
expect(pathPrefixResult.pathPrefixKey).eq('pathPrefixValue');
});

it('should be able to put an item to bucket', async() => {
Expand Down
1 change: 1 addition & 0 deletions docs/en/Managing-Attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ Config Options
* **bucketName** (string) - The name of the S3 bucket used.
* **objectKeyGenerator** (function) - Optional. The function used to generate object key using ``RequestEnvelope``. Default to generate the object key using the ``userId``.
* **s3Client** (`AWS.S3 <https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html>`_ ) - Optional. The ``S3Client`` used to query AWS S3 bucket. You can inject your ``S3Client`` with custom configuration here. Default to use ``new AWS.S3({apiVersion : 'latest'})``.
* **pathPrefix** (string) - The prefix value added to the object key generated. This is used for s3 to mimic a file system structure. Default to empty string.

Method Details
^^^^^^^^^^^^^^
Expand Down

0 comments on commit 10780e0

Please sign in to comment.