Skip to content

Commit

Permalink
Added FilesAdapter for Azure Blob Storage
Browse files Browse the repository at this point in the history
  • Loading branch information
aneeshd16 committed Feb 28, 2016
1 parent bd89338 commit c020e9e
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"apn": "^1.7.5",
"aws-sdk": "~2.2.33",
"babel-polyfill": "^6.5.0",
"azure-storage": "^0.8.0",
"babel-runtime": "^6.5.0",
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.14.2",
Expand Down
116 changes: 116 additions & 0 deletions src/Adapters/Files/AzureBlobStorageAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// AzureBlobStorageAdapter
//
// Stores Parse files in Azure Blob Storage.

import * as azure from 'azure-storage';
import { FilesAdapter } from './FilesAdapter';

export class AzureBlobStorageAdapter extends FilesAdapter {
// Creates an Azure Storage client.
// Provide storage account name or storage account connection string as first parameter
// Provide container name as second parameter
// If you had provided storage account name, then also provide storage access key
// Host is optional, Azure will default to the default host
// directAccess defaults to false. If set to true, the file URL will be the actual blob URL
constructor(
storageAccountOrConnectionString,
container, {
storageAccessKey = '',
host = '',
directAccess = false
} = {}
) {
super();

this._storageAccountOrConnectionString = storageAccountOrConnectionString;
this._storageAccessKey = storageAccessKey;
this._host = host;
this._container = container;
this._directAccess = directAccess;
if (this._storageAccountOrConnectionString.indexOf(';') != -1) {
// Connection string was passed
// Extract storage account name
// Storage account name is needed in getFileLocation
this._storageAccountName = this._storageAccountOrConnectionString.substring(
this._storageAccountOrConnectionString.indexOf('AccountName') + 12,
this._storageAccountOrConnectionString.indexOf(';', this._storageAccountOrConnectionString.indexOf('AccountName') + 12)
);
} else {
// Storage account name was passed
this._storageAccountName = this._storageAccountOrConnectionString;
}
// Init client
this._azureBlobStorageClient = azure.createBlobService(this._storageAccountOrConnectionString, this._storageAccessKey, this._host);
}

// For a given config object, filename, and data, store a file in Azure Blob Storage
// Returns a promise containing the Azure Blob Storage blob creation response
createFile(config, filename, data) {
let containerParams = {};
if (this._directAccess) {
containerParams.publicAccessLevel = 'blob';
}

return new Promise((resolve, reject) => {
this._azureBlobStorageClient.createContainerIfNotExists(
this._container,
containerParams,
(cerror, cresult, cresponse) => {
if (cerror) {
return reject(cerror);
}
this._azureBlobStorageClient.createBlockBlobFromText(
this._container,
filename,
data,
(error, result, response) => {
if (error) {
return reject(error);
}
resolve(result);
});
});
});
}

deleteFile(config, filename) {
return new Promise((resolve, reject) => {
this._azureBlobStorageClient.deleteBlob(
this._container,
filename,
(error, response) => {
if (error) {
return reject(error);
}
resolve(response);
});
});
}

// Search for and return a file if found by filename
// Returns a promise that succeeds with the buffer result from Azure Blob Storage
getFileData(config, filename) {
return new Promise((resolve, reject) => {
this._azureBlobStorageClient.getBlobToText(
this._container,
filename,
(error, text, blob, response) => {
if (error) {
return reject(error);
}
resolve(text);
});
});
}

// Generates and returns the location of a file stored in Azure Blob Storage for the given request and filename
// The location is the direct Azure Blob Storage link if the option is set, otherwise we serve the file through parse-server
getFileLocation(config, filename) {
if (this._directAccess) {
return `http://${this._storageAccountName}.blob.core.windows.net/${this._container}/${filename}`;
}
return (config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename));
}
}

export default AzureBlobStorageAdapter;
10 changes: 6 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ var batch = require('./batch'),

import cache from './cache';
import PromiseRouter from './PromiseRouter';
import { GridStoreAdapter } from './Adapters/Files/GridStoreAdapter';
import { S3Adapter } from './Adapters/Files/S3Adapter';
import { FilesController } from './Controllers/FilesController';
import { GridStoreAdapter } from './Adapters/Files/GridStoreAdapter';
import { S3Adapter } from './Adapters/Files/S3Adapter';
import { AzureBlobStorageAdapter } from './Adapters/Files/AzureBlobStorageAdapter';
import { FilesController } from './Controllers/FilesController';

import ParsePushAdapter from './Adapters/Push/ParsePushAdapter';
import { PushController } from './Controllers/PushController';
Expand Down Expand Up @@ -229,5 +230,6 @@ function getClassName(parseClass) {

module.exports = {
ParseServer: ParseServer,
S3Adapter: S3Adapter
S3Adapter: S3Adapter,
AzureBlobStorageAdapter: AzureBlobStorageAdapter
};

0 comments on commit c020e9e

Please sign in to comment.