Commit b8039434 authored by Sven Franck's avatar Sven Franck

work-in-progress replicate master-slave storage

parent 074b9ddc
......@@ -1073,6 +1073,87 @@
storage.write(obj);
},
/**
* Create an installation = new service object
* @method install
* @param {object} obj Action Object
**/
"install": function (obj) {
// force new portal type and POST (create new record)
obj.gadget.state.force_type = "Service";
obj.gadget.state.create_new = true;
storage.add(obj);
},
/**
* Destroy an installation = service object
* @method destroy
* @param {object} obj Action Object
**/
"destroy": function (obj) {
storage.remove(obj);
},
/**
* Start a software instance
* @method start_instance
* @param {object} obj Action Object
**/
"update_ticket": function (obj) {
var element = obj.element, formData, valid, replace, property, value, id,
decode, store;
id = obj.state.fragment_list[1];
formData = new FormData();
store = app.storage_dict;
valid = storage.validate(obj.gadget);
decode = /^[^\/]*%2[^\/]*$/.test(id);
if (valid === undefined) {
util.loader("", "validation_dict.general", "ban-circle");
// form is valid and not "spam"
} else {
replace = obj.gadget.id + "_";
for (property in valid) {
if (valid.hasOwnProperty(property)) {
value = valid[property];
// prepare to store
// TODO: add id to captcha fields missing it...
if (property !== "undefined") {
if (property !== "identifier") {
formData.append(property.replace(replace, ""), value);
}
}
}
}
util.loader("", "status_dict.updating");
store.items.get({"_id": window.decodeURIComponent(obj.state.fragment_list[1])},{"_view": "web_view"})
.then(function(response) {
return jIO.util.ajax({
"url": util.parse(response).data._actions.update.href,
"type": "POST",
"data": formData,
"xhrFields": {
"withCredentials": true
}
});
})
.then(function (answer) {
util.loader("", "status_dict.success", "check");
$.mobile.changePage("#services");
})
.fail(function(error) {
util.error(error);
if (util.parse(error.target).responseText === "" && id && obj.state.callback) {
$.mobile.changePage(obj.state.callback.replace("__id__", decode ? id : window.encodeURIComponent(id)));
}
});
}
},
/**
* Start a software instance
* @method start_instance
......@@ -1326,87 +1407,6 @@
});
},
/**
* Create an installation = new service object
* @method install
* @param {object} obj Action Object
**/
"install": function (obj) {
// force new portal type and POST (create new record)
obj.gadget.state.force_type = "Service";
obj.gadget.state.create_new = true;
storage.add(obj);
},
/**
* Destroy an installation = service object
* @method destroy
* @param {object} obj Action Object
**/
"destroy": function (obj) {
storage.remove(obj);
},
/**
* Start a software instance
* @method start_instance
* @param {object} obj Action Object
**/
"update_ticket": function (obj) {
var element = obj.element, formData, valid, replace, property, value, id,
decode, store;
id = obj.state.fragment_list[1];
formData = new FormData();
store = app.storage_dict;
valid = storage.validate(obj.gadget);
decode = /^[^\/]*%2[^\/]*$/.test(id);
if (valid === undefined) {
util.loader("", "validation_dict.general", "ban-circle");
// form is valid and not "spam"
} else {
replace = obj.gadget.id + "_";
for (property in valid) {
if (valid.hasOwnProperty(property)) {
value = valid[property];
// prepare to store
// TODO: add id to captcha fields missing it...
if (property !== "undefined") {
if (property !== "identifier") {
formData.append(property.replace(replace, ""), value);
}
}
}
}
util.loader("", "status_dict.updating");
store.items.get({"_id": window.decodeURIComponent(obj.state.fragment_list[1])},{"_view": "web_view"})
.then(function(response) {
return jIO.util.ajax({
"url": util.parse(response).data._actions.update.href,
"type": "POST",
"data": formData,
"xhrFields": {
"withCredentials": true
}
});
})
.then(function (answer) {
util.loader("", "status_dict.success", "check");
$.mobile.changePage("#services");
})
.fail(function(error) {
util.error(error);
if (util.parse(error.target).responseText === "" && id && obj.state.callback) {
$.mobile.changePage(obj.state.callback.replace("__id__", decode ? id : window.encodeURIComponent(id)));
}
});
}
},
// ==============================================================
/**
......@@ -5540,7 +5540,7 @@
data._id = form.identifier.value;
} else {
config = {
"call": obj.state.url_pointer[obj.element.getAttribute("data-action")]
"action": obj.state.url_pointer[obj.element.getAttribute("data-action")]
};
}
......@@ -5548,14 +5548,18 @@
app.storage_dict.items[method || "post"](data, config)
)
.then(function (response) {
util.loader("", "status_dict.saved", "check");
if (obj.state.callback) {
answer = util.parse(response);
id = answer.id;
decode = /^[^\/]*%2[^\/]*$/.test(id);
goto = decode ? id : window.encodeURIComponent(id);
if (response.status === 201) {
util.loader("", "status_dict.saved", "check");
if (obj.state.callback) {
answer = util.parse(response);
id = answer.id;
decode = /^[^\/]*%2[^\/]*$/.test(id);
goto = decode ? id : window.encodeURIComponent(id);
$.mobile.changePage(obj.state.callback.replace("__id__", goto));
$.mobile.changePage(obj.state.callback.replace("__id__", goto));
}
} else {
util.loader("", "status_dict.error", "ban-circle");
}
}).fail(util.error);
};
......
......@@ -23,38 +23,48 @@
this._url = spec.url;
}
ERP5Storage.prototype._getSiteDocument = function () {
ERP5Storage.prototype._getPrivates = function (site_hal, param, options) {
var fetch, item = (param || {})._id || (site_hal._links.me || {}).href;
if (!item) {
return command.error(401);
}
fetch = new URI(item);
return this._getSiteDocument(
site_hal._links.traverse.href,
{"relative_url": fetch.segment(2) || item, "view": options._view}
);
};
ERP5Storage.prototype._getSiteDocument = function (traverse, expando) {
var url = UriTemplate.parse(traverse || "").expand(expando || {});
console.log(url);
return jIO.util.ajax({
"type": "GET",
"url": this._url,
"url": url || this._url,
"xhrFields": {
withCredentials: true
"withCredentials": true
}
}).then(function (response) {
return JSON.parse(response.target.responseText);
var result = JSON.parse(response.target.responseText);
// result._id = param._id;
return result;
});
};
ERP5Storage.prototype._get = function (param, options) {
return this._getSiteDocument()
.then(function (site_hal) {
return jIO.util.ajax({
"type": "GET",
"url": UriTemplate.parse(site_hal._links.traverse.href)
.expand({
relative_url: param._id,
view: options._view
}),
"xhrFields": {
withCredentials: true
}
});
})
.then(function (response) {
var result = JSON.parse(response.target.responseText);
result._id = param._id;
return result;
});
var that = this;
return that._getSiteDocument()
.then(function (site_hal) {
return that._getPrivates(site_hal, param, options);
})
.then(function (response) {
console.log("GET, response")
console.log(response)
var result = JSON.parse(response.target.responseText);
result._id = param._id;
return result;
});
};
ERP5Storage.prototype.get = function (command, param, options) {
......@@ -74,11 +84,15 @@
};
ERP5Storage.prototype.post = function (command, metadata, options) {
return this._getSiteDocument()
var that = this;
return that._getSiteDocument()
.then(function (site_hal) {
var post_action = site_hal._actions.add,
data = new FormData(),
key;
return that._getPrivates(site_hal, undefined, options);
})
.then(function(opts) {
var key, custom_action = opts._actions[options.action],
post_action = custom_action || site_hal._actions.add,
data = new FormData();
for (key in metadata) {
if (metadata.hasOwnProperty(key)) {
......@@ -86,17 +100,18 @@
data.append(key, metadata[key]);
}
}
return jIO.util.ajax({
"type": post_action.method,
"url": post_action.href,
"data": data,
"xhrFields": {
withCredentials: true
"withCredentials": true
}
});
}).then(function (doc) {
// XXX Really depend on server response...
var uri = new URI(doc.target.getResponseHeader("Location"));
var uri = new URI(doc.target.getResponseHeader("X-Location"));
command.success({"id": uri.segment(2)});
}).fail(function (error) {
console.error(error);
......
......@@ -82,7 +82,7 @@
"xhrFields": {
"withCredentials": true
}
})
})z
})
.then(function (opts) {
var doc_hal, custom_action, post_action, data, key;
......
......@@ -177,13 +177,16 @@
* last(promise_list): Promise
*
* @param {Array} promise_list An array of promises
* @param {Integer} master The "promise" with id authority
* @return {Promise} A new promise
*/
function last(promise_list) {
function last(promise_list, master) {
var length = promise_list.length;
promise_list = promise_list.slice();
return new Promise(function (resolve, reject, notify) {
var index, last_answer, count = 0, error_count = 0;
function resolver() {
return function (answer) {
count += 1;
......@@ -213,8 +216,14 @@
});
};
}
for (index = 0; index < length; index += 1) {
promise_list[index].then(resolver(), rejecter(), notifier(index));
if (typeof master === "number") {
length = 1;
promise_list[master].then(resolver(), rejecter(), notifier(master));
} else {
for (index = 0; index < length; index += 1) {
promise_list[index].then(resolver(), rejecter(), notifier(index));
}
}
}, function () {
var index;
......@@ -309,18 +318,60 @@
"storage_list is not of type array");
}
this._storage_list = spec.storage_list;
this._master = spec.master;
}
ReplicateStorage.prototype.post = function (command, metadata, option) {
var promise_list = [], index, length = this._storage_list.length;
for (index = 0; index < length; index += 1) {
promise_list[index] = success(
command.storage(this._storage_list[index]).post(metadata, option)
var index, subindex,
storages = this._storage_list,
promise_list = [],
priority_list = [],
length = storages.length,
master = this._master;
// first run priority storage
if (master !== undefined) {
priority_list[0] = success(
command.storage(storages[master]).post(metadata, option)
);
} else {
for (index = 0; index < length; index += 1) {
promise_list[index] = success(
command.storage(storages[index]).post(metadata, option)
);
}
}
sequence([function () {
return last(promise_list);
}, [command.success, command.error]]);
sequence([
function () {
if (master !== undefined) {
return last(priority_list, master);
}
return {};
},
function (response) {
var method, subindex = 0;
// this is the id issued by the master storage
if (response.id) {
metadata._id = response.id;
method = "put";
} else {
// TODO: error/offline handling
}
for (index = 0; index < length; index += 1) {
if (index !== master) {
promise_list[subindex] = success(
command.storage(storages[index])
[method || "post"](metadata, option)
);
subindex += 1;
}
}
return last(promise_list);
},
[command.success, command.error]
]);
};
ReplicateStorage.prototype.put = function (command, metadata, option) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment