Merge branch 'master' of https://github.com/ParsePlatform/parse-server into mcdonald-gcs-adapter

Get GCSAdapter up to snuff with FilesController + FilesControllerTestFactory

* 'master' of https://github.com/ParsePlatform/parse-server: (102 commits)
  Remove duplicated instructions
  Release and Changelog for 2.1.4
  fixes missing coverage with sh script
  Fix update system schema
  Adds optional COVERAGE
  Allows to pass no where in $select clause
  Sanitize objectId in
  Fix delete schema when actual collection does not exist
  Fix replace query overwrite the existing query object.
  Fix create system class with relation/pointer
  Use throws syntax for errors in SchemasRouter.
  Completely migrate SchemasRouter to new MongoCollection API.
  Add tests that verify installationId in Cloud Code triggers.
  Propagate installationId in all Cloud Code triggers.
  Add test
  expiresAt should be a Date, not a string. Fixes #776
  Fix missing 'let/var' in OneSignalPushAdapter.spec.
  Don't run any afterSave hooks if none are registered.
  Fix : remove query count limit
  Flatten custom operations in request.object in afterSave hooks.
  ...
This commit is contained in:
Mike McDonald
2016-03-03 22:36:25 -08:00
83 changed files with 4170 additions and 1458 deletions

View File

@@ -1,16 +1,18 @@
// GCSAdapter
// Store Parse Files in Google Cloud Storage: https://cloud.google.com/storage
import * as gcloud from 'gcloud';
import { storage } from 'gcloud';
import { FilesAdapter } from './FilesAdapter';
import requiredParameter from '../../requiredParameter';
export class GCSAdapter extends FilesAdapter {
// GCS Project ID and the name of a corresponding Keyfile are required.
// Unlike the S3 adapter, you must create a new Cloud Storage bucket, as this is not created automatically.
// See https://googlecloudplatform.github.io/gcloud-node/#/docs/master/guides/authentication
// for more details.
constructor(
projectId,
keyFilename,
bucket,
projectId = requiredParameter('GCSAdapter requires a GCP Project ID'),
keyFilename = requiredParameter('GCSAdapter requires a GCP keyfile'),
bucket = requiredParameter('GCSAdapter requires a GCS bucket name'),
{ bucketPrefix = '',
directAccess = false } = {}
) {
@@ -20,21 +22,25 @@ export class GCSAdapter extends FilesAdapter {
this._bucketPrefix = bucketPrefix;
this._directAccess = directAccess;
let gcsOptions = {
let options = {
projectId: projectId,
keyFilename: keyFilename
};
this._gcsClient = new gcloud.storage(gcsOptions);
this._gcsClient = new storage(options);
}
// For a given config object, filename, and data, store a file in GCS.
// Resolves the promise or fails with an error.
createFile(config, filename, data) {
createFile(config, filename, data, contentType) {
let params = {
contentType: contentType || 'application/octet-stream'
};
return new Promise((resolve, reject) => {
let file = this._gcsClient.bucket(this._bucket).file(this._bucketPrefix + filename);
// gcloud supports upload(file) not upload(bytes), so we need to stream.
var uploadStream = file.createWriteStream();
var uploadStream = file.createWriteStream(params);
uploadStream.on('error', (err) => {
return reject(err);
}).on('finish', () => {
@@ -61,6 +67,7 @@ export class GCSAdapter extends FilesAdapter {
return new Promise((resolve, reject) => {
let file = this._gcsClient.bucket(this._bucket).file(this._bucketPrefix + filename);
file.delete((err, res) => {
console.log("delete: ", filename, err, res);
if(err !== null) {
return reject(err);
}
@@ -74,11 +81,19 @@ export class GCSAdapter extends FilesAdapter {
getFileData(config, filename) {
return new Promise((resolve, reject) => {
let file = this._gcsClient.bucket(this._bucket).file(this._bucketPrefix + filename);
file.download((err, data) => {
if (err !== null) {
return reject(err);
// Check for existence, since gcloud-node seemed to be caching the result
file.exists((err, exists) => {
if (exists) {
file.download((err, data) => {
console.log("get: ", filename, err, data);
if (err !== null) {
return reject(err);
}
return resolve(data);
});
} else {
reject(err);
}
resolve(data);
});
});
}