1
0
Fork 0

added install command

This commit is contained in:
Frank Celler 2013-07-25 18:33:24 +02:00
parent 1b6dfad627
commit 709e09d04e
5 changed files with 156 additions and 49 deletions

View File

@ -4,76 +4,79 @@ Foxx {#UserManualFoxx}
@NAVIGATE_UserManualFoxx @NAVIGATE_UserManualFoxx
@EMBEDTOC{UserManualFoxxTOC} @EMBEDTOC{UserManualFoxxTOC}
Foxx: Build APIs and simple web applications in ArangoDB Foxx: Build APIs and simple web applications in ArangoDB{#UserManualFoxxIntro}
======================================================== ==============================================================================
Foxx is an easy way to create APIs and simple web applications from within **ArangoDB**. It is inspired by Sinatra, Foxx is an easy way to create APIs and simple web applications from within
the classy Ruby web framework. If FoxxApplication is Sinatra, **ArangoDB**. It is inspired by Sinatra, the classy Ruby web framework. If
[ArangoDB Actions](http://www.arangodb.org/manuals/current/UserManualActions.html) are the corresponding `Rack`. FoxxApplication is Sinatra,
They provide all the HTTP goodness. [ArangoDB Actions](http://www.arangodb.org/manuals/current/UserManualActions.html)
are the corresponding `Rack`. They provide all the HTTP goodness.
So let's get started, shall we? So let's get started, shall we?
An application build with Foxx is written in JavaScript and deployed to ArangoDB directly. ArangoDB serves this An application build with Foxx is written in JavaScript and deployed to ArangoDB
application, you do not need a separate application server. directly. ArangoDB serves this application, you do not need a separate
application server.
So given you want to build an application that sends a plain-text response "Worked!" for all requests to `/my/wiese`. So given you want to build an application that sends a plain-text response
How would you achieve that with Foxx? "Worked!" for all requests to `/my/wiese`. How would you achieve that with
Foxx?
First, create a directory `apps` somewhere in your filesystem. Let's assume from now on that the absolute path for First, create a directory `apps` somewhere in your filesystem. Let's assume from
this directory is `/home/user/apps`. now on that the absolute path for this directory is `/home/user/apps`.
After that, create a sub-directory `my_app` in the `apps` directory and save the following content in a file named `app.js` there: After that, create a sub-directory `my_app` in the `apps` directory and save the
following content in a file named `app.js` there:
var Foxx = require("org/arangodb/foxx"); var Foxx = require("org/arangodb/foxx");
var app = new Foxx.Application(applicationContext);
var app = new Foxx.Application();
app.get("/wiese", function(req, res) { app.get("/wiese", function(req, res) {
res.set("Content-Type", "text/plain"); res.set("Content-Type", "text/plain");
res.body = "Worked!" res.body = "Worked!"
}); });
app.start(applicationContext); Beside the app.js we need a manifest file. In order to achieve that, we create a
file called `manifest.json` in our `my_app` directory with the following
content:
Beside the app.js we need a manifest file. In order to achieve that, we create a file called `manifest.json` in our {
`my_app` directory with the following content: "name": "my_app",
"version": "0.0.1",
"apps": {
"/": "app.js"
}
}
{ You **must** specify a name and a version number for your application, otherwise
"name": "my_app", it won't be loaded into ArangoDB.
"version": "0.0.1",
"apps": {
"/": "app.js"
}
}
You **must** specify a name and a version number for your application, otherwise it won't be loaded into ArangoDB. You should now have the following files and directories with your application
(starting at `/home/user` in our example):
You should now have the following files and directories with your application (starting at `/home/user` in our example):
apps/ apps/
my_app/ my_app/
manifest.json manifest.json
app.js app.js
This is your application. Now we need to mount it to the path `/my`. This is your application.
Now your application is done. Start ArangoDB as follows: Now your application is done. Start ArangoDB as follows:
$ arangod --javascript.dev-app-path /home/user/apps /tmp/fancy_db $ arangod --javascript.dev-app-path /home/user/apps /tmp/fancy_db
Replace `/home/user/apps` with the apps path that you initially created. This is the path that you created the `my_app` This will start the ArangoDB server in a development mode using the directory
directory in. Replace `/tmp/fancy_db` with the directory your database is located in. '/home/user/apps' as workspace. Produktion application are installed using the
Foxx manager and should not be changed. In development mode the server
automatically monitors the workspace and detects any change made to the files.
To include your app in the list of apps running on your ArangoDB instance, start the ArangoDB shell and add your Replace `/home/user/apps` with the apps path that you initially created. This is
new application: the path that you created the `my_app` directory in. Replace `/tmp/fancy_db`
with the directory your database is located in.
$ arangosh Now point your browser to `http://localhost:8529/dev/my_app/wiese` and you
arangosh> aal = require('org/arangodb/aal'); should see "Worked!". After this short overview, let's get into the details.
arangosh> aal.installDevApp('my_app', '/my');
Now point your browser to `http://localhost:8529/my/wiese` and you should see "Worked!". After this short overview,
let's get into the details.
## Fishbowl - Foxx's app repository ## Fishbowl - Foxx's app repository

View File

@ -1,5 +1,6 @@
[server] [server]
endpoint = tcp://localhost:8529 endpoint = tcp://localhost:8529
password =
[javascript] [javascript]
startup-directory = @PKGDATADIR@/js startup-directory = @PKGDATADIR@/js

View File

@ -172,8 +172,17 @@ actions.defineHttp({
fs.unzipFile(realFile, path, false, true); fs.unzipFile(realFile, path, false, true);
foxxManager.scanAppDirectory(); foxxManager.scanAppDirectory();
var found = arangodb.db._collection("_aal").firstExample({
type: "app",
path: name + "-" + version
});
if (found !== null) {
found = found.app;
}
actions.resultOk(req, res, actions.HTTP_OK, { path: path }); actions.resultOk(req, res, actions.HTTP_OK, { path: path, app: found });
} }
catch (err) { catch (err) {
actions.resultException(req, res, err); actions.resultException(req, res, err);

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */ /*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */
/*global require, exports */ /*global require, exports, module */
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoDB Application Launcher /// @brief ArangoDB Application Launcher
@ -521,11 +521,13 @@ function updateFishbowl () {
function compareApps (l, r) { function compareApps (l, r) {
'use strict'; 'use strict';
var left = l.name.toLowerCase(), right = r.name.toLowerCase(); var left = l.name.toLowerCase();
var right = r.name.toLowerCase();
if (left < right) { if (left < right) {
return -1; return -1;
} }
if (right < left) { if (right < left) {
return 1; return 1;
} }
@ -538,6 +540,8 @@ function compareApps (l, r) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
function cmdUsage () { function cmdUsage () {
'use strict';
var printf = arangodb.printf; var printf = arangodb.printf;
var fm = "foxx-manager"; var fm = "foxx-manager";
@ -558,6 +562,8 @@ function cmdUsage () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
exports.run = function (args) { exports.run = function (args) {
'use strict';
if (typeof args === 'undefined' || args.length === 0) { if (typeof args === 'undefined' || args.length === 0) {
console.error("expecting a command, please try: "); console.error("expecting a command, please try: ");
cmdUsage(); cmdUsage();
@ -568,7 +574,7 @@ exports.run = function (args) {
try { try {
if (type === 'fetch') { if (type === 'fetch') {
exports.fecth(args[1], args[2], args[3]); exports.fetch(args[1], args[2], args[3]);
} }
else if (type === 'mount') { else if (type === 'mount') {
if (3 < args.length) { if (3 < args.length) {
@ -578,6 +584,14 @@ exports.run = function (args) {
exports.mount(args[1], args[2]); exports.mount(args[1], args[2]);
} }
} }
else if (type === 'install') {
if (3 < args.length) {
exports.install(args[1], args[2], JSON.parse(args[3]));
}
else {
exports.install(args[1], args[2]);
}
}
else if (type === 'unmount') { else if (type === 'unmount') {
exports.unmount(args[1]); exports.unmount(args[1]);
} }
@ -662,7 +676,7 @@ exports.fetch = function (type, location, version) {
var res = arango.POST("/_admin/foxx/fetch", JSON.stringify(req)); var res = arango.POST("/_admin/foxx/fetch", JSON.stringify(req));
arangosh.checkRequestResult(res); arangosh.checkRequestResult(res);
return { path: res.path }; return { path: res.path, app: res.app };
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -720,6 +734,86 @@ exports.unmount = exports.uninstall = function (key) {
arangosh.checkRequestResult(res); arangosh.checkRequestResult(res);
}; };
////////////////////////////////////////////////////////////////////////////////
/// @brief installs a FOXX application
////////////////////////////////////////////////////////////////////////////////
exports.install = function (name, mount, options) {
'use strict';
var usage = ", usage: install(<name>, <mount>, [<options>])";
if (typeof name === "undefined") {
throwBadParameter("name missing" + usage);
}
if (typeof mount === "undefined") {
throwBadParameter("mount missing" + usage);
}
validateMount(mount);
// .............................................................................
// latest fishbowl version
// .............................................................................
var fishbowl = getFishbowlStorage();
var available = fishbowl.firstExample({name: name});
var source = null;
var version = null;
if (available !== null) {
var keys = [];
var key;
for (key in available.versions) {
if (available.versions.hasOwnProperty(key)) {
keys.push(key);
}
}
keys = keys.sort(module.compareVersions);
version = keys[keys.length - 1];
source = available.versions[version];
}
// .............................................................................
// latest fetched version
// .............................................................................
var appId = null;
var aal = getStorage();
var cursor = aal.byExample({ type: "app", name: name });
while (cursor.hasNext()) {
var doc = cursor.next();
if (module.compareVersions(version, doc.version) <= 0) {
version = doc.version;
source = "fetched";
appId = doc.app;
}
}
// .............................................................................
// fetched latest version
// .............................................................................
if (source !== "fetched") {
appId = exports.fetch(source.type, source.location, source.tag).app;
}
// .............................................................................
// install at path
// .............................................................................
if (appId === null) {
throw new Error("cannot extract application id");
}
return exports.mount(appId, mount, options);
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief lists all installed FOXX applications /// @brief lists all installed FOXX applications
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -548,7 +548,7 @@ function require (path) {
} }
} }
// If one's a prefix of the other, the longer one is greater. // If one's a prefix of the other, the longer one is bigger one.
if (aComponents.length > bComponents.length) { if (aComponents.length > bComponents.length) {
return 1; return 1;
} }