*
* Parameters:
* dict :
- * .request : ???? used to be FIELD_REQUEST_ADD / FIELD_REQUEST_REMOVE
+ * .state : ???? used to be FIELD_REQUEST_ADD / FIELD_REQUEST_REMOVE
* .key : ??? the key fields of the record
- * .value : the key of the record who has received an update
- * .status : the new state of the record
- * TODO rename to state, and use values from STATE_SET
+ * .op : the key of the record who has received an update
+ * .value : the new state of the record
*/
var FIELD_STATE_CHANGED = 9;
/* Update requests related to subqueries */
-/**
- * event: SET_ADD
- *
- * Parameters:
- * string : The key of the element being added
- */
+/*
var SET_ADD = 201;
-
-/**
- * event: SET_REMOVED
- *
- * Parameters:
- * string : The key of the element being removed
- */
var SET_REMOVED = 202;
-
+*/
// request
+/*
var FIELD_REQUEST_CHANGE = 301;
var FIELD_REQUEST_ADD = 302;
var FIELD_REQUEST_REMOVE = 303;
var FIELD_REQUEST_ADD_RESET = 304;
var FIELD_REQUEST_REMOVE_RESET = 305;
+*/
// status (XXX Should be deprecated)
var FIELD_REQUEST_PENDING = 401;
var FIELD_REQUEST_SUCCESS = 402;
******************************************************************************/
var STATE_SET = 0;
-var STATE_WARNINGS = 1;
-var STATE_VISIBLE = 2;
+var STATE_VALUE = 1;
+var STATE_WARNINGS = 2;
+var STATE_VISIBLE = 3;
+
+// ACTIONS
+var STATE_SET_CHANGE = 0;
+var STATE_SET_ADD = 1;
+var STATE_SET_REMOVE = 2;
+var STATE_SET_CLEAR = 3;
// STATE_SET : enum
var STATE_SET_IN = 0;
var STATE_SET_OUT_SUCCESS = 5;
var STATE_SET_IN_FAILURE = 6;
var STATE_SET_OUT_FAILURE = 7;
+var STATE_VALUE_CHANGE_PENDING = 8;
+var STATE_VALUE_CHANGE_SUCCESS = 9;
+var STATE_VALUE_CHANGE_FAILURE = 10;
// STATE_WARNINGS : dict
var CONSTRAINT_RESERVABLE_LEASE = 0;
+var CONSTRAINT_RESERVABLE_LEASE_MSG = "Configuration required: this resource needs to be scheduled";
+
// A structure for storing queries
function QueryExt(query, parent_query_ext, main_query_ext, update_query_ext, disabled, domain_query_ext) {
throw "Internal error";
data = {
- request: FIELD_REQUEST_CHANGE,
+ state : STATE_SET,
key : field,
- value : update_value,
- status: (update_value == result_value) ? FIELD_REQUEST_SUCCESS : FIELD_REQUEST_FAILURE,
+ op : update_value,
+ value : (update_value == result_value) ? STATE_VALUE_CHANGE_SUCCESS : STATE_VALUE_CHANGE_FAILURE,
}
manifold.raise_record_event(query_uuid, FIELD_STATE_CHANGED, data);
manifold.raise_event_handler('record', query_uuid, event_type, value);
},
+ /**
+ * Event handler helpers
+ */
+ _get_next_state_add: function(prev_state, event_type)
+ {
+ switch (prev_state) {
+ case STATE_SET_OUT:
+ case STATE_SET_OUT_SUCCESS:
+ case STATE_SET_IN_FAILURE:
+ new_state = STATE_SET_IN_PENDING;
+ break;
+
+ case STATE_SET_OUT_PENDING:
+ new_state = STATE_SET_IN;
+ break;
+
+ case STATE_SET_IN:
+ case STATE_SET_IN_PENDING:
+ case STATE_SET_IN_SUCCESS:
+ case STATE_SET_OUT_FAILURE:
+ console.log("Inconsistent state: already in");
+ return;
+ }
+ return new_state;
+ },
+
+ _get_next_state_remove: function(prev_state, event_type)
+ {
+ switch (prev_state) {
+ case STATE_SET_IN:
+ case STATE_SET_IN_SUCCESS:
+ case STATE_SET_OUT_FAILURE:
+ new_state = STATE_SET_OUT_PENDING;
+ break;
+
+ case STATE_SET_IN_PENDING:
+ new_state = STATE_SET_OUT;
+ break;
+
+ case STATE_SET_OUT:
+ case STATE_SET_OUT_PENDING:
+ case STATE_SET_OUT_SUCCESS:
+ case STATE_SET_IN_FAILURE:
+ console.log("Inconsistent state: already out");
+ return;
+ }
+ return new_state;
+ },
+
+ _grep_active_lease_callback: function(lease_query, resource_key) {
+ return function(lease_key_lease) {
+ var state, lease_key, lease;
+
+ lease_key = lease_key_lease[0];
+ lease = lease_key_lease[1];
+
+ if (lease['resource'] != resource_key)
+ return false;
+
+ state = manifold.query_store.get_record_state(lease_query.query_uuid, lease_key, STATE_SET);;
+ switch(state) {
+ case STATE_SET_IN:
+ case STATE_SET_IN_PENDING:
+ case STATE_SET_IN_SUCCESS:
+ case STATE_SET_OUT_FAILURE:
+ return true;
+ case STATE_SET_OUT:
+ case STATE_SET_OUT_PENDING:
+ case STATE_SET_OUT_SUCCESS:
+ case STATE_SET_IN_FAILURE:
+ return false;
+ }
+ }
+ },
+
+ _enforce_constraints: function(query_ext, record, resource_key, event_type)
+ {
+ var query, data;
+
+ query = query_ext.query;
+
+ switch(query.object) {
+
+ case 'resource':
+ // CONSTRAINT_RESERVABLE_LEASE
+ //
+ // +) If a reservable node is added to the slice, then it should have a corresponding lease
+ // XXX Not always a resource
+ var is_reservable = (record.exclusive == true);
+ if (is_reservable) {
+ var warnings = manifold.query_store.get_record_state(query.query_uuid, resource_key, STATE_WARNINGS);
+
+ if (event_type == STATE_SET_ADD) {
+ // We should have a lease_query associated
+ var lease_query = query_ext.parent_query_ext.query.subqueries['lease']; // in options
+ var lease_query_ext = manifold.query_store.find_analyzed_query_ext(lease_query.query_uuid);
+ // Do we have lease records (in) with this resource
+ var lease_records = $.grep(lease_query_ext.records.entries(), this._grep_active_lease_callback(lease_query, resource_key));
+ if (lease_records.length == 0) {
+ // Sets a warning
+ // XXX Need for a better function to manage warnings
+ var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
+ warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+ } else {
+ // Lease are defined, delete the warning in case it was set previously
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ }
+ } else {
+ // Remove warnings attached to this resource
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ }
+
+ manifold.query_store.set_record_state(query.query_uuid, resource_key, STATE_WARNINGS, warnings);
+ }
+
+ manifold.query_store.recount(query.query_uuid);
+ manifold.query_store.recount(lease_query.query_uuid);
+
+ // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+ data = {
+ state: STATE_WARNINGS,
+ key : resource_key,
+ op : null,
+ value : warnings
+ }
+ manifold.raise_record_event(query.query_uuid, FIELD_STATE_CHANGED, data);
+ break;
+
+ case 'lease':
+ var resource_key = record.resource;
+ var resource_query = query_ext.parent_query_ext.query.subqueries['resource'];
+ var warnings = manifold.query_store.get_record_state(resource_query.query_uuid, resource_key, STATE_WARNINGS);
+
+ if (event_type == STATE_SET_ADD) {
+ // A lease is added, it removes the constraint
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ } else {
+ // A lease is removed, it might trigger the warning
+ var lease_records = $.grep(query_ext.records.entries(), this._grep_active_lease_callback(query, resource_key));
+ if (lease_records.length == 0) { // XXX redundant cases
+ // Sets a warning
+ // XXX Need for a better function to manage warnings
+ var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
+ warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+ } else {
+ // Lease are defined, delete the warning in case it was set previously
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ }
+
+ }
+
+ manifold.query_store.recount(query.query_uuid);
+ manifold.query_store.recount(resource_query.query_uuid);
+
+ // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+ data = {
+ state: STATE_WARNINGS,
+ key : resource_key,
+ op : null,
+ value : warnings
+ }
+ manifold.raise_record_event(resource_query.query_uuid, FIELD_STATE_CHANGED, data);
+ break;
+ }
+
+ // -) When a lease is added, it might remove the warning associated to a reservable node
+
+ // If a NITOS node is reserved, then at least a NITOS channel should be reserved
+ // - When a NITOS channel is added, it might remove a warning associated to all NITOS nodes
+
+ // If a NITOS channel is reserved, then at least a NITOS node should be reserved
+ // - When a NITOS node is added, it might remove a warning associated to all NITOS channels
+
+ // A lease is present while the resource has been removed => Require warnings on nodes not in set !
+
+ },
+
+ _get_query_path: function(query_ext) {
+ var path = "";
+ var sq = query_ext;
+ while (sq.parent_query_ext) {
+ if (path != "")
+ path = '.' + path;
+ path = sq.query.object + path;
+ sq = sq.parent_query_ext;
+ }
+ return path;
+ },
+
- raise_event: function(query_uuid, event_type, value) {
+ /**
+ * Handling events raised by plugins
+ */
+ raise_event: function(query_uuid, event_type, data)
+ {
var query, query_ext;
// Query uuid has been updated with the key of a new element
switch(event_type) {
+ // XXX At some point, should be renamed to RECORD_STATE_CHANGED
case FIELD_STATE_CHANGED:
+
// value is an object (request, key, value, status)
// update is only possible is the query is not pending, etc
// SET_ADD is on a subquery, FIELD_STATE_CHANGED on the query itself
update_query = query_ext.main_query_ext.update_query_ext.query;
update_query_orig = query_ext.main_query_ext.update_query_orig_ext.query;
- switch(value.request) {
- case FIELD_REQUEST_CHANGE:
- if (update_query.params[value.key] === undefined)
- update_query.params[value.key] = Array();
- update_query.params[value.key] = value.value;
- break;
- case FIELD_REQUEST_ADD:
- if ($.inArray(value.value, update_query_orig.params[value.key]) != -1)
- value.request = FIELD_REQUEST_ADD_RESET;
- if (update_query.params[value.key] === undefined)
- update_query.params[value.key] = Array();
- update_query.params[value.key].push(value.value);
- break;
- case FIELD_REQUEST_REMOVE:
- if ($.inArray(value.value, update_query_orig.params[value.key]) == -1)
- value.request = FIELD_REQUEST_REMOVE_RESET;
-
- var arr = update_query.params[value.key];
- arr = $.grep(arr, function(x) { return x != value.value; });
- if (update_query.params[value.key] === undefined)
- update_query.params[value.key] = Array();
- update_query.params[value.key] = arr;
+ switch(data.state) {
+
+ case STATE_VALUE:
+ switch(data.op) {
+ case STATE_CHANGE:
+ /* Set parameter data.key in the update_query to VALUE */
+ if (update_query.params[data.key] === undefined)
+ update_query.params[data.key] = Array();
+ update_query.params[data.key] = value.value;
+ break;
+ }
break;
- case FIELD_REQUEST_ADD_RESET:
- case FIELD_REQUEST_REMOVE_RESET:
- // XXX We would need to keep track of the original query
- throw "Not implemented";
- break;
- }
-
- // 3. Inform others about the change
- // a) the main query...
- manifold.raise_record_event(query_uuid, event_type, value);
-
- // b) subqueries eventually (dot in the key)
- // Let's unfold
- var path_array = value.key.split('.');
- var value_key = value.key.split('.');
-
- var cur_query = query;
- if (cur_query.analyzed_query)
- cur_query = cur_query.analyzed_query;
- $.each(path_array, function(i, method) {
- cur_query = cur_query.subqueries[method];
- value_key.shift(); // XXX check that method is indeed shifted
- });
- value.key = value_key;
-
- manifold.query_store.recount(cur_query.query_uuid);
- manifold.raise_record_event(cur_query.query_uuid, event_type, value);
+ case STATE_SET:
- // XXX make this DOT a global variable... could be '/'
- break;
-
- case SET_ADD:
- case SET_REMOVED:
-
- /* An object has been added to / removed from a set : its
- * status become pending or reset to the original state. We
- * update the record status in the analyzed queries.
- *
- * XXX Shall we update something in the main_query ?
- */
- var prev_state, new_state;
-
- prev_state = manifold.query_store.get_record_state(query_uuid, value, STATE_SET);
- if (prev_state === null)
- prev_state = STATE_SET_OUT;
-
- if (event_type == SET_ADD) {
- switch (prev_state) {
- case STATE_SET_OUT:
- case STATE_SET_OUT_SUCCESS:
- case STATE_SET_IN_FAILURE:
- new_state = STATE_SET_IN_PENDING;
- break;
-
- case STATE_SET_OUT_PENDING:
- new_state = STATE_SET_IN;
- break;
-
- case STATE_SET_IN:
- case STATE_SET_IN_PENDING:
- case STATE_SET_IN_SUCCESS:
- case STATE_SET_OUT_FAILURE:
- console.log("Inconsistent state: already in");
- return;
- }
- } else { // SET_REMOVE
- switch (prev_state) {
- case STATE_SET_IN:
- case STATE_SET_IN_SUCCESS:
- case STATE_SET_OUT_FAILURE:
- new_state = STATE_SET_OUT_PENDING;
- break;
-
- case STATE_SET_IN_PENDING:
- new_state = STATE_SET_OUT;
- break;
-
- case STATE_SET_OUT:
- case STATE_SET_OUT_PENDING:
- case STATE_SET_OUT_SUCCESS:
- case STATE_SET_IN_FAILURE:
- console.log("Inconsistent state: already out");
- return;
- }
- }
+ switch(data.op) {
+ case STATE_SET_ADD:
+ if (!data.key) {
+ var prev_state, new_state;
+ var main_query, record, new_data;
+
+ prev_state = manifold.query_store.get_record_state(query_uuid, data.value, STATE_SET);
+ if (prev_state === null)
+ prev_state = STATE_SET_OUT;
+ new_state = this._get_next_state_add(prev_state, data.state);
+
+ /* data.value containts the resource key */
+ manifold.query_store.add_record(query_uuid, data.value, new_state);
+ record = manifold.query_store.get_record(query_uuid, data.value);
+ this._enforce_constraints(query_ext, record, data.value, STATE_SET_ADD);
+
+ /* Inform the parent query: important for update */
+ new_data = {
+ state : STATE_SET,
+ key : this._get_query_path(query_ext),
+ op : STATE_SET_IN_PENDING,
+ value : data.value,
+ };
+ main_query = query_ext.main_query_ext.query;
+ this.raise_event(main_query.query_uuid, FIELD_STATE_CHANGED, new_data);
+
+ /*
+ * Propagate the event to other plugins subscribed to the query
+ */
+ manifold.raise_query_event(query_uuid, event_type, data);
+ } else {
+ // mainquery: proceed to update
-
- var resource_key = value;
+ //if ($.inArray(data.value, update_query_orig.params[data.key]) != -1)
+ // value.request = FIELD_REQUEST_ADD_RESET;
- if (event_type == SET_ADD)
- manifold.query_store.add_record(query_uuid, resource_key, new_state);
- else
- manifold.query_store.remove_record(query_uuid, resource_key, new_state);
-
- var record = manifold.query_store.get_record(query_uuid, resource_key);
-
- /* CONSTRAINTS */
-
- // XXX When we add a lease we must update the warnings
-
- switch(query.object) {
-
- case 'resource':
- // CONSTRAINT_RESERVABLE_LEASE
- //
- // +) If a reservable node is added to the slice, then it should have a corresponding lease
- // XXX Not always a resource
- var is_reservable = (record.exclusive == true);
- if (is_reservable) {
- var warnings = manifold.query_store.get_record_state(query_uuid, resource_key, STATE_WARNINGS);
-
- if (event_type == SET_ADD) {
- // We should have a lease_query associated
- var lease_query = query_ext.parent_query_ext.query.subqueries['lease']; // in options
- var lease_query_ext = manifold.query_store.find_analyzed_query_ext(lease_query.query_uuid);
- // Do we have lease records with this resource
- var lease_records = $.grep(lease_query_ext.records, function(lease_key, lease) {
- return lease['resource'] == value;
- });
- if (lease_records.length == 0) {
- // Sets a warning
- // XXX Need for a better function to manage warnings
- var warn = "No lease defined for this reservable resource.";
- warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
- } else {
- // Lease are defined, delete the warning in case it was set previously
- delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ if (update_query.params[data.key] === undefined)
+ update_query.params[data.key] = Array();
+ update_query.params[data.key].push(data.value);
}
- } else {
- // Remove warnings attached to this resource
- delete warnings[CONSTRAINT_RESERVABLE_LEASE];
- }
+ break;
- manifold.query_store.set_record_state(query_uuid, resource_key, STATE_WARNINGS, warnings);
- break;
- }
-
- // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
- data = {
- request: null,
- key : null,
- value : resource_key,
- status: STATE_WARNINGS
- };
- manifold.raise_record_event(query_uuid, FIELD_STATE_CHANGED, data);
+ case STATE_SET_REMOVE:
+ if (!data.key) {
+ var prev_state, new_state;
+ var main_query, record, new_data;
+
+ prev_state = manifold.query_store.get_record_state(query_uuid, data.value, STATE_SET);
+ if (prev_state === null)
+ prev_state = STATE_SET_OUT;
+ new_state = this._get_next_state_remove(prev_state, data.state);
+
+ /* data.value contains the resource key */
+ manifold.query_store.remove_record(query_uuid, data.value, new_state);
+ record = manifold.query_store.get_record(query_uuid, data.value);
+ this._enforce_constraints(query_ext, record, data.value, STATE_SET_REMOVE);
+
+ /* Inform the parent query: important for update */
+ new_data = {
+ state : STATE_SET,
+ key : this._get_query_path(query_ext),
+ op : STATE_SET_OUT_PENDING,
+ value : data.value,
+ };
+ main_query = query_ext.main_query_ext.query;
+ this.raise_event(main_query.query_uuid, FIELD_STATE_CHANGED, new_data);
+
+ /* Propagate the event to other plugins subscribed to the query */
+ manifold.raise_query_event(query_uuid, event_type, data);
+
+ } else {
+ // main query: proceed to update
- case 'lease':
- /*
- var resource_key = record.resource;
- var resource_query = query_ext.parent_query_ext.query.subqueries['resource'];
- var warnings = manifold.query_store.get_record_state(resource_query.query_uuid, resource_key, STATE_WARNINGS);
+ //if ($.inArray(data.value, update_query_orig.params[data.key]) == -1)
+ // value.request = FIELD_REQUEST_REMOVE_RESET;
- if (event_type == SET_ADD) {
- // A lease is added, it removes the constraint
- delete warnings[CONSTRAINT_RESERVABLE_LEASE];
- } else {
- // A lease is removed, it might trigger the warning
- var lease_records = $.grep(query_ext.records, function(lease_key, lease) {
- return lease['resource'] == value;
- });
- if (lease_records.length == 0) { // XXX redundant cases
- // Sets a warning
- // XXX Need for a better function to manage warnings
- var warn = "No lease defined for this reservable resource.";
- warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
- } else {
- // Lease are defined, delete the warning in case it was set previously
- delete warnings[CONSTRAINT_RESERVABLE_LEASE];
- }
-
+ var arr = update_query.params[data.key];
+ arr = $.grep(arr, function(x) { return x != data.value; });
+ if (update_query.params[data.key] === undefined)
+ update_query.params[data.key] = Array();
+ update_query.params[data.key] = arr;
+ }
+ break;
}
-
- // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
- data = {
- request: null,
- key : null,
- value : resource_key,
- status: STATE_WARNINGS
- };
- manifold.raise_record_event(resource_query.query_uuid, FIELD_STATE_CHANGED, data);
break;
- */
}
+ // 3. Inform others about the change
+ // a) the main query...
+ manifold.raise_record_event(query_uuid, event_type, data);
- // -) When a lease is added, it might remove the warning associated to a reservable node
-
- // If a NITOS node is reserved, then at least a NITOS channel should be reserved
- // - When a NITOS channel is added, it might remove a warning associated to all NITOS nodes
-
- // If a NITOS channel is reserved, then at least a NITOS node should be reserved
- // - When a NITOS node is added, it might remove a warning associated to all NITOS channels
-
- // A lease is present while the resource has been removed => Require warnings on nodes not in set !
+ // b) subqueries eventually (dot in the key)
+ // Let's unfold
- /* END CONSTRAINTS */
+ var cur_query = query;
+ if (cur_query.analyzed_query)
+ cur_query = cur_query.analyzed_query;
- // update is only possible is the query is not pending, etc
- // CHECK status !
-
- // XXX we can only update subqueries of the main query. Check !
- // assert query_ext.parent_query == query_ext.main_query
- // old // update_query = query_ext.main_query_ext.update_query_ext.query;
-
- // This SET_ADD is called on a subquery, so we have to
- // recontruct the path of the key in the main_query
- // We then call FIELD_STATE_CHANGED which is the equivalent for the main query
-
- var path = "";
- var sq = query_ext;
- while (sq.parent_query_ext) {
- if (path != "")
- path = '.' + path;
- path = sq.query.object + path;
- sq = sq.parent_query_ext;
+ if (data.key) {
+ var path_array = data.key.split('.');
+ var value_key = data.key.split('.');
+ $.each(path_array, function(i, method) {
+ cur_query = cur_query.subqueries[method];
+ value_key.shift(); // XXX check that method is indeed shifted
+ });
+ data.key = value_key;
}
- main_query = query_ext.main_query_ext.query;
- data = {
- request: (event_type == SET_ADD) ? FIELD_REQUEST_ADD : FIELD_REQUEST_REMOVE,
- key : path,
- value : value,
- status: STATE_SET, // XXX used to be FIELD_REQUEST_PENDING, and not new_state
- };
- this.raise_event(main_query.query_uuid, FIELD_STATE_CHANGED, data);
-
- // old //update_query.params[path].push(value);
- // old // console.log('Updated query params', update_query);
- // NOTE: update might modify the fields in Get
- // NOTE : we have to modify all child queries
- // NOTE : parts of a query might not be started (eg slice.measurements, how to handle ?)
-
- // if everything is done right, update_query should not be null.
- // It is updated when we received results from the get query
- // object = the same as get
- // filter = key : update a single object for now
- // fields = the same as get
- manifold.raise_query_event(query_uuid, event_type, value);
+ manifold.query_store.recount(cur_query.query_uuid);
+ manifold.raise_record_event(cur_query.query_uuid, event_type, data);
break;
manifold.run_query(query_ext.main_query_ext.update_query_ext.query);
break;
- /* FILTERS */
+ /* QUERY STATE CHANGED */
+
+ // FILTERS
case FILTER_ADDED:
/* Update internal record state */
- manifold.query_store.add_filter(query_uuid, value);
+ manifold.query_store.add_filter(query_uuid, data);
/* Propagate the message to plugins */
- manifold.raise_query_event(query_uuid, event_type, value);
+ manifold.raise_query_event(query_uuid, event_type, data);
break;
case FILTER_REMOVED:
/* Update internal record state */
- manifold.query_store.remove_filter(query_uuid, value);
+ manifold.query_store.remove_filter(query_uuid, data);
/* Propagate the message to plugins */
- manifold.raise_query_event(query_uuid, event_type, value);
+ manifold.raise_query_event(query_uuid, event_type, data);
break;
case FIELD_ADDED:
main_query = query_ext.main_query_ext.query;
main_update_query = query_ext.main_query_ext.update_query;
- query.select(value);
+ query.select(data);
// Here we need the full path through all subqueries
path = ""
// XXX We might need the query name in the QueryExt structure
- main_query.select(value);
+ main_query.select(data);
// XXX When is an update query associated ?
// XXX main_update_query.select(value);
- manifold.raise_query_event(query_uuid, event_type, value);
+ manifold.raise_query_event(query_uuid, event_type, data);
break;
case FIELD_REMOVED:
query = query_ext.query;
main_query = query_ext.main_query_ext.query;
main_update_query = query_ext.main_query_ext.update_query;
- query.unselect(value);
- main_query.unselect(value);
+ query.unselect(data);
+ main_query.unselect(data);
// We need to inform about changes in these queries to the respective plugins
// Note: query & main_query have the same UUID
- manifold.raise_query_event(query_uuid, event_type, value);
+ manifold.raise_query_event(query_uuid, event_type, data);
break;
}
// We need to inform about changes in these queries to the respective plugins
this.selected_resources = Array();
this.table = this.elmt('table').dataTable({
-// the original querytable layout was
-// sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
-// however the bottom line with 'showing blabla...' and the navigation widget are not really helpful
sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t>",
-// so this does not matter anymore now that the pagination area is turned off
-// sPaginationType: 'bootstrap',
- bAutoWidth: true,
-// bJQueryUI : true,
-// bRetrieve : true,
-// sScrollX : '100%', // Horizontal scrolling
-// bSortClasses : false, // Disable style for the sorted column
-// aaSorting : [[ 0, 'asc' ]], // Default sorting on URN
-// fnDrawCallback: function() { // Reassociate close click every time the table is redrawn
-// /* Prevent to loop on click while redrawing table */
-// $('.ResourceSelectedClose').unbind('click');
-// /* Handle clicks on close span */
-// /* Reassociate close click every time the table is redrawn */
-// $('.ResourceSelectedClose').bind('click', self, self._close_click);
-// }
- });
+ bAutoWidth: true,
+ });
- // XXX This should not be done at init...
- this.elmt('update').click(this, this.do_checksla);
- this.elmt('refresh').click(this, this.do_refresh);
- this.elmt('reset').click(this, this.do_reset);
- this.elmt('clear_annotations').click(this, this.do_clear_annotations);
+ this.elmt('update').click(this, this.do_ok);
+ this.elmt('refresh').click(this, this.do_cancel);
this.listen_query(options.query_uuid);
},
/***************************** GUI EVENTS *****************************/
- do_checksla: function(e) {
- var username = e.data.options.username;
- var urn = data.value;
- var arrayselectedresources = data.selected_resources;
-
- var accepted_sla = Array();
- var count = 0;
- var self = e.data;
- // XXX check that the query is not disabled
-
- console.log("DATA VALUE: " + data.value);
-
- //<p>SLA description</p>
- //<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>
- //<p>SLA description</p>
- //<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the WiLab2 resources during the sliver lifetime</p>
- var promt = $('#modal-body');
-
- // id="myModalLabel"
- var flagVW = false;
- var flagWi = false;
-
- promt.append('<p>SLA description</p>');
-
- var wilabForm = "";
- wilabForm += "<ul>";
- for(var iter = 0; iter < arrayselectedresources.length; iter++){
- var list = '<li class="wi'+iter+'" name=wi"'+iter+'">'+arrayselectedresources[iter].toLowerCase()+'</li>';
-
- if (arrayselectedresources[iter].toLowerCase().indexOf("wilab2") >= 0){
-
- accepted_sla.push({"wilab2":false});
- wilabForm += list;
- flagWi = true;
-
- }
-
- }
- wilabForm += "</ul>";
-
- //var wallmessage = '<p>SLA description</p><p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>';
-
- var wallForm = "";
- wallForm += "<ul>";
- for(var iter = 0; iter < arrayselectedresources.length; iter++){
- var list = '<li class="wall'+iter+'" name=wall"'+iter+'" >'+arrayselectedresources[iter].toLowerCase()+'</li>';
-
- if (arrayselectedresources[iter].toLowerCase().indexOf("wall2") >= 0){
-
- accepted_sla.push({"wall2":false});
- wallForm += list;
- flagVW = true;
-
- }
-
- }
- wallForm += "</ul>";
-
- var flagDouble = false;
- if(flagWi)
- {
- flagDouble = true;
- promt.append('<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the WiLab2 resources during the sliver lifetime</p>');
- promt.append(wilabForm);
- promt.append('<br />');
- }
- if(flagVW)
- {
- //promt.append(wallmessage);
- flagDouble = true;
- promt.append('<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>');
- promt.append(wallForm);
- promt.append('<br />');
- }
-
-
- // var wimessage = '<p>SLA description</p><p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>'
-
- if(flagWi || flagVW){
- $('#sla_dialog').show();
-
- $('#slamodal-wilab2').modal('show');
- }
- else
- {
-
-
- var username = e.data.options.username;
- var urn = data.value;
- // XXX check that the query is not disabled
-
- self.spin();
- // XXX check that the query is not disabled
- manifold.raise_event(self.options.query_uuid, RUN_UPDATE);
- return;
- }
-
- $("#accept_sla_wilab2").click(function(){
- console.log("SLA ACCEPTED");
- console.log("With username: " + username);
-
- // var promt = $('#modal-body');
- // var notchecked = true;
- // for (var i=0;i<50;i++)
- // {
- // var wielement = $('#wi'+i);
- // var wallElement = $('#wall'+i);
- // if(wielement != null && !wielement.checked)
- // {
- // notchecked = false;
- // }
- // if(wallElement!= null && !wallElement.checked)
- // {
- // notchecked = false;
- // }
- // }
-
-
- if(flagDouble)
- {
- $.post("/sla/agreements/simplecreate",
- { "template_id": "iMindsServiceWiLab2",
- "user": username,
- "expiration_time": new Date().toISOString()
- });
- $.post("/sla/agreements/simplecreate",
- { "template_id": "iMindsServiceVirtualwall",
- "user": username,
- "expiration_time": new Date().toISOString()
- });
-
- $('#slamodal-wilab2').modal('hide');
- accepted_sla["wilab2"] = true;
-
- manifold.raise_event(self.options.query_uuid, RUN_UPDATE);
- }
- $('#modal-body').empty();
- });
-
- $("#dismiss_sla_wilab2").click(function(){
- console.log("SLA NOT ACCEPTED");
- $('#slamodal-wilab2').modal('hide');
- $('#modal-body').empty();
- });
-
- // } else {
- // this.do_update(e);
- // }
-
- // for(var iter = 0; iter < arrayselectedresources.length; iter++){
- // var list = '<input type="checkbox" name="'+iter+'" >'+arrayselectedresources[iter].toLowerCase()+'<br>';
- // promt.append(list);
- // if (arrayselectedresources[iter].toLowerCase().indexOf("wall2") >= 0){
-
-
-
- // accepted_sla.push({"wall2":false});
-
- // $('#sla_dialog').show();
- // $('#slamodal-virtualwall').modal('show');
-
-
- // $("#accept_sla_vwall").click(function(){
- // console.log("SLA ACCEPTED");
- // console.log("With username: " + username);
-
- // $.post("/sla/agreements/simplecreate",
- // { "template_id": "iMindsServiceVirtualwall",
- // "user": username,
- // "expiration_time": new Date()
- // });
-
- // $('#slamodal-virtualwall').modal('hide');
- // accepted_sla["wall2"] = true;
- // });
-
- // $("#dismiss_sla_vwall").click(function(){
- // console.log("SLA NOT ACCEPTED");
- // $('#slamodal-vir').modal('hide');
- // });
-
- // }
-
- // if (arrayselectedresources[iter].toLowerCase().indexOf("wilab2") >= 0){
-
- // accepted_sla.push({"wilab2":false});
-
- // $('#sla_dialog').show();
- // $('#slamodal-wilab2').modal('show');
-
-
- // $("#accept_sla_wilab2").click(function(){
- // console.log("SLA ACCEPTED");
- // console.log("With username: " + username);
-
- // $.post("/sla/agreements/simplecreate",
- // { "template_id": "iMindsServiceWiLab2",
- // "user": username,
- // "expiration_time": new Date()
- // });
-
- // $('#slamodal-wilab2').modal('hide');
- // accepted_sla["wilab2"] = true;
- // });
-
- // $("#dismiss_sla_wilab2").click(function(){
- // console.log("SLA NOT ACCEPTED");
- // $('#slamodal-wilab2').modal('hide');
- // });
-
-
- // }
-
- // }
-
- // for(var sla in accepted_sla){
- // if(accepted_sla[sla] == true){
- // count += 1;
- // }
- // }
-
- // if(count == accepted_sla.length){
- // this.do_update(e);
- // }
- },
-
-
/************************** GUI MANIPULATION **************************/
populate_table: function()
{
+ var state;
+
// Loop over records and display pending ones
manifold.query_store.iter_records(this.options.query_uuid, function (record_key, record) {
+ state = manifold.query_store.get_record_state(this.options.query_uuid, null, STATE_SET);
+
});
},
return cols[0];
},
- set_state: function(data)
- {
- var action;
- var msg;
- var button = '';
-
- var row;
-
- // make sure the change is visible : toggle on the whole plugin
- // this might have to be made an 'auto-toggle' option of this plugin..
- // also it might be needed to be a little finer-grained here
-
- // XXX we don't want to show automaticaly the pending when a checkbox is checked
- //this.toggle_on();
-
- switch (data.status) {
- case STATE_SET_IN_PENDING:
- action = 'ADD';
- msg = 'PENDING';
- button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
- break;
- case STATE_SET_OUT_PENDING:
- action = 'REMOVE';
- msg = 'PENDING';
- button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
- break;
- case STATE_SET_IN:
- case STATE_SET_OUT:
- // find line and delete it
- // XXX Naming is incorrect for badge-pending !!!!
- // XXX What is this badge ?
- row = this.find_row(data.value);
- if (row)
- this.table.fnDeleteRow(row.nTr);
- /* indent was wrong !!
- $("#badge-pending").data('number', $("#badge-pending").data('number') - 1 );
- $("#badge-pending").text($("#badge-pending").data('number'));
- */
- return;
- break;
- case STATE_SET_IN_SUCCESS:
- case STATE_SET_OUT_SUCCESS:
- msg = 'SUCCESS';
- break;
- case STATE_SET_IN_FAILURE:
- case STATE_SET_OUT_FAILURE:
- msg = 'FAILURE';
- break;
- case STATE_CHANGE:
- action = 'UPDATE';
- break;
-
- }
-
- var status = msg + status;
-
- // find line
- // if no, create it, else replace it
- // XXX it's not just about adding lines, but sometimes removing some
- // XXX how do we handle status reset ?
-
- // Jordan : I don't understand this. I added this test otherwise we have string = ""..."" double quoted twice.
- if (typeof(data.value) !== "string")
- data.value = JSON.stringify(data.value);
- data.selected_resources = this.selected_resources;
- row = this.find_row(data.value);
- newline = [
- action,
- data.key,
- data.value,
- msg,
- button
- ];
- if (!row) {
- // XXX second parameter refresh = false can improve performance. todo in querytable also
- this.table.fnAddData(newline);
- row = this.find_row(data.value);
- /*
- $("#badge-pending").data('number', $("#badge-pending").data('number') + 1 );
- $("#badge-pending").text($("#badge-pending").data('number'));
- */
- } else {
- // Update row text...
- this.table.fnUpdate(newline, row.nTr);
- }
-
- // Change cell color according to status
- if (row) {
- $(row.nTr).removeClass('add remove')
- var cls = action.toLowerCase();
- if (cls)
- $(row.nTr).addClass(cls);
- }
- },
-
do_update: function(e) {
var self = e.data;
},
- // related buttons are also disabled in the html template
- do_refresh: function(e)
- {
- throw 'resource_selected.do_refresh Not implemented';
- },
-
- do_reset: function(e)
+ do_ok: function(e)
{
throw 'queryupdater.do_reset Not implemented';
},
- do_clear_annotations: function(e)
+ do_cancel: function(e)
{
throw 'queryupdater.do_clear_annotations Not implemented';
},
this.spin();
},
+ on_query_done: function()
+ {
+ this.populate_table();
+ this.unspin();
+ },
+
// D : Data present
// - on_clear_records (Get)
// - on_new_record (shared with AD) XXX
// - Key and confirmation could be sufficient, or key and record state
// XXX move record state to the manifold plugin API
- on_field_state_changed: function(result)
+ on_field_state_changed: function(data)
{
+ /*
if(result.request == FIELD_REQUEST_ADD){
this.selected_resources.push(result.value);
} else if(result.request == FIELD_REQUEST_REMOVE_RESET){
}
}
this.set_state(result);
+ */
+
+ var action, msg, row, status, button = '';
+
+ switch(data.state) {
+ case STATE_VALUE:
+ switch(data.op) {
+ // XXX other events missing !!
+ case STATE_VALUE_CHANGE_PENDING:
+ action = 'UPDATE';
+ break;
+ }
+ break;
+
+ case STATE_SET:
+ switch(data.op) {
+ case STATE_SET_IN_PENDING:
+ action = 'ADD';
+ msg = 'PENDING';
+ button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
+ break;
+
+ case STATE_SET_OUT_PENDING:
+ action = 'REMOVE';
+ msg = 'PENDING';
+ button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
+ break;
+
+ case STATE_SET_IN:
+ case STATE_SET_OUT:
+ // find line and delete it
+ row = this.find_row(data.value);
+ if (row)
+ this.table.fnDeleteRow(row.nTr);
+ return;
+
+ case STATE_SET_IN_SUCCESS:
+ case STATE_SET_OUT_SUCCESS:
+ msg = 'SUCCESS';
+ break;
+
+ case STATE_SET_IN_FAILURE:
+ case STATE_SET_OUT_FAILURE:
+ msg = 'FAILURE';
+ break;
+
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ status = msg + status;
+
+ // find line
+ // if no, create it, else replace it
+ // XXX it's not just about adding lines, but sometimes removing some
+ // XXX how do we handle status reset ?
+
+ // Jordan : I don't understand this. I added this test otherwise we have string = ""..."" double quoted twice.
+ if (typeof(data.value) !== "string")
+ data.value = JSON.stringify(data.value);
+ data.selected_resources = this.selected_resources;
+ row = this.find_row(data.value);
+ newline = [action, data.key, data.value, msg, button];
+ if (!row) {
+ // XXX second parameter refresh = false can improve performance. todo in querytable also
+ this.table.fnAddData(newline);
+ row = this.find_row(data.value);
+ } else {
+ // Update row text...
+ this.table.fnUpdate(newline, row.nTr);
+ }
+
+ // Change cell color according to status
+ if (row) {
+ $(row.nTr).removeClass('add remove')
+ var cls = action.toLowerCase();
+ if (cls)
+ $(row.nTr).addClass(cls);
+ }
},
// XXX we will have the requests for change
\r
$scope._create_new_lease = function(resource_urn, start_time, end_time)\r
{\r
- var lease_key, new_lease;\r
+ var lease_key, new_lease, data;\r
\r
lease_key = manifold.metadata.get_key('lease');\r
\r
new_lease.hashCode = manifold.record_hashcode(lease_key.sort());\r
new_lease.equals = manifold.record_equals(lease_key);\r
\r
- manifold.raise_event($scope.instance.options.query_lease_uuid, SET_ADD, new_lease);\r
+ data = {\r
+ state: STATE_SET,\r
+ key : null,\r
+ op : STATE_SET_ADD,\r
+ value: new_lease\r
+ }\r
+ manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
/* Add to local cache also, unless we listen to events from outside */\r
if (!(resource_urn in $scope._leases_by_resource))\r
$scope._leases_by_resource[resource_urn] = [];\r
\r
$scope._remove_lease = function(other)\r
{\r
- var lease_key, other_key;\r
+ var lease_key, other_key, data;\r
\r
lease_key = manifold.metadata.get_key('lease');\r
\r
other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
other_key.equals = manifold.record_equals(lease_key);\r
\r
- manifold.raise_event($scope.instance.options.query_lease_uuid, SET_REMOVED, other_key);\r
+ data = {\r
+ state: STATE_SET,\r
+ key : null,\r
+ op : STATE_SET_REMOVE,\r
+ value: other_key\r
+ }\r
+ manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
/* Remove from local cache also, unless we listen to events from outside */\r
$.grep($scope._leases_by_resource[other.resource], function(x) { return x != other; });\r
\r
\r
$scope.select = function(index, model_lease, model_resource)\r
{\r
+ var data;\r
+\r
console.log("Selected", index, model_lease, model_resource);\r
\r
var day_timestamp = SchedulerDateSelected.getTime() / 1000;\r
other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
other_key.equals = manifold.record_equals(lease_key);\r
\r
- manifold.raise_event($scope.instance.options.query_lease_uuid, SET_REMOVED, other_key);\r
+ data = {\r
+ state: STATE_SET,\r
+ key : null,\r
+ op : STATE_SET_REMOVE,\r
+ value: other_key\r
+ }\r
+ manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
/* Remove from local cache also, unless we listen to events from outside */\r
$.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
return false; // ~ break\r
/* The lease 'other' is just after, and there should not exist\r
* any other lease after it */\r
end_time = other.end_time;\r
- // XXX SET_ADD and SET_REMOVE should accept full objects\r
other_key = {\r
resource: other.resource,\r
start_time: other.start_time,\r
other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
other_key.equals = manifold.record_equals(lease_key);\r
\r
- manifold.raise_event($scope.instance.options.query_lease_uuid, SET_REMOVED, other_key);\r
+ data = {\r
+ state: STATE_SET,\r
+ key : null,\r
+ op : STATE_SET_REMOVE,\r
+ value: other_key\r
+ }\r
+ manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, other_key);\r
/* Remove from local cache also, unless we listen to events from outside */\r
$.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
return false; // ~ break\r
}\r
\r
\r
- //$scope._dump_leases();\r
+ $scope._dump_leases();\r
};\r
\r
$scope._dump_leases = function()\r
$("#plugin-scheduler").show();\r
},\r
\r
- // GUI EVENTS\r
-\r
- // TO BE REMOVED\r
- _on_submit : function()\r
- {\r
- var leasesForCommit = new Array();\r
- var tmpDateTime = SchedulerDateSelected;\r
- for (var i = 0; i < SchedulerData.length; i++)\r
- {\r
- var tpmR = SchedulerData[i];\r
- //for capturing start and end of the lease\r
- var newLeaseStarted = false;\r
- for (var j = 0; j < tpmR.leases.length; j++) {\r
- var tpmL = tpmR.leases[j];\r
- if (newLeaseStarted == false && tpmL.status == 'selected') {\r
- //get date of the slot\r
- tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
- var unixStartTime = tmpDateTime.getTime() / 1000;\r
- //add lease object\r
- leasesForCommit.push({\r
- resource: tpmR.id,\r
- //granularity: tpmR.granularity,\r
- //lease_type: null,\r
- //slice: null,\r
- start_time: unixStartTime,\r
- end_time: null,\r
- //duration: null\r
- });\r
- console.log(tpmR.id);\r
- newLeaseStarted = true;\r
- } else if (newLeaseStarted == true && tpmL.status != 'selected') {\r
- //get date of the slot\r
- tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
- var unixEndTime = tmpDateTime.getTime() / 1000;\r
- //upate end_time\r
- var tmpCL = leasesForCommit[leasesForCommit.length - 1];\r
- tmpCL.end_time = unixEndTime;\r
- //tmpCL.duration = schedulerFindDuration(tmpCL.start_time, tmpCL.end_time, tmpCL.granularity);\r
- newLeaseStarted = false;\r
- }\r
- }\r
- }\r
- console.log(leasesForCommit);\r
- for (var i = 0; i < leasesForCommit.length; i++) {\r
- manifold.raise_event(scheduler2Instance.options.query_lease_uuid, SET_ADD, leasesForCommit[i]);\r
- }\r
- },\r
- \r
// PRIVATE METHODS\r
\r
/**\r