From 7e6cf381332b2df0709da6eee5a52e7154845b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Miko=C5=82ajczyk?= Date: Tue, 19 Jul 2016 13:56:32 +0200 Subject: [PATCH 1/2] Allow usage of analytics adapter --- src/Adapters/Analytics/AnalyticsAdapter.js | 9 +++++++++ src/Config.js | 1 + src/Controllers/AnalyticsController.js | 15 +++++++++++++++ src/ParseServer.js | 8 +++++++- src/Routers/AnalyticsRouter.js | 12 +++++------- 5 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 src/Adapters/Analytics/AnalyticsAdapter.js create mode 100644 src/Controllers/AnalyticsController.js diff --git a/src/Adapters/Analytics/AnalyticsAdapter.js b/src/Adapters/Analytics/AnalyticsAdapter.js new file mode 100644 index 0000000000..523ee6799a --- /dev/null +++ b/src/Adapters/Analytics/AnalyticsAdapter.js @@ -0,0 +1,9 @@ +export class AnalyticsAdapter { + post(req) { + return Promise.resolve({ + response: {} + }); + } +} + +export default AnalyticsAdapter; diff --git a/src/Config.js b/src/Config.js index 927319ab88..83cec09dcd 100644 --- a/src/Config.js +++ b/src/Config.js @@ -39,6 +39,7 @@ export class Config { this.preventLoginWithUnverifiedEmail = cacheInfo.preventLoginWithUnverifiedEmail; this.appName = cacheInfo.appName; + this.analyticsController = cacheInfo.analyticsController; this.cacheController = cacheInfo.cacheController; this.hooksController = cacheInfo.hooksController; this.filesController = cacheInfo.filesController; diff --git a/src/Controllers/AnalyticsController.js b/src/Controllers/AnalyticsController.js new file mode 100644 index 0000000000..bda1f139d2 --- /dev/null +++ b/src/Controllers/AnalyticsController.js @@ -0,0 +1,15 @@ +import AdaptableController from './AdaptableController'; +import { AnalyticsAdapter } from '../Adapters/Analytics/AnalyticsAdapter'; + +export class AnalyticsController extends AdaptableController { + post(req) { + var analyticsAdapter = this.adapter; + return analyticsAdapter.post(req); + } + + expectedAdapterType() { + return AnalyticsAdapter; + } +} + +export default AnalyticsController; diff --git a/src/ParseServer.js b/src/ParseServer.js index 7e96d7c55a..ce2471f8a0 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -25,7 +25,9 @@ import { AnalyticsRouter } from './Routers/AnalyticsRouter'; import { ClassesRouter } from './Routers/ClassesRouter'; import { FeaturesRouter } from './Routers/FeaturesRouter'; import { InMemoryCacheAdapter } from './Adapters/Cache/InMemoryCacheAdapter'; +import { AnalyticsController } from './Controllers/AnalyticsController'; import { CacheController } from './Controllers/CacheController'; +import { AnalyticsAdapter } from './Adapters/Analytics/AnalyticsAdapter'; import { FileLoggerAdapter } from './Adapters/Logger/FileLoggerAdapter'; import { FilesController } from './Controllers/FilesController'; import { FilesRouter } from './Routers/FilesRouter'; @@ -65,6 +67,7 @@ const requiredUserFields = { fields: { ...SchemaController.defaultColumns._Defau // ParseServer works like a constructor of an express app. // The args that we understand are: +// "analyticsAdapter": an adapter class for analytics // "filesAdapter": a class like GridStoreAdapter providing create, get, // and delete // "loggerAdapter": a class like FileLoggerAdapter providing info, error, @@ -95,6 +98,7 @@ class ParseServer { appId = requiredParameter('You must provide an appId!'), masterKey = requiredParameter('You must provide a masterKey!'), appName, + analyticsAdapter = undefined, filesAdapter, push, loggerAdapter, @@ -137,7 +141,6 @@ class ParseServer { // Initialize the node client SDK automatically Parse.initialize(appId, javascriptKey || 'unused', masterKey); Parse.serverURL = serverURL; - if ((databaseOptions || databaseURI || collectionPrefix !== '') && databaseAdapter) { throw 'You cannot specify both a databaseAdapter and a databaseURI/databaseOptions/connectionPrefix.'; } else if (!databaseAdapter) { @@ -183,6 +186,7 @@ class ParseServer { const loggerControllerAdapter = loadAdapter(loggerAdapter, FileLoggerAdapter); const emailControllerAdapter = loadAdapter(emailAdapter); const cacheControllerAdapter = loadAdapter(cacheAdapter, InMemoryCacheAdapter, {appId: appId}); + const analyticsControllerAdapter = loadAdapter(analyticsAdapter, AnalyticsAdapter); // We pass the options and the base class for the adatper, // Note that passing an instance would work too @@ -194,6 +198,7 @@ class ParseServer { const cacheController = new CacheController(cacheControllerAdapter, appId); const databaseController = new DatabaseController(databaseAdapter); const hooksController = new HooksController(appId, databaseController, webhookKey); + const analyticsController = new AnalyticsController(analyticsControllerAdapter); // TODO: create indexes on first creation of a _User object. Otherwise it's impossible to // have a Parse app without it having a _User collection. @@ -225,6 +230,7 @@ class ParseServer { webhookKey: webhookKey, fileKey: fileKey, facebookAppIds: facebookAppIds, + analyticsController: analyticsController, cacheController: cacheController, filesController: filesController, pushController: pushController, diff --git a/src/Routers/AnalyticsRouter.js b/src/Routers/AnalyticsRouter.js index 76be8d8718..6d4bfa1718 100644 --- a/src/Routers/AnalyticsRouter.js +++ b/src/Routers/AnalyticsRouter.js @@ -1,17 +1,15 @@ // AnalyticsRouter.js import PromiseRouter from '../PromiseRouter'; -// Returns a promise that resolves to an empty object response -function ignoreAndSucceed(req) { - return Promise.resolve({ - response: {} - }); +function handlePost(req) { + const analyticsController = req.config.analyticsController; + return analyticsController.sendToAdapter(req); } export class AnalyticsRouter extends PromiseRouter { mountRoutes() { - this.route('POST','/events/AppOpened', ignoreAndSucceed); - this.route('POST','/events/:eventName', ignoreAndSucceed); + this.route('POST','/events/AppOpened', handlePost); + this.route('POST','/events/:eventName', handlePost); } } From 9cb040fe37184c14bd0ad5a904490481958a013d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Miko=C5=82ajczyk?= Date: Wed, 20 Jul 2016 13:45:41 +0200 Subject: [PATCH 2/2] Use promises in controller --- src/Adapters/Analytics/AnalyticsAdapter.js | 10 ++++++---- src/Controllers/AnalyticsController.js | 19 ++++++++++++++++--- src/Routers/AnalyticsRouter.js | 13 +++++++++---- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/Adapters/Analytics/AnalyticsAdapter.js b/src/Adapters/Analytics/AnalyticsAdapter.js index 523ee6799a..48dd272b3c 100644 --- a/src/Adapters/Analytics/AnalyticsAdapter.js +++ b/src/Adapters/Analytics/AnalyticsAdapter.js @@ -1,8 +1,10 @@ export class AnalyticsAdapter { - post(req) { - return Promise.resolve({ - response: {} - }); + appOpened(parameters, req) { + return Promise.resolve({}); + } + + trackEvent(eventName, parameters, req) { + return Promise.resolve({}); } } diff --git a/src/Controllers/AnalyticsController.js b/src/Controllers/AnalyticsController.js index bda1f139d2..8bcda298a6 100644 --- a/src/Controllers/AnalyticsController.js +++ b/src/Controllers/AnalyticsController.js @@ -2,9 +2,22 @@ import AdaptableController from './AdaptableController'; import { AnalyticsAdapter } from '../Adapters/Analytics/AnalyticsAdapter'; export class AnalyticsController extends AdaptableController { - post(req) { - var analyticsAdapter = this.adapter; - return analyticsAdapter.post(req); + appOpened(req) { + return this.adapter.appOpened(req.body, req).then( + function(response) { + return { response: response }; + }).catch((err) => { + return { response: {} }; + }); + } + + trackEvent(req) { + return this.adapter.trackEvent(req.params.eventName, req.body, req).then( + function(response) { + return { response: response }; + }).catch((err) => { + return { response: {} }; + }); } expectedAdapterType() { diff --git a/src/Routers/AnalyticsRouter.js b/src/Routers/AnalyticsRouter.js index 6d4bfa1718..511781d807 100644 --- a/src/Routers/AnalyticsRouter.js +++ b/src/Routers/AnalyticsRouter.js @@ -1,15 +1,20 @@ // AnalyticsRouter.js import PromiseRouter from '../PromiseRouter'; -function handlePost(req) { +function appOpened(req) { const analyticsController = req.config.analyticsController; - return analyticsController.sendToAdapter(req); + return analyticsController.appOpened(req); +} + +function trackEvent(req) { + const analyticsController = req.config.analyticsController; + return analyticsController.trackEvent(req); } export class AnalyticsRouter extends PromiseRouter { mountRoutes() { - this.route('POST','/events/AppOpened', handlePost); - this.route('POST','/events/:eventName', handlePost); + this.route('POST','/events/AppOpened', appOpened); + this.route('POST','/events/:eventName', trackEvent); } }