UNPKG

gpii-universal

Version:

Cross platform, core components of the GPII personalization infrastructure.

237 lines (219 loc) 11.3 kB
/*! GPII Preferences Server Copyright 2012-2016 OCAD University Copyright 2014-2015 Raising The Floor - International Copyright 2017-2019 OCAD University Licensed under the New BSD license. You may not use this file except in compliance with this License. The research leading to these results has received funding from the European Union's Seventh Framework Programme (FP7/2007-2013) under grant agreement no. 289016. You may obtain a copy of the License at https://github.com/GPII/universal/blob/master/LICENSE.txt */ "use strict"; var fluid = require("infusion"), gpii = fluid.registerNamespace("gpii"); require("ontologyHandler"); fluid.defaults("gpii.preferencesServer", { gradeNames: ["kettle.app"], requestHandlers: { // The endpoint to check the readiness of the preferences server: the server is ready but does not check the database connection. healthGet: { route: "/health", method: "get", type: "gpii.health.handler" }, // The endpoint to check the liveness of the preferences server: both the server and the database connection is ok readyGet: { route: "/ready", method: "get", type: "gpii.preferencesServer.ready.handler" }, preferencesGet: { route: "/preferences/:gpiiKey", method: "get", type: "gpii.preferencesServer.get.handler" }, preferencesPost: { route: "/preferences", method: "post", type: "gpii.preferencesServer.post.handler" }, preferencesPut: { route: "/preferences/:gpiiKey", method: "put", type: "gpii.preferencesServer.put.handler" } }, invokers: { getPreferences: { funcName: "gpii.preferencesServer.getPreferences", args: ["{preferencesService}", "{ontologyHandler}", "{arguments}.0", "@expand:gpii.preferencesServer.getView({arguments}.1)"] // gpiiKey, view }, createPreferences: { funcName: "gpii.preferencesServer.createPreferences", args: ["{preferencesService}", "{ontologyHandler}", "{arguments}.0", "@expand:gpii.preferencesServer.getView({arguments}.1)", "{arguments}.2"] // preferences, view, gpiiKey }, updatePreferences: { funcName: "gpii.preferencesServer.updatePreferences", args: ["{preferencesService}", "{ontologyHandler}", "{arguments}.0", "{arguments}.1", "@expand:gpii.preferencesServer.getView({arguments}.2)", "{arguments}.3"] // gpiiKey, preferences, view, merge } }, components: { preferencesService: { type: "gpii.preferencesServer.preferencesService" }, ontologyHandler: { type: "gpii.ontologyHandler" }, dataStore: { type: "gpii.dbOperation.dbDataStore" }, // persistent validation component for preferences. preferencesValidator: { type: "gpii.universal.solutionsRegistry.validators.preferences" } }, distributeOptions: { authorizationServiceDataStore: { "record": "{gpii.preferencesServer}.dataStore", "target": "{that authorizationService}.options.components.dataStore" }, preferencesServiceDataStore: { "record": "{gpii.preferencesServer}.dataStore", "target": "{that preferencesService}.options.components.dataStore" }, // Censor the last source of DB auth credentials for GPII-3309 censorDataSourceBaseUrl: { "record": { "directModel.baseUrl": true }, "target": "{that dataSource}.options.censorRequestOptionsLog" } } }); /** * Simple function to get the 'view'. In case none is given, defaults to the "flat" ontology. * @param {String} view - A view. * @return {String} The value of the 'view', or "flat" if none is given. */ gpii.preferencesServer.getView = function (view) { return view ? view : "flat"; }; /** * The API to get preferences. Note that this API returns the entire value of the prefsSafe.preferences * rather than the particular prefs set that is associated with the GPII key provided as an argument. * @param {Component} preferencesService - An instance of gpii.preferencesServer.preferencesService component. * @param {Component} ontologyHandler - An instance of gpii.ontologyHandler component. * @param {String} gpiiKey - An GPII key. * @param {String} view - An view that the preferences should be transformed upon. * @return {Promise} A promise object whose resolved value is the preferences transformed based on the view. */ gpii.preferencesServer.getPreferences = function (preferencesService, ontologyHandler, gpiiKey, view) { fluid.log("gpii.preferencesServer.getPreferences called - fetching preferences for the GPII key " + gpiiKey); var rawPrefsPromise = preferencesService.getPreferencesByGpiiKey(gpiiKey); var mapper = function (rawPrefs) { var prefs = rawPrefs ? ontologyHandler.rawPrefsToOntology(rawPrefs, view) : undefined; fluid.log("Preferences Server, getPreferences(), returning preferences: ", prefs); return prefs; }; return fluid.promise.map(rawPrefsPromise, mapper); }; /** * The API to create preferences. This API does: * 1. If the GPII key is not provided, first auto generat a GPII key and create it, then create a new prefs safe with the given preferences and associate this prefs safe with the new GPII key; * 2. If the GPII key is provided but not yet exists, create it first, then create a new prefs safe with the given preferences and associate the prefs safe with the GPII key; * 3. If the GPII key is provided and already exists, reject with an error; * 4. If preferences is not provided, reject with an error. * @param {Component} preferencesService - An instance of gpii.preferencesServer.preferencesService component. * @param {Component} ontologyHandler - An instance of gpii.ontologyHandler component. * @param {Object} preferences - A preferences object. * @param {String} view - An view that the provided preferences is based upon. * @param {String} [gpiiKey] - [optional] The GPII key to be created. * @return {Promise} A promise object whose resolved value is: * { * gpiiKey: {String}, * preferences: {Object} * } */ gpii.preferencesServer.createPreferences = function (preferencesService, ontologyHandler, preferences, view, gpiiKey) { fluid.log("gpii.preferencesServer.createPreferences called for creating preferences: ", preferences); var promiseTogo = fluid.promise(); if (!preferences) { // preferences must be provided fluid.log("Preferences Server, createPreferences(), creating preferences, rejected due to missing preferences"); promiseTogo.reject(gpii.preferencesServer.errors.missingPreferences); } else { var payload = {}; payload[view] = preferences; fluid.log("Preferences Server, createPreferences(), creating GPII key (", gpiiKey, ") and its preferences: ", payload); var mapper = function (addPrefsResponse) { return fluid.extend({}, addPrefsResponse, { preferences: fluid.get(addPrefsResponse, ["preferences", view]) }); }; promiseTogo = fluid.promise.map(preferencesService.createPreferences(payload, gpiiKey), mapper); } return promiseTogo; }; /** * The API to update an existing preferences safe to the Preferences Server. This API does: * 1. If the GPII key exists and associates with a prefs safe, update the prefs safe with the new preferences; * 2. If the GPII key exists but does not associates with a prefs safe, create a new prefs safe with the preferences and associate it with the GPII key; * 3. If the GPII key does not exist in the db, reject with an error; * 4. If the GPII key or the preferences value is not provided, reject with an error. * @param {Component} preferencesService - An instance of gpii.preferencesServer component. * @param {Object} ontologyHandler - An ontology handler. * @param {String} gpiiKey - A GPII key. * @param {Object} preferences - A preferences object. * @param {String} view - An view that the provided preferences is based upon. * @param {Boolean} [merge] - [optional] A flag that indicates whether to merge the incoming preferences with the existing preferences. * @return {Promise} A promise object whose resolved value is: * { * gpiiKey: {String}, * preferences: {Object} * } */ gpii.preferencesServer.updatePreferences = function (preferencesService, ontologyHandler, gpiiKey, preferences, view, merge) { fluid.log("gpii.preferencesServer.updatePreferences called - updating preferences for the GPII key " + gpiiKey); var promiseTogo = fluid.promise(); if (!gpiiKey) { // GPII key must be provided fluid.log("Preferences Server, updatePreferences(), updating preferences, rejected due to the missing GPII key"); promiseTogo.reject(gpii.preferencesServer.errors.missingGpiiKey); } else if (!preferences) { // preferences must be provided fluid.log("Preferences Server, updatePreferences(), updating preferences, rejected due to the missing preferences"); promiseTogo.reject(gpii.preferencesServer.errors.missingPreferences); } else { var gpiiKeyPromise = preferencesService.getPrefsSafeByGpiiKey(gpiiKey); gpiiKeyPromise.then(function (gpiiKeyRelatedData) { var preferencesPromise = fluid.promise(); var payload; if (gpiiKeyRelatedData) { // If the GPII key exists: // 1. If an existing prefs safe already associates with the GPII key, update the prefs safe; // 2. If no prefs safe is associated with the GPII key, create the prefs safe and associate with the GPII key. var rawPrefs = fluid.get(gpiiKeyRelatedData, ["prefsSafe", "preferences"]); payload = ontologyHandler.addPrefsToRawPrefs(preferences, view, rawPrefs || {}); var updatePromise = preferencesService.updatePreferences(payload, gpiiKey, merge); var mapper = function (updateResponse) { return { gpiiKey: updateResponse.gpiiKey, preferences: fluid.get(updateResponse, ["preferences", view]) }; }; preferencesPromise = fluid.promise.map(updatePromise, mapper); } else { // Reject if the GPII key does not exist fluid.log("Preferences Server, updatePreferences(), updating preferences, rejected due to the missing GPII key: " + gpiiKey); preferencesPromise.reject(gpii.preferencesServer.errors.missingGpiiKey); } fluid.promise.follow(preferencesPromise, promiseTogo); }); } return promiseTogo; };