diff --git a/js/actions/api-foxx.js b/js/actions/api-foxx.js index deac5d083b..7717cbbfd4 100644 --- a/js/actions/api-foxx.js +++ b/js/actions/api-foxx.js @@ -40,11 +40,6 @@ var foxxManager = require("org/arangodb/foxx-manager"); // --SECTION-- public functions // ----------------------------------------------------------------------------- -//////////////////////////////////////////////////////////////////////////////// -/// @addtogroup ArangoAPI -/// @{ -//////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// /// @brief sets up a FOXX dev application //////////////////////////////////////////////////////////////////////////////// @@ -253,9 +248,38 @@ actions.defineHttp({ }); //////////////////////////////////////////////////////////////////////////////// -/// @} +/// @brief tears down a FOXX application //////////////////////////////////////////////////////////////////////////////// +actions.defineHttp({ + url : "_admin/foxx/teardown", + context : "admin", + prefix : false, + + callback : function (req, res) { + 'use strict'; + + var result; + var body = actions.getJsonBody(req, res); + + if (body === undefined) { + return; + } + + var appId = body.appId; + var mount = body.mount; + var collectionPrefix = body.collectionPrefix; + + try { + result = foxxManager.teardown(appId, mount, collectionPrefix); + actions.resultOk(req, res, actions.HTTP_OK, result); + } + catch (err) { + actions.resultException(req, res, err); + } + } +}); + // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE // ----------------------------------------------------------------------------- diff --git a/js/apps/aardvark/repositories/swagger.js b/js/apps/aardvark/repositories/swagger.js index ac425e1be1..435dc8b29d 100644 --- a/js/apps/aardvark/repositories/swagger.js +++ b/js/apps/aardvark/repositories/swagger.js @@ -87,18 +87,20 @@ api, ops, foxxApp = _aal.firstExample({"mount": appname}), - app; + app, + list; if (!foxxApp.development) { - app = _routing.firstExample({"foxxMount": foxxApp._key}); + list = foxx_manager.appRoutes(); } else { - _.each(foxx_manager.developmentRoutes(), function(r) { - var ac = r.appContext; - if (ac.appId === foxxApp.app && ac.mount === foxxApp.mount) { - app = r; - return; - } - }); + list = foxx_manager.developmentRoutes(); } + _.each(list, function(r) { + var ac = r.appContext; + if (ac.appId === foxxApp.app && ac.mount === foxxApp.mount) { + app = r; + return; + } + }); result.swaggerVersion = "1.1"; result.basePath = app.urlPrefix; result.apis = apis; diff --git a/js/client/modules/org/arangodb/foxx-manager.js b/js/client/modules/org/arangodb/foxx-manager.js index ea057745df..75dd20be6c 100644 --- a/js/client/modules/org/arangodb/foxx-manager.js +++ b/js/client/modules/org/arangodb/foxx-manager.js @@ -740,27 +740,8 @@ exports.unmount = function (key) { var res = arango.POST("/_admin/foxx/unmount", JSON.stringify(req)); arangosh.checkRequestResult(res); -}; -//////////////////////////////////////////////////////////////////////////////// -/// @brief uninstalls a FOXX application -//////////////////////////////////////////////////////////////////////////////// - -exports.uninstall = function (key) { - 'use strict'; - - var usage = ", usage: uninstall()"; - - if (typeof key === "undefined") { - throwBadParameter("mount point or mount key missing" + usage); - } - - validateAppName(key); - - // unmount app - exports.unmount(key); - - throw "TODO!"; + return { appdId: res.appId, mount: res.mount, collectionPrefix: res.collectionPrefix }; }; //////////////////////////////////////////////////////////////////////////////// @@ -800,7 +781,7 @@ exports.install = function (name, mount, options) { keys.push(key); } } - + keys = keys.sort(module.compareVersions); version = keys[keys.length - 1]; source = available.versions[version]; @@ -828,6 +809,10 @@ exports.install = function (name, mount, options) { // fetched latest version // ............................................................................. + if (source === null) { + throw new Error("Unknown foxx application '%s', use search", name); + } + if (source !== "fetched") { appId = exports.fetch(source.type, source.location, source.tag).app; } @@ -843,6 +828,31 @@ exports.install = function (name, mount, options) { return exports.mount(appId, mount, options); }; +//////////////////////////////////////////////////////////////////////////////// +/// @brief uninstalls a FOXX application +//////////////////////////////////////////////////////////////////////////////// + +exports.uninstall = function (key) { + 'use strict'; + + var usage = ", usage: uninstall()"; + + if (typeof key === "undefined") { + throwBadParameter("mount point or mount key missing" + usage); + } + + var req = { + key: key + }; + + validateAppName(key); + + var doc = exports.unmount(key); + + var res = arango.POST("/_admin/foxx/teardown", JSON.stringify(doc)); + arangosh.checkRequestResult(res); +}; + //////////////////////////////////////////////////////////////////////////////// /// @brief returns all installed FOXX applications //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/modules/org/arangodb/foxx-manager.js b/js/server/modules/org/arangodb/foxx-manager.js index 5c33182134..113d3429e1 100644 --- a/js/server/modules/org/arangodb/foxx-manager.js +++ b/js/server/modules/org/arangodb/foxx-manager.js @@ -197,12 +197,14 @@ function executeAppScript (app, name, mount, prefix) { } var root; + var devel = false; if (app._id.substr(0,4) === "app:") { root = module.appPath(); } else if (app._id.substr(0,4) === "dev:") { root = module.devAppPath(); + devel = true; } else { throw new Error("cannot extract root path for app '" + app._id + "', unknown type"); @@ -215,7 +217,9 @@ function executeAppScript (app, name, mount, prefix) { appId: app._id, mount: mount, collectionPrefix: prefix, - appModule: app.createAppModule() + appModule: app.createAppModule(), + isDevelopment: devel, + isProduction: ! devel }; var cp = appContext.collectionPrefix; @@ -227,17 +231,15 @@ function executeAppScript (app, name, mount, prefix) { var context = {}; - context.app = { - collectionName: function (name) { - return cname + name; - }, - - path: function (name) { - return fs.join(root, app._path, name); - } + appContext.collectionName = function (name) { + return cname + name; }; - app.loadAppScript(appContext.appModule, desc[name], appContext, context); + appContext.path = function (name) { + return fs.join(root, app._path, name); + }; + + app.loadAppScript(appContext.appModule, desc[name], appContext); } } @@ -420,6 +422,11 @@ function routingAalApp (app, mount, prefix, dev) { for (i in apps) { if (apps.hasOwnProperty(i)) { var file = apps[i]; + var devel = false; + + if (app._id.substr(0,4) === "dev:") { + devel = true; + } // set up a context for the application start function var context = { @@ -638,27 +645,27 @@ exports.unmount = function (key) { throw new Error("key '" + key + "' is neither a mount id nor a mount point"); } - var appId = doc.app; + aal.remove(doc); + + internal.executeGlobalContextFunction("require(\"org/arangodb/actions\").reloadRouting()"); + + return { appId: doc.app, mount: doc.mount, collectionPrefix: doc.collectionPrefix }; +}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief tears down a FOXX application +//////////////////////////////////////////////////////////////////////////////// + +exports.teardown = function (appId, mount, collectionPrefix) { + 'use strict'; try { - if (appId.substr(0,4) === "app:") { - var appDoc = aal.firstExample({ app: appId, type: "app" }); - - if (appDoc === null) { - throw new Error("cannot find app '" + appId + "' in _aal collection"); - } - } - var app = module.createApp(appId); - teardownApp(app, doc.mount, doc.collectionPrefix); + teardownApp(app, mount, collectionPrefix); } catch (err) { console.error("teardown not possible for application '%s': %s", appId, String(err)); } - - aal.remove(doc); - - internal.executeGlobalContextFunction("require(\"org/arangodb/actions\").reloadRouting()"); }; //////////////////////////////////////////////////////////////////////////////// @@ -760,10 +767,10 @@ exports.appRoutes = function () { routes.push(r); - console.log("installed foxx app %s", appId); + console.log("mounted foxx app '%s' on '%s'", appId); } catch (err) { - console.error("cannot install foxx app '%s': %s", appId, String(err.stack || err)); + console.error("cannot mount foxx app '%s': %s", appId, String(err.stack || err)); } } @@ -807,7 +814,7 @@ exports.developmentRoutes = function () { routes.push(r); - console.log("installed dev app %s", appId); + console.log("mounted dev app '%s' on '%s'", appId); } catch (err) { console.error("cannot read app manifest '%s': %s", m, String(err.stack || err)); diff --git a/js/server/modules/org/arangodb/foxx.js b/js/server/modules/org/arangodb/foxx.js index 682bee51b2..7db30eb905 100644 --- a/js/server/modules/org/arangodb/foxx.js +++ b/js/server/modules/org/arangodb/foxx.js @@ -125,6 +125,8 @@ Application = function (context, options) { } } + this.isDevelopment = context.isDevelopment; + this.isProduction = context.isProduction; this.helperCollection = {}; this.routingInfo.urlPrefix = urlPrefix;