Database version in features (#5627)
* adding database.version in the serverInfo (only MongoDB, it gives undefined when using Postgres) * . correction of old 'features' tests . adding engine and database in the StorageAdapter interface and implementations * . version retrieval done in performInitialization . PostgreSQL version * performInitialization now returns a Promise
This commit is contained in:
committed by
Diamond Lewis
parent
266d6328a3
commit
7fc0d45b89
@@ -3,20 +3,41 @@
|
||||
const request = require('../lib/request');
|
||||
|
||||
describe('features', () => {
|
||||
it('requires the master key to get features', done => {
|
||||
request({
|
||||
it('should return the serverInfo', async () => {
|
||||
const response = await request({
|
||||
url: 'http://localhost:8378/1/serverInfo',
|
||||
json: true,
|
||||
headers: {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
'X-Parse-Master-Key': 'test',
|
||||
},
|
||||
}).then(fail, response => {
|
||||
expect(response.status).toEqual(403);
|
||||
expect(response.data.error).toEqual(
|
||||
'unauthorized: master key is required'
|
||||
);
|
||||
done();
|
||||
});
|
||||
const data = response.data;
|
||||
expect(data).toBeDefined();
|
||||
expect(data.features).toBeDefined();
|
||||
expect(data.parseServerVersion).toBeDefined();
|
||||
expect(data.database).toBeDefined();
|
||||
expect(['MongoDB', 'PostgreSQL']).toContain(data.database.engine);
|
||||
});
|
||||
|
||||
it('requires the master key to get features', async done => {
|
||||
try {
|
||||
await request({
|
||||
url: 'http://localhost:8378/1/serverInfo',
|
||||
json: true,
|
||||
headers: {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
},
|
||||
});
|
||||
done.fail(
|
||||
'The serverInfo request should be rejected without the master key'
|
||||
);
|
||||
} catch (error) {
|
||||
expect(error.status).toEqual(403);
|
||||
expect(error.data.error).toEqual('unauthorized: master key is required');
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -126,6 +126,8 @@ export class MongoStorageAdapter implements StorageAdapter {
|
||||
client: MongoClient;
|
||||
_maxTimeMS: ?number;
|
||||
canSortOnJoinTables: boolean;
|
||||
databaseVersion: string;
|
||||
engine: string;
|
||||
|
||||
constructor({
|
||||
uri = defaults.DefaultMongoURI,
|
||||
@@ -136,6 +138,7 @@ export class MongoStorageAdapter implements StorageAdapter {
|
||||
this._collectionPrefix = collectionPrefix;
|
||||
this._mongoOptions = mongoOptions;
|
||||
this._mongoOptions.useNewUrlParser = true;
|
||||
this.engine = 'MongoDB';
|
||||
|
||||
// MaxTimeMS is not a global MongoDB client option, it is applied per operation.
|
||||
this._maxTimeMS = mongoOptions.maxTimeMS;
|
||||
@@ -959,7 +962,15 @@ export class MongoStorageAdapter implements StorageAdapter {
|
||||
}
|
||||
|
||||
performInitialization(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
// databaseVersion
|
||||
return this.connect()
|
||||
.then(() => {
|
||||
const adminDb = this.database.admin();
|
||||
return adminDb.serverStatus();
|
||||
})
|
||||
.then(status => {
|
||||
this.databaseVersion = status.version;
|
||||
});
|
||||
}
|
||||
|
||||
createIndex(className: string, index: any) {
|
||||
|
||||
@@ -778,6 +778,8 @@ const buildWhereClause = ({ schema, query, index }): WhereClause => {
|
||||
|
||||
export class PostgresStorageAdapter implements StorageAdapter {
|
||||
canSortOnJoinTables: boolean;
|
||||
databaseVersion: string;
|
||||
engine: string;
|
||||
|
||||
// Private
|
||||
_collectionPrefix: string;
|
||||
@@ -790,6 +792,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
|
||||
this._client = client;
|
||||
this._pgp = pgp;
|
||||
this.canSortOnJoinTables = false;
|
||||
this.engine = 'PostgreSQL';
|
||||
}
|
||||
|
||||
handleShutdown() {
|
||||
@@ -2276,6 +2279,12 @@ export class PostgresStorageAdapter implements StorageAdapter {
|
||||
})
|
||||
.then(data => {
|
||||
debug(`initializationDone in ${data.duration}`);
|
||||
// databaseVersion
|
||||
return this._client.query('SHOW server_version');
|
||||
})
|
||||
.then(versionData => {
|
||||
// versionData is like [ { server_version: '11.3' } ]
|
||||
this.databaseVersion = versionData[0].server_version;
|
||||
})
|
||||
.catch(error => {
|
||||
/* eslint-disable no-console */
|
||||
|
||||
@@ -25,6 +25,8 @@ export type FullQueryOptions = QueryOptions & UpdateQueryOptions;
|
||||
|
||||
export interface StorageAdapter {
|
||||
canSortOnJoinTables: boolean;
|
||||
databaseVersion: string;
|
||||
engine: string;
|
||||
|
||||
classExists(className: string): Promise<boolean>;
|
||||
setClassLevelPermissions(className: string, clps: any): Promise<void>;
|
||||
|
||||
@@ -9,6 +9,7 @@ export class FeaturesRouter extends PromiseRouter {
|
||||
'/serverInfo',
|
||||
middleware.promiseEnforceMasterKeyAccess,
|
||||
req => {
|
||||
const { config } = req;
|
||||
const features = {
|
||||
globalConfig: {
|
||||
create: true,
|
||||
@@ -33,9 +34,9 @@ export class FeaturesRouter extends PromiseRouter {
|
||||
from: true,
|
||||
},
|
||||
push: {
|
||||
immediatePush: req.config.hasPushSupport,
|
||||
scheduledPush: req.config.hasPushScheduledSupport,
|
||||
storedPushData: req.config.hasPushSupport,
|
||||
immediatePush: config.hasPushSupport,
|
||||
scheduledPush: config.hasPushScheduledSupport,
|
||||
storedPushData: config.hasPushSupport,
|
||||
pushAudiences: true,
|
||||
localization: true,
|
||||
},
|
||||
@@ -51,10 +52,15 @@ export class FeaturesRouter extends PromiseRouter {
|
||||
},
|
||||
};
|
||||
|
||||
const dbAdapter = config.database.adapter;
|
||||
return {
|
||||
response: {
|
||||
features: features,
|
||||
parseServerVersion: version,
|
||||
database: {
|
||||
engine: dbAdapter.engine,
|
||||
version: dbAdapter.databaseVersion,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user