Added snapshot and restore API to the KB

One caveat - the create repository endpoint assumes you've written the type before the settings in your JSON. It also encorages you to write it so.

Closes #123
This commit is contained in:
Boaz Leskes 2014-03-06 21:21:10 +01:00
parent f5ed021533
commit 0db9ca50ff
7 changed files with 204 additions and 15 deletions

View file

@ -202,7 +202,8 @@ define([
endpoint: null,
urlPath: null,
method: null,
activeScheme: null
activeScheme: null,
editor: editor
};
// context.updatedForToken = session.getTokenAt(pos.row, pos.column);
@ -871,7 +872,7 @@ define([
function getCompletions(aceEditor, session, pos, prefix, callback) {
var context = getAutoCompleteContext(aceEditor, session, pos);
var context = getAutoCompleteContext(editor, session, pos);
if (!context) {
callback(null, []);
}

View file

@ -21,9 +21,8 @@ define([
});
}
function getRulesForPath(rules, tokenPath, scopeRules) {
// scopeRules are the rules used to resolve relative scope links
var walker = new json_rule_walker.RuleWalker(rules, scopeRules);
function getRulesForPath(rules, tokenPath, context) {
var walker = new json_rule_walker.RuleWalker(rules, context);
walker.walkTokenPath(tokenPath);
return walker.getNormalizedRules();
@ -47,7 +46,7 @@ define([
function addAutocompleteForPath(autocompleteSet, rules, tokenPath, context) {
// extracts the relevant parts of rules for tokenPath
var initialRules = rules;
rules = getRulesForPath(rules, tokenPath);
rules = getRulesForPath(rules, tokenPath, context);
// apply rule set
var term;
@ -85,7 +84,7 @@ define([
while (typeof rules_for_term.__template == "undefined" &&
typeof rules_for_term.__scope_link != "undefined"
) {
rules_for_term = json_rule_walker.getLinkedRules(rules_for_term.__scope_link, initialRules);
rules_for_term = json_rule_walker.getLinkedRules(rules_for_term.__scope_link, initialRules, context);
}
if (typeof rules_for_term.__template != "undefined") {

View file

@ -3,14 +3,20 @@ define(['_', 'kb', 'exports'], function (_, kb, exports) {
var WALKER_MODE_EXPECTS_KEY = 1, WALKER_MODE_EXPECTS_CONTAINER = 2, WALKER_MODE_DONE = 3;
function RuleWalker(initialRules, scopeRules) {
function RuleWalker(initialRules, context, scopeRules) {
// scopeRules are the rules used to resolve relative scope links
if (typeof scopeRules == "undefined") {
scopeRules = initialRules;
}
if ((initialRules || {}).__scope_link) {
// normalize now
initialRules = getLinkedRules(initialRules.__scope_link, scopeRules, context);
}
this._rules = initialRules;
this._mode = WALKER_MODE_EXPECTS_CONTAINER;
this._context = context;
this.scopeRules = scopeRules;
}
@ -30,7 +36,11 @@ define(['_', 'kb', 'exports'], function (_, kb, exports) {
return "value";
}
function getLinkedRules(link, currentRules) {
function getLinkedRules(link, currentRules, context) {
if (_.isFunction(link)) {
return link(context, currentRules)
}
var link_path = link.split(".");
var scheme_id = link_path.shift();
var linked_rules = currentRules;
@ -76,7 +86,7 @@ define(['_', 'kb', 'exports'], function (_, kb, exports) {
new_rules = this._rules[token] || this._rules["*"]
|| this._rules["$FIELD$"] || this._rules["$TYPE$"]; // we accept anything for a field.
if (new_rules && new_rules.__scope_link) {
new_rules = getLinkedRules(new_rules.__scope_link, this.scopeRules);
new_rules = getLinkedRules(new_rules.__scope_link, this.scopeRules, this._context);
}
switch (getRulesType(new_rules)) {

View file

@ -191,7 +191,7 @@ define([
es.addServerChangeListener(function () {
var version = es.getVersion(), api;
if (!version || version.length == 0) {
api = "kb/api_0_90";
api = "kb/api_1_0";
}
else if (version[0] === "1") {
api = "kb/api_1_0";

View file

@ -14,6 +14,7 @@ define([
'./api_1_0/mappings',
'./api_1_0/misc',
'./api_1_0/query',
'./api_1_0/snapshot_restore',
'./api_1_0/search',
'./api_1_0/settings',
'./api_1_0/templates',

View file

@ -0,0 +1,131 @@
define(function () {
'use strict';
return function init(api) {
api.addEndpointDescription('restore_snapshot', {
methods: ['POST'],
patterns: [
'_snapshot/{id}/{id}/_restore'
],
url_params: {
wait_for_completion: "__flag__"
},
data_autocomplete_rules: {
indices: "*",
ignore_unavailable: { __one_of: [ true, false] },
include_global_state: false,
rename_pattern: "index_(.+)",
rename_replacement: "restored_index_$1"
}
});
api.addEndpointDescription('single_snapshot', {
methods: ['GET', 'DELETE'],
patterns: [
'_snapshot/{id}/{id}'
]
});
api.addEndpointDescription('all_snapshots', {
methods: ['GET'],
patterns: [
'_snapshot/{id}/_all'
]
});
api.addEndpointDescription('put_snapshot', {
methods: ['PUT'],
patterns: [
'_snapshot/{id}/{id}'
],
url_params: {
wait_for_completion: "__flag__"
},
data_autocomplete_rules: {
indices: "*",
ignore_unavailable: { __one_of: [ true, false] },
include_global_state: { __one_of: [ true, false] },
partial: { __one_of: [ true, false] }
}
});
function getRepositoryType(context) {
var iter = context.editor.iterForCurrentLoc();
// for now just iterate back to the first "type" key
var t = iter.getCurrentToken();
var type;
while (t && t.type.indexOf("url") < 0) {
if (t.type === 'variable' && t.value === '"type"') {
t = context.editor.parser.nextNonEmptyToken(iter);
if (!t || t.type !== "punctuation.colon") {
// weird place to be in, but safe choice..
break;
}
t = context.editor.parser.nextNonEmptyToken(iter);
if (t && t.type === "string") {
type = t.value.replace(/"/g, '');
}
break;
}
t = context.editor.parser.prevNonEmptyToken(iter);
}
return type;
}
api.addEndpointDescription('put_repository', {
methods: ['PUT'],
patterns: [
'_snapshot/{id}'
],
data_autocomplete_rules: {
__scope_link: function (context) {
var type = getRepositoryType(context);
if (!type) {
return {
"type": {
__one_of: ["fs", "url"]
}
}
}
return {
"settings": {
__scope_link: function (context) {
var rules = {
fs: {
__template: {
location: "path"
},
location: "path",
compress: { __one_of: [ true, false]},
concurrent_streams: 5,
chunk_size: "1g",
max_restore_bytes_per_sec: "20mb",
max_snapshot_bytes_per_sec: "20mb"
},
url: {
__template: {
url: ""
},
url: "",
concurrent_streams: 5
}
};
var type = getRepositoryType(context);
if (!type) {
console.log("failed to resolve snapshot, defaulting to 'fs'");
type = "fs";
}
return rules[type];
}
}
}
}
}
});
}
;
})
;

View file

@ -374,7 +374,7 @@ define([
cursor: { row: 5, column: 21},
initialValue: "",
autoCompleteSet: [ 4, 5]
},
}
]
);
@ -572,7 +572,8 @@ define([
"e": {},
"f": [
{}
]
],
"g": {}
}
},
MAPPING,
@ -604,7 +605,15 @@ define([
{
__scope_link: "ext.target"
}
]
],
"g": {
__scope_link: function () {
return {
"a": 1,
"b": 2
}
}
}
}
}
},
@ -626,7 +635,7 @@ define([
autoCompleteSet: [
tt("b", {}), tt("c", {}), tt("d", {}), tt("e", {}), tt("f", [
{}
])
]), tt("g", {})
]
},
{
@ -648,6 +657,44 @@ define([
name: "A scope link within an array",
cursor: { row: 7, column: 10},
autoCompleteSet: [tt("t2", 1)]
},
{
name: "A function based scope link",
cursor: { row: 9, column: 12},
autoCompleteSet: [tt("a", 1), tt("b", 2)]
}
]
);
context_tests(
{
},
MAPPING,
{
globals: {
gtarget: {
t1: 2
}
},
endpoints: {
_current: {
patterns: [ "_current" ],
id: "POST _current",
data_autocomplete_rules: {
__scope_link: "GLOBAL.gtarget"
}
}
}
},
"POST _current",
[
{
name: "Top level scope link",
cursor: { row: 0, column: 1},
autoCompleteSet: [
tt("t1", 2)
]
}
]
);