Skip to content
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This project is licensed under the MIT License. See LICENSE for more information
- [Installation](#installation)
- [Usage](#usage)
- [Options](#options)
- [Releases](#releases)
---

### Installation
Expand Down Expand Up @@ -66,3 +67,6 @@ storage.SERVICE_NAME()...
| reportsContainer | Azure Reports Container Name | AWS Reports Container Name | GCloud Reports Container Name |
| labelsContainer | Azure Labels Container Name | AWS Labels Container Name | GCloud Labels Container Name |

### Releases

[Release Notes](/README.md)
7 changes: 7 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### 2.0.0
#### Breaking Changes
- AWS and GCP supports container name passed thru params
- AWS and GCP supports new folder structure

### 1.0.3
- Working first release for Azure, AWS and GCP
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "client-cloud-services",
"version": "1.0.1",
"version": "2.0.0",
"description": "Sunbird Client Services - To access cloud services",
"main": "dist/bundle.js",
"module": "dist/bundle.js",
Expand Down
31 changes: 14 additions & 17 deletions src/AWSStorageService.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,13 @@ export class AWSStorageService extends BaseStorageService {

constructor(config) {
super();
if (!_.get(config, 'identity') || !_.get(config, 'credential') ||
!_.get(config, 'region') || !_.get(config, 'containerName')) {
if (!_.get(config, 'identity') || !_.get(config, 'credential') || !_.get(config, 'region')) {
throw new Error('AWS__StorageService :: Required configuration is missing');
}
process.env.AWS_ACCESS_KEY_ID = _.get(config, 'identity');
process.env.AWS_SECRET_ACCESS_KEY = _.get(config, 'credential');
const region = _.get(config, 'region').toString();
this.client = new S3Client({ region });
this.containerName = _.get(config, 'containerName');
this.reportsContainer = _.get(config, 'reportsContainer') + '/';
}

/**
Expand Down Expand Up @@ -69,9 +66,9 @@ export class AWSStorageService extends BaseStorageService {
* @param {string} bucketName - Bucket name or folder name in storage service
* @param {string} fileToGet - File path in storage service
*/
fileReadStream(bucketName = undefined, fileToGet = undefined) {
fileReadStream(_bucketName = undefined, fileToGet = undefined) {
return async (req, res, next) => {
let bucketName = this.containerName;
let bucketName = _bucketName;
let fileToGet = req.params.slug.replace('__', '\/') + '/' + req.params.filename;
logger.info({ msg: 'AWS__StorageService - fileReadStream called for bucketName ' + bucketName + ' for file ' + fileToGet });

Expand All @@ -87,7 +84,7 @@ export class AWSStorageService extends BaseStorageService {
resolve(Buffer.concat(chunks).toString("utf8"))
});
});
await this.client.send(this.getAWSCommand(bucketName, fileToGet, this.reportsContainer)).then((resp) => {
await this.client.send(this.getAWSCommand(bucketName, fileToGet, undefined)).then((resp) => {
streamToString(_.get(resp, 'Body')).then((data) => {
res.end(data);
}).catch((err) => {
Expand All @@ -101,11 +98,11 @@ export class AWSStorageService extends BaseStorageService {
}
});
} else {
this.fileExists(bucketName, fileToGet, this.reportsContainer, async (error, resp) => {
this.fileExists(bucketName, fileToGet, undefined, async (error, resp) => {
if (_.get(error, '$metadata.httpStatusCode') == 404) {
storageLogger.s404(res, 'AWS__StorageService : fileExists error - Error with status code 404', error, 'File does not exists');
} else if (_.get(resp, '$metadata.httpStatusCode') == 200) {
const command = this.getAWSCommand(bucketName, fileToGet, this.reportsContainer);
const command = this.getAWSCommand(bucketName, fileToGet, undefined);
// `expiresIn` - The number of seconds before the presigned URL expires
const presignedURL = await getSignedUrl(this.client, command, { expiresIn: 3600 });
const response = {
Expand All @@ -128,9 +125,9 @@ export class AWSStorageService extends BaseStorageService {
}
}

getFileProperties() {
getFileProperties(_bucketName = undefined) {
return (req, res, next) => {
const bucketName = this.containerName;
const bucketName = _bucketName;
const fileToGet = JSON.parse(req.query.fileNames);
logger.info({ msg: 'AWS__StorageService - getFileProperties called for bucketName ' + bucketName + ' for file ' + fileToGet });
const responseData = {};
Expand Down Expand Up @@ -179,7 +176,7 @@ export class AWSStorageService extends BaseStorageService {
}

async getBlobProperties(request, callback) {
this.fileExists(request.bucketName, request.file, this.reportsContainer, (error, resp) => {
this.fileExists(request.bucketName, request.file, undefined, (error, resp) => {
if (_.get(error, '$metadata.httpStatusCode') == 404) {
logger.error({ msg: 'AWS__StorageService : getBlobProperties_fileExists error - Error with status code 404. File does not exists - ' + request.file, error: error });
callback({ msg: _.get(error, 'name'), statusCode: _.get(error, '$metadata.httpStatusCode'), filename: request.file, reportname: request.reportname })
Expand All @@ -200,8 +197,8 @@ export class AWSStorageService extends BaseStorageService {
}

async getFileAsText(container = undefined, fileToGet = undefined, callback) {
const bucketName = this.containerName;
logger.info({ msg: 'AWS__StorageService : getFileAsText called for bucket ' + bucketName + ' container ' + container + ' for file ' + fileToGet });
const bucketName = container;
logger.info({ msg: 'AWS__StorageService : getFileAsText called for bucket ' + bucketName + ' for file ' + fileToGet });
const streamToString = (stream) =>
new Promise((resolve, reject) => {
const chunks = [];
Expand All @@ -213,7 +210,7 @@ export class AWSStorageService extends BaseStorageService {
resolve(Buffer.concat(chunks).toString("utf8"))
});
});
await this.client.send(this.getAWSCommand(bucketName, fileToGet, container)).then((resp) => {
await this.client.send(this.getAWSCommand(bucketName, fileToGet)).then((resp) => {
streamToString(_.get(resp, 'Body')).then((data) => {
callback(null, data);
}).catch((err) => {
Expand All @@ -233,15 +230,15 @@ export class AWSStorageService extends BaseStorageService {
blockStreamUpload(uploadContainer = undefined) {
return (req, res) => {
try {
const bucketName = this.containerName;
const bucketName = uploadContainer;
const blobFolderName = new Date().toLocaleDateString();
let form = new multiparty.Form();
form.on('part', async (part) => {
if (part.filename) {
let size = part.byteCount - part.byteOffset;
let name = `${_.get(req, 'query.deviceId')}_${Date.now()}.${_.get(part, 'filename')}`;
logger.info({
msg: 'AWS__StorageService : blockStreamUpload Uploading file to container ' +
msg: 'AWS__StorageService : blockStreamUpload Uploading file to bucket ' +
uploadContainer + ' to folder ' + blobFolderName +
' for file name ' + name + ' with size ' + size
});
Expand Down
3 changes: 2 additions & 1 deletion src/AzureStorageService.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class AzureStorageService extends BaseStorageService {
if (!_.get(config, 'identity') || !_.get(config, 'credential')) {
throw new Error('Azure__StorageService :: Required configuration is missing');
}
this.reportsContainer = _.get(config, 'reportsContainer') + '/';
this.reportsContainer = _.get(config, 'reportsContainer')?.toString();
this.blobService = azure.createBlobService(config?.identity, config?.credential);
}

Expand Down Expand Up @@ -148,6 +148,7 @@ export class AzureStorageService extends BaseStorageService {
}

async getBlobProperties(request, callback) {
logger.info({ msg: 'Azure__StorageService - getBlobProperties called for container ' + request.container + ' for file ' + request.file });
this.blobService.getBlobProperties(request.container, request.file, function (err, result, response) {
if (err) {
logger.error({ msg: 'Azure__StorageService : readStream error - Error with status code 404' });
Expand Down
21 changes: 9 additions & 12 deletions src/GCPStorageService.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@ export class GCPStorageService extends BaseStorageService {

constructor(config) {
super();
if (!_.get(config, 'identity') || !_.get(config, 'credential') ||
!_.get(config, 'projectId') || !_.get(config, 'containerName')) {
if (!_.get(config, 'identity') || !_.get(config, 'credential') || !_.get(config, 'projectId')) {
throw new Error('GCLOUD__StorageService :: Required configuration is missing');
}
this.containerName = _.get(config, 'containerName');
this.reportsContainer = _.get(config, 'reportsContainer') + '/';
this._storage = new Storage({
credentials: {
client_email: _.get(config, 'identity'),
Expand Down Expand Up @@ -53,10 +50,10 @@ export class GCPStorageService extends BaseStorageService {
* @param {string} bucketName - Bucket name or folder name in storage service
* @param {string} fileToGet - File path in storage service
*/
fileReadStream(bucketName = undefined, fileToGet = undefined) {
fileReadStream(_bucketName = undefined, fileToGet = undefined) {
return async (req, res, next) => {
let bucketName = this.containerName;
let fileToGet = this.reportsContainer + req.params.slug.replace('__', '\/') + '/' + req.params.filename;
let bucketName = _bucketName;
let fileToGet = _bucketName + req.params.slug.replace('__', '\/') + '/' + req.params.filename;
logger.info({ msg: 'GCLOUD__StorageService - fileReadStream called for bucketName ' + bucketName + ' for file ' + fileToGet });

if (fileToGet.includes('.json')) {
Expand Down Expand Up @@ -138,9 +135,9 @@ export class GCPStorageService extends BaseStorageService {
}).catch((err) => cb(_.get(err, 'message')));
}

getFileProperties() {
getFileProperties(_bucketName = undefined) {
return (req, res, next) => {
const bucketName = this.containerName;
const bucketName = _bucketName;
const fileToGet = JSON.parse(req.query.fileNames);
logger.info({ msg: 'GCLOUD__StorageService - getFileProperties called for bucketName ' + bucketName + ' for file ' + fileToGet });
const responseData = {};
Expand Down Expand Up @@ -189,7 +186,7 @@ export class GCPStorageService extends BaseStorageService {
}

async getBlobProperties(request, callback) {
const file = this._storage.bucket(request.bucketName).file(this.reportsContainer + request.file);
const file = this._storage.bucket(request.bucketName).file(request.file);
file.getMetadata((err, metadata, resp) => {
if (err) {
logger.error({ msg: 'GCLOUD__StorageService : getBlobProperties_getMetadata client send error - Error 500 Failed to check file exists', err: err });
Expand All @@ -213,8 +210,8 @@ export class GCPStorageService extends BaseStorageService {
}

async getFileAsText(container = undefined, fileToGet = undefined, callback) {
const bucketName = this.containerName;
logger.info({ msg: 'GCLOUD__StorageService : getFileAsText called for bucket ' + bucketName + ' container ' + container + ' for file ' + fileToGet });
const bucketName = container;
logger.info({ msg: 'GCLOUD__StorageService : getFileAsText called for bucket ' + bucketName + ' for file ' + fileToGet });
const file = this._storage.bucket(bucketName).file(container + fileToGet);
const fileStream = file.createReadStream();
const streamToString = (stream) =>
Expand Down