1
0
Fork 0

Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel

This commit is contained in:
Jan Steemann 2013-03-27 18:14:47 +01:00
commit f3798dcf02
13 changed files with 233 additions and 65 deletions

View File

@ -37,15 +37,36 @@
app = new FoxxApplication();
app.requiresModels = {
foxxes: "foxxes"
foxxes: "foxxes",
swagger: "swagger"
};
// Define a GET event for the URL: /foxxes
// This is used to retrieve all foxxes.
app.get('/foxxes', function (req, res) {
// Return the complete list of all foxxes
res.json(foxxes.viewAll());
});
}).nickname("Foxxes")
.summary("List of all foxxes.")
.notes("This function simply returns the list of all running"
+ " foxxes and supplies the information for the application viewer");
app.get('/swagger', function (req, res) {
res.json(swagger.list());
}).nickname("Swaggers")
.summary("List of all foxxes.")
.notes("This function simply returns the list of all running"
+ " foxxes and supplies the paths for the swagger documentation");
app.get('/swagger/:appname', function(req, res) {
res.json(swagger.show(req.params("appname")))
}).pathParam("appname", {
description: "The mount point of the App the documentation should be requested for",
dataType: "string",
required: true,
allowMultiple: false
}).nickname("SwaggersApp")
.summary("List the API for one foxx")
.notes("This function lists the API of the foxx"
+ " runnning under the given mount point");
app.start(applicationContext);
}());

View File

@ -0,0 +1,81 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true, plusplus: true, unparam: true */
/*global exports, appCollection*/
////////////////////////////////////////////////////////////////////////////////
/// @brief A TODO-List Foxx-Application written for ArangoDB
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Michael Hackstein
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
(function () {
"use strict";
// Define the functionality to receive the documentation.
// And transform it into swagger format.
exports.list = function() {
var result = {},
apis = [],
key,
pathes,
routes = require("internal").db._collection("_routing"),
res = require("internal").db._collection("_aal").byExample({"type": "mount"});
result.swaggerVersion = "1.1";
result.basePath = "http://127.0.0.1:8529/aardvark/swagger/";
result.apis = apis;
while (res.hasNext()) {
apis.push({path: res.next().mount});
}
return result;
};
exports.show = function(appname) {
var result = {},
apis = [],
key,
pathes,
routes = require("internal").db._collection("_routing"),
key = require("internal").db._collection("_aal").firstExample({"mount": "/" + appname})._key;
var app = routes.firstExample({"foxxMount": key});
result.swaggerVersion = "1.1";
result.basePath = app.urlPrefix;
result.apis = apis;
pathes = app.routes;
for (var i in pathes) {
if (pathes[i].url.methods !== undefined) {
var url = pathes[i].url.match;
var regex = /(:)([^\/]*)/;
var api = {};
var ops = [];
url = url.replace(regex, "{$2}");
api.path = url;
ops.push(pathes[i].docs);
api.operations = ops;
apis.push(api);
}
}
return result;
};
}());

View File

@ -582,7 +582,7 @@ bool ApplicationV8::prepare () {
}
if (! _devAppPath.empty()) {
paths.push_back(string("application '" + _devAppPath + "'"));
paths.push_back(string("dev application '" + _devAppPath + "'"));
}
LOGGER_INFO("JavaScript using " << StringUtils::join(paths, ", "));

View File

@ -5,7 +5,7 @@ window.SwaggerView = Backbone.View.extend({
initialize: function() {
window.swaggerUi = new SwaggerUi({
discoveryUrl:"api-docs.json",
discoveryUrl:"../../aardvark/swagger",
apiKey: false,
dom_id:"swagger-ui-container",
supportHeaderParams: true,

View File

@ -69,6 +69,34 @@ actions.defineHttp({
}
});
////////////////////////////////////////////////////////////////////////////////
/// @brief installs a FOXX application
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url : "_admin/foxx/dev-install",
context : "admin",
prefix : false,
callback : function (req, res) {
'use strict';
var result;
var body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
var name = body.name;
var mount = body.mount;
var options = body.options || {};
result = foxx.installDevApp(name, mount, options);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
});
////////////////////////////////////////////////////////////////////////////////
/// @brief uninstalls a FOXX application
////////////////////////////////////////////////////////////////////////////////

View File

@ -53,6 +53,20 @@ exports.installApp = function (name, mount, options) {
return internal.arango.POST("/_admin/foxx/install", JSON.stringify(req));
};
////////////////////////////////////////////////////////////////////////////////
/// @brief installs a FOXX dev application
////////////////////////////////////////////////////////////////////////////////
exports.installDevApp = function (name, mount, options) {
var req = {
name: name,
mount: mount,
options: options
};
return internal.arango.POST("/_admin/foxx/dev-install", JSON.stringify(req));
};
////////////////////////////////////////////////////////////////////////////////
/// @brief uninstalls a FOXX application
////////////////////////////////////////////////////////////////////////////////

View File

@ -733,8 +733,13 @@ function stop_color_print () {
if (appId.substr(0,4) === "app:") {
var a = appManifestAal(appId);
path = a.path;
appId = a.appId;
if (a != null) {
path = a.path;
appId = a.appId;
}
else {
path = null;
}
}
else if (appId.substr(0,4) === "dev:") {
path = appManifestDev(appId);
@ -752,6 +757,7 @@ function stop_color_print () {
file = fs.join(path, "/manifest.json");
if (! internal.exists(file)) {
console.error("manifest file is missing '%s'", file);
return null;
}

View File

@ -34,7 +34,7 @@ function CreateFoxxApplicationSpec () {
assertEqual(routingInfo.routes.length, 0);
assertNotNull(templateCollection);
assertEqual(routingInfo.templateCollection, templateCollection);
assertEqual(app.templateCollection, templateCollection);
},
testCreationWithTemplateCollectionIfCollectionDoesExist: function () {
@ -48,7 +48,7 @@ function CreateFoxxApplicationSpec () {
assertEqual(routingInfo.routes.length, 0);
assertNotNull(templateCollection);
assertEqual(routingInfo.templateCollection, templateCollection);
assertEqual(app.templateCollection, templateCollection);
},
testAdditionOfBaseMiddlewareInRoutingInfo: function () {

View File

@ -131,7 +131,8 @@
////////////////////////////////////////////////////////////////////////////////
internal.resetEngine = function () {
internal.output("warning: engine resetted\n");
internal.output("warning: routing engine resetted\n");
require("org/arangodb/actions").reloadRouting();
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -28,10 +28,14 @@
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var arangodb = require("org/arangodb");
var internal = require("internal");
var fs = require("fs");
var console = require("console");
var arangodb = require("org/arangodb");
var foxxManager = require("org/arangodb/foxx-manager");
var moduleExists = function(name) { return module.exists; };
// -----------------------------------------------------------------------------
@ -1096,6 +1100,7 @@ function resultError (req, res, httpReturnCode, errorNum, errorMessage, headers,
function reloadRouting () {
var i;
var j;
var routes;
var routing;
var handleRoute;
@ -1122,8 +1127,26 @@ function reloadRouting () {
// lookup all routes
// .............................................................................
routes = [];
routing = arangodb.db._collection("_routing");
routes = routing.all();
i = routing.all();
while (i.hasNext()) {
var n = i.next();
routes.push(n.shallowCopy);
}
// allow the collection to unload
i = null;
routing = null;
// check development routes
if (internal.developmentMode) {
i = foxxManager.developmentRoutes();
routes = routes.concat(i);
}
// .............................................................................
// defines a new route
@ -1150,42 +1173,14 @@ function reloadRouting () {
defineRoute(route, storage, url, callback);
};
// .............................................................................
// deep-copy a route object
// .............................................................................
function clone (obj) {
if (obj === null || typeof(obj) !== "object") {
return obj;
}
var copy, a;
if (Array.isArray(obj)) {
copy = [ ];
obj.forEach(function (i) {
copy.push(clone(i));
});
}
else if (obj instanceof Object) {
copy = { };
for (a in obj) {
if (obj.hasOwnProperty(a)) {
copy[a] = clone(obj[a]);
}
}
}
return copy;
}
// .............................................................................
// loop over the routes or routes bundle
// .............................................................................
while (routes.hasNext()) {
for (j = 0; j < routes.length; ++j) {
// clone the route object so the barrier for the collection can be removed soon
var route = clone(routes.next());
var route = routes[j];
var r;
if (route.hasOwnProperty('routes') || route.hasOwnProperty('middleware')) {
@ -1213,10 +1208,6 @@ function reloadRouting () {
}
}
// allow the collection to unload
routes = null;
routing = null;
// .............................................................................
// compute the flat routes
// .............................................................................

View File

@ -34,7 +34,6 @@ var console = require("console");
var fs = require("fs");
var arangodb = require("org/arangodb");
var actions = require("org/arangodb/actions");
// -----------------------------------------------------------------------------
// --SECTION-- private functions
@ -250,7 +249,7 @@ function upsertAalAppEntry (manifest, path) {
/// @brief installs an app for aal
////////////////////////////////////////////////////////////////////////////////
function installAalApp (app, mount, options) {
function installAalApp (app, mount, options, development) {
'use strict';
var aal;
@ -292,7 +291,8 @@ function installAalApp (app, mount, options) {
app: app._id,
mount: mount,
active: false,
collectionPrefix: prefix
collectionPrefix: prefix,
development: development
};
return aal.save(desc);
@ -302,7 +302,7 @@ function installAalApp (app, mount, options) {
/// @brief installs an app for aal
////////////////////////////////////////////////////////////////////////////////
function routingAalApp (app, mount, options) {
function routingAalApp (app, mount, prefix) {
'use strict';
try {
@ -342,8 +342,6 @@ function routingAalApp (app, mount, options) {
});
// compute the collection prefix
prefix = options && options.collectionPrefix;
if (prefix === undefined) {
prefix = mount.substr(1).replace(/\//g, "_");
}
@ -500,7 +498,7 @@ exports.installApp = function (name, mount, options) {
// compute the routing information
// .............................................................................
routes = routingAalApp(app, mount, options);
routes = routingAalApp(app, mount, options && options.collectionPrefix);
if (routes === null) {
throw "cannot compute the routing table for fox application '"
@ -512,7 +510,7 @@ exports.installApp = function (name, mount, options) {
// .............................................................................
try {
doc = installAalApp(app, mount, options);
doc = installAalApp(app, mount, options, false);
// and save the routings
routes.foxxMount = doc._key;
@ -562,18 +560,21 @@ exports.uninstallApp = function (key) {
}
try {
appDoc = aal.firstExample({ app: doc.app, type: "app" });
var appId = doc.app;
if (appDoc === null) {
throw "cannot find app '" + doc.app + "'";
if (appId.substr(0,4) === "app:") {
appDoc = aal.firstExample({ app: appId, type: "app" });
if (appDoc === null) {
throw "cannot find app '" + appId + "' in _aal collection";
}
}
app = module.createApp(appDoc.app);
app = module.createApp(appId);
teardownApp(app, doc.mount, doc.collectionPrefix);
}
catch (err) {
console.error("teardown not possible for application '%s': %s", doc.app, String(err));
console.error("teardown not possible for application '%s': %s", appId, String(err));
}
routing = arangodb.db._collection("_routing");
@ -631,7 +632,7 @@ exports.installDevApp = function (name, mount, options) {
// .............................................................................
try {
doc = installAalApp(app, mount, options);
doc = installAalApp(app, mount, options, true);
}
catch (err) {
if (doc !== undefined) {
@ -648,6 +649,30 @@ exports.installDevApp = function (name, mount, options) {
return aal.document(doc);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the development routes
////////////////////////////////////////////////////////////////////////////////
exports.developmentRoutes = function () {
var routes = [];
var aal = arangodb.db._collection("_aal");
var cursor = aal.byExample({ type: "mount", active: true, development: true });
while (cursor.hasNext()) {
var doc = cursor.next();
var appId = doc.app;
var mount = doc.mount;
var prefix = doc.collectionPrefix;
var app = module.createApp(appId);
var r = routingAalApp(app, mount, prefix);
routes.push(r);
}
return routes;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -107,7 +107,7 @@ FoxxApplication = function (options) {
this.routingInfo.urlPrefix = urlPrefix;
if (_.isString(templateCollection)) {
this.routingInfo.templateCollection = db._collection(templateCollection) ||
this.templateCollection = db._collection(templateCollection) ||
db._create(templateCollection);
myMiddleware = new BaseMiddleware(templateCollection, this.helperCollection);
} else {

View File

@ -862,8 +862,9 @@ static bool FillShapeValueJson (TRI_shaper_t* shaper,
LOG_TRACE("shaper failed because a date cannot be converted");
}
// treat undefined as null value
else if (json->IsUndefined()) {
LOG_TRACE("shaper failed because an undefined cannot be converted");
result = FillShapeValueNull(shaper, dst);
}
else {