diff --git a/lib/app.js b/lib/app.js index 42d3dad5..dff48b45 100644 --- a/lib/app.js +++ b/lib/app.js @@ -7,7 +7,6 @@ function SealiousApp(path_to_package_json, mode, layer_name){ this.mode = mode || "local"; this.layer_name = layer_name || null; - //ModuleManager = new ModuleManager(); //ConfigManager = new ConfigManager(); this.ChipManager = require("./chip-types/chip-manager"); @@ -80,11 +79,11 @@ SealiousApp.prototype = new function(){ }else{ var dispatcher_path = "./dispatchers/" + layer_name + "/dispatcher-" + layer_name + ".js"; } - console.log("dispatcher_path =", dispatcher_path); return require(dispatcher_path); } this.start = function(){ + Sealious.Dispatcher = this.dispatcher; this.dispatcher.init(); this.dispatcher.start(); diff --git a/lib/chip-types/association-interface.js b/lib/chip-types/association-interface.js index c2a20844..d8a42f19 100644 --- a/lib/chip-types/association-interface.js +++ b/lib/chip-types/association-interface.js @@ -22,8 +22,6 @@ var AssociationInterface = new function(){ var from_type = ResourceTypeManager.getByName(from_type_name); var to_type = ResourceTypeManager.getByName(to_type_name); - //var field_type_ltr = new FieldTypeManager.getFieldTypeConstructorByName("association")(from_type_name, to_type_name); - var from_field_options = { type: "association", required: options.left_required || false diff --git a/lib/chip-types/chip-manager.js b/lib/chip-types/chip-manager.js index 6b905e01..ff537cad 100644 --- a/lib/chip-types/chip-manager.js +++ b/lib/chip-types/chip-manager.js @@ -67,6 +67,14 @@ var ChipManager = new function(){ action_handler_function(chip_instance, dispatcher, dependencies); } + this.chip_exists = function(type, name){ + if(chips[type] && chips[type][name]){ + return true; + }else{ + return false; + } + } + this.get_chip = function(type, name){ try{ return chips[type][name] diff --git a/lib/chip-types/datastore.js b/lib/chip-types/datastore.js index 34b2d714..b7bd4ef4 100644 --- a/lib/chip-types/datastore.js +++ b/lib/chip-types/datastore.js @@ -13,7 +13,7 @@ Datastore.prototype = new Chip(); Datastore.prototype.return_not_implemented = function(fn_name){ return function(){ - throw new Error("Function ", fn_name, "not implemented in ", this.longid, ", aborting."); + throw new Sealious.Errors.DeveloperError("Function ", fn_name, "not implemented in ", this.longid, ", aborting."); } } diff --git a/lib/chip-types/field-type.js b/lib/chip-types/field-type.js index 75a7a133..46de7a52 100644 --- a/lib/chip-types/field-type.js +++ b/lib/chip-types/field-type.js @@ -5,7 +5,7 @@ var merge = require("merge"); * Stores field type metadata, as well as validation methods * @class */ -function FieldType(longid){ +function FieldType(longid, declaration){ this.longid = longid; } @@ -23,19 +23,25 @@ FieldType.prototype = new function(){ }); } + this.validate_declaration = function(declaration){ + return new Promise(function(resolve, reject){ + resolve(); + }); + } + this.encode = function(value_in_code){ return new Promise(function(resolve, reject){ resolve(value_in_code); }) } - this.decode = function(value_in_database){ + this.decode = function(value_in_database, formatting_options){ return new Promise(function(resolve, reject){ resolve(value_in_database); }) } - this.setParams = function(param_map){ + this.set_params = function(param_map){ if(this.params==undefined){ this.params = param_map; } diff --git a/lib/chip-types/resource-manager.js b/lib/chip-types/resource-manager.js index 4348a465..d1ef8538 100644 --- a/lib/chip-types/resource-manager.js +++ b/lib/chip-types/resource-manager.js @@ -1,7 +1,7 @@ var Promise = require("bluebird"); - var ResourceRepresentation = require("./resource-representation.js"); -var ChipManager = require("./chip-manager.js"); + +var UUIDGenerator = require("uid"); /** * Manages resources in the database @@ -10,27 +10,13 @@ var ChipManager = require("./chip-manager.js"); var ResourceManager = new function(){ this.create = function(dispatcher, type_name, body, owner, access_mode, access_mode_args){ - console.log("resource-manager.js:create-resource"); - if(arguments.length==3){ - var owner=null; - var access_mode = "private"; - var access_mode_args = []; - } else if(arguments.length==4){ - var access_mode = "private"; - } else if(arguments.length==5){ - var access_mode = "private"; - var access_mode_args = []; - } else if(arguments.length==6) { - - } else { - throw new Sealious.Errors.ValidationError("Wrong amount of arguments: create_resource."); //~ - } - - if(!ChipManager.chip_is_registred("resource_type." + type_name)){ - throw new Sealious.Errors.ValidationError("Unknown resource type: " + type_name); //~ + if(owner===undefined) owner=null; + if(access_mode===undefined) access_mode = "private"; + if(access_mode_args==undefined) access_mode_args = []; + if(!Sealious.ChipManager.chip_exists("resource_type", type_name)){ + throw new Sealious.Errors.ValidationError("Unknown resource type: " + type_name); } - - var resource_type_object = ChipManager.get_chip("resource_type", type_name); + var resource_type_object = Sealious.ChipManager.get_chip("resource_type", type_name); var encoded_body = null; @@ -39,14 +25,10 @@ var ChipManager = require("./chip-manager.js"); .then( function(){ return resource_type_object.encode_field_values(body); - } - ).then( + }).then( function(response){ encoded_body = response; - return dispatcher.metadata_increment_variable("first_free_id", dispatcher) - } - ).then( - function(newID) { + var newID = UUIDGenerator(10); var resource_data = { sealious_id: newID, type: type_name, @@ -77,7 +59,6 @@ var ChipManager = require("./chip-manager.js"); } this.get_resource_access_mode = function(dispatcher, resource_id){ - resource_id = parseInt(resource_id); return new Promise(function(resolve,reject){ dispatcher.datastore.find("resources", { sealious_id: resource_id }, {}) .then(function(documents){ @@ -89,13 +70,13 @@ var ChipManager = require("./chip-manager.js"); }); } - this.delete = function(dispatcher, type_name, body){ - if(!ChipManager.chip_is_registred("resource_type." + type_name)){ - throw new Sealious.Errors.ValidationError("Unknown resource type: " + type_name); //~ + this.delete = function(dispatcher, type_name, id){ + if(!Sealious.ChipManager.chip_is_registred("resource_type." + type_name)){ + throw new Sealious.Errors.ValidationError("Unknown resource type: " + type_name); } return new Promise(function(resolve, reject){ - dispatcher.datastore.delete("resources", {sealious_id: body.id, type: type_name}, {}) + dispatcher.datastore.delete("resources", {sealious_id: id, type: type_name}, {}) .then(function(data){ resolve(); }).catch(function(e){ @@ -112,7 +93,6 @@ var ChipManager = require("./chip-manager.js"); */ this.get_by_id = function(dispatcher, resource_id){ - resource_id = parseInt(resource_id); return new Promise(function(resolve,reject){ dispatcher.datastore.find("resources", { sealious_id: resource_id }, {}) .then(function(documents){ @@ -132,15 +112,15 @@ var ChipManager = require("./chip-manager.js"); params = {}; } return new Promise(function(resolve, reject){ - if(!ChipManager.chip_is_registred("resource_type."+type_name)){ + if(!Sealious.ChipManager.chip_exists("resource_type", type_name)){ reject(new Sealious.Errors.ValidationError("resource type "+type_name+" does not exist")); }else{ dispatcher.datastore.find("resources", { type: type_name }, {}, params).then(function(response) { var ret = response.map(function(database_entry){ return new ResourceRepresentation(database_entry).getData(); }) - resolve(ret); - }) + resolve(ret); + }) } }) } @@ -196,28 +176,28 @@ var ChipManager = require("./chip-manager.js"); this.search_by_mode = function(dispatcher, type, mode){ return new Promise(function(resolve, reject){ - dispatcher.datastore.find("resources", {access_mode: mode, type: type}, {}) - .then(function(documents){ - var database_entry = documents; - var resource_representations = documents.map(function(document){ - return new ResourceRepresentation(document).getData() - }); - resolve(resource_representations); - }); + dispatcher.datastore.find("resources", {access_mode: mode, type: type}, {}) + .then(function(documents){ + var database_entry = documents; + var resource_representations = documents.map(function(document){ + return new ResourceRepresentation(document).getData() + }); + resolve(resource_representations); + }); }); - } + } - this.get_resource_type_signature = function(dispatcher, type_name){ - return new Promise(function(resolve, reject){ - var resource_type_chip = ChipManager.get_chip("resource_type", type_name); - if(resource_type_chip){ - resolve(resource_type_chip.get_signature()); - }else{ - reject(new Sealious.Errors.Error("ResourceManager tried to access chip type `" + type_name + "`, which does not exist.")); - } - }) + this.get_resource_type_signature = function(dispatcher, type_name){ + return new Promise(function(resolve, reject){ + var resource_type_chip = ChipManager.get_chip("resource_type", type_name); + if(resource_type_chip){ + resolve(resource_type_chip.get_signature()); + }else{ + reject(new Sealious.Errors.Error("ResourceManager tried to access chip type `" + type_name + "`, which does not exist.")); + } + }) + } } -} -module.exports = ResourceManager; + module.exports = ResourceManager; diff --git a/lib/chip-types/resource-representation.js b/lib/chip-types/resource-representation.js index 278a8cfb..811fadca 100644 --- a/lib/chip-types/resource-representation.js +++ b/lib/chip-types/resource-representation.js @@ -5,10 +5,6 @@ */ function ResourceRepresentation(database_entry){ this.database_entry = database_entry; - if(!database_entry.body){ - //console.log("database_entry missing:", database_entry.body); - } - //console.log("DATABASE_ENTRY: ", database_entry); } ResourceRepresentation.prototype = new function(){ @@ -19,10 +15,10 @@ ResourceRepresentation.prototype = new function(){ */ this.getData = function(){ var data = this.database_entry.body || {}; - //console.log(data===null); data.owner_id = this.database_entry.owner; data.id = this.database_entry.sealious_id; data.access_mode = this.database_entry.access_mode; + data.type = this.database_entry.type; return data; } diff --git a/lib/chip-types/resource-type-field.js b/lib/chip-types/resource-type-field.js index 9e481fe4..43e6fdaf 100644 --- a/lib/chip-types/resource-type-field.js +++ b/lib/chip-types/resource-type-field.js @@ -1,11 +1,5 @@ var Promise = require("bluebird"); -/** - * A field in a resource type - * @class - * @param {string} name - * @param {object} options - */ function ResourceTypeField(declaration){ this.name = declaration.name; this.type_name = declaration.type; @@ -13,7 +7,7 @@ function ResourceTypeField(declaration){ var type_constructor = Sealious.ChipManager.get_chip("field_type", declaration.type); this.type_parameters = declaration.params; this.type = new type_constructor(); - this.type.setParams(declaration.params); + this.type.set_params(declaration.params); this.required = declaration.required || false; this.derived = declaration.derived || false; } @@ -31,10 +25,15 @@ ResourceTypeField.prototype = new function(){ that.type.isProperValue(value, dispatcher).then( resolve, function(err){ + /* + //older version, not compliant with #132 var new_error = { field_name: that.name, error_message: err } + */ + var new_error={}; + new_error[that.name] = err; reject(new_error); } ); diff --git a/lib/chip-types/resource-type.js b/lib/chip-types/resource-type.js index b656da74..360c5e38 100644 --- a/lib/chip-types/resource-type.js +++ b/lib/chip-types/resource-type.js @@ -1,5 +1,7 @@ var Promise = require("bluebird"); var ResourceTypeField = require("./resource-type-field.js"); +//var Reference = require("./reference.js"); + var merge = require("merge"); var ResourceType = function(parent_module_path, name){ @@ -7,6 +9,8 @@ var ResourceType = function(parent_module_path, name){ this.longid = "resource_type" + name; this.name = name; this.fields = {}; + this.references = {}; + this.keys = {}; Sealious.ChipManager.add_chip("resource_type", this.name, this, parent_module_path); } @@ -15,8 +19,9 @@ ResourceType.prototype = new function(){ this.add_field = function(field_declaration){ var field_object = new ResourceTypeField(field_declaration); var field_name = field_object.name; - if(!this.fields[field_name]){ + if(!this.keys[field_name]){ this.fields[field_name] = field_object; + this.keys[field_name] = field_object; } } @@ -27,34 +32,54 @@ ResourceType.prototype = new function(){ } } + function ensure_no_unknown_fields(values){ + var validation_errors = {}; + for(var field_name in values){ + if(this.keys[field_name]==undefined){ + validation_errors[field_name] = "unknown_field"; + } + } + return validation_errors; + } + + function ensure_no_missing_required_fields(values){ + var validation_errors = {}; + for(var i in this.keys){ + var field = this.keys[i]; + if(field.required && !values[field.name]){ + validation_errors[field.name] = "missing_value"; + } + } + return validation_errors; + } + this.validate_field_values = function(values){ var that = this; + var validation_errors = {}; return new Promise(function(resolve, reject){ - for(var field_name in values){ - //checking for unknown fields - if(that.fields[field_name]==undefined){ - throw new Sealious.Errors.ValidationError("unknown field: " + field_name); //~ - } - } - for(var i in that.fields){ - var field = that.fields[i]; - if(field.required && !values[field.name]){ - reject(new Sealious.Errors.ValidationError("required field missing:" + field.name)) //~ - return; - } - } + validation_errors = merge(validation_errors, ensure_no_unknown_fields.call(that, values)); + validation_errors = merge(validation_errors, ensure_no_missing_required_fields.call(that, values)); var promise_array = []; - for(var field_name in values){ - var temp_promise = that.fields[field_name].isProperValue(values[field_name]); - promise_array.push(temp_promise); + for(var key in values){ + if(validation_errors[key]===undefined){ + var temp_promise = that.keys[key].isProperValue(values[key]); + promise_array.push(temp_promise); + } } + var error_message = "There are problems with some of the provided values";//TODO: ładnie generować tekst podsumowujący problem z inputem + Promise.all(promise_array) .then(function(result){ - resolve(); + if(Object.keys(validation_errors).length>0){ + throw new Sealious.Errors.ValidationError(error_message, {invalid_fields: validation_errors}); + }else{ + resolve(); + } }) .catch(function(error){ - reject(error); + validation_errors = merge(validation_errors, error); + reject(new Sealious.Errors.ValidationError(error_message, {invalid_fields: validation_errors})); }); }) @@ -64,7 +89,7 @@ ResourceType.prototype = new function(){ var promises = []; for(var field_name in body){ var current_value = body[field_name]; - promises.push(this.fields[field_name].encode_value(current_value, true)); + promises.push(this.keys[field_name].encode_value(current_value, true)); } return Promise.all(promises).then(function(responses){ return new Promise(function(resolve, reject){ diff --git a/lib/core.js b/lib/core.js index 4a947591..794be5ba 100644 --- a/lib/core.js +++ b/lib/core.js @@ -5,6 +5,9 @@ Sealious.Response = require("./response/response.js"); Sealious.ChipManager = require("./chip-types/chip-manager.js"); Sealious.ConfigManager = require("./config/config-manager.js"); +Sealious.Dispatcher = null; + +Sealious.Logger = require("./logger/logger.js"); Sealious.which_chip_types_to_start_for_layer = { db: ["datastore"], diff --git a/lib/dispatchers/biz/dispatcher-biz.js b/lib/dispatchers/biz/dispatcher-biz.js index 5ec8e68c..6efc1c6c 100644 --- a/lib/dispatchers/biz/dispatcher-biz.js +++ b/lib/dispatchers/biz/dispatcher-biz.js @@ -1,13 +1,7 @@ -var MetadataManager = require("../../metadata-manager.js"); - var DispatcherDistributed = require("../dispatcher-distributed.js"); var DispatcherDistributedBIZ = new DispatcherDistributed("biz"); -DispatcherDistributedBIZ.metadata_increment_variable = function() { - //in local mode - return MetadataManager.increment_variable.apply(MetadataManager, arguments); -} DispatcherDistributedBIZ.process_resource_manager_method = function(ResourceManager, method_name) { return ResourceManager[method_name].bind(ResourceManager, this); diff --git a/lib/dispatchers/db/database-rest-server.js b/lib/dispatchers/db/database-rest-server.js deleted file mode 100644 index 20aa218c..00000000 --- a/lib/dispatchers/db/database-rest-server.js +++ /dev/null @@ -1,96 +0,0 @@ -var Hapi = require('hapi'); -var config = require("../../config/config-manager.js").getConfiguration(); - -var DatabaseAccess = null;//a proper datastore driver will be passed by the dispatcher using pass_datastore_object method - -var server = new Hapi.Server(); -server.connection({ port: parseInt(config.db_layer_config.port)}); - -//console.log("I'm in database-rest-server"); - -server.route({ - method: 'GET', - path: '/', - handler: function (request, reply) { - reply('jestę serwerę 1'); - } -}); - -server.route({ - method: 'GET', - path: '/api/rest/v1/{collection_name}/', - handler: function (request, reply) { - var collection_name = request.params.collection_name; - var query = (request.query.query && JSON.parse(request.query.query))||{}; - console.log(request.query); - for(var i in query){ - //checking for regular expression - if(query[i]!=null && query[i].toString().slice(0, 3) == "$R("){ - var regex_declaration = query[i].slice(3, -1); - query[i] = new RegExp(regex_declaration.split("/")[1], regex_declaration.split("/")[2]); - } - } - var options = (request.query.options && JSON.parse(request.query.options)) || {}; - var output_options = JSON.parse(request.query.output_options); - DatabaseAccess.find(collection_name, query, options, output_options).then(function(data){ - reply(data); // odpowiedz na zapytanie http - }) - } -}); - -/* POST NA ZASÓB */ -server.route({ - method: 'POST', - path: '/api/rest/v1/{collection_name}/', - handler: function (request, reply) { - var collection_name = request.params.collection_name; - var options2 = JSON.parse(request.payload.json_encoded_payload); - var query = options2.query; - var mode = options2.mode; - var options = options2.options; - DatabaseAccess.insert(collection_name, query, options).then(function(data){ - reply(data); - }); - } -}); - -server.route({ - method: 'PUT', - path: '/api/rest/v1/{collection_name}/', - handler: function (request, reply) { - var collection_name = request.params.collection_name; - var options2 = JSON.parse(request.payload.json_encoded_payload); - var query = options2.query; - var mode = options2.mode; - var options = options2.options; - DatabaseAccess.update(collection_name, query, options).then(function(data){ - reply(data); - }); - } -}); - -server.route({ - method: 'DELETE', - path: '/api/rest/v1/{collection_name}/', - handler: function (request, reply) { - var collection_name = request.params.collection_name; - var options2 = JSON.parse(request.payload.json_encoded_payload); - var query = options2.query; - var mode = options2.mode; - var options = options2.options; - DatabaseAccess.delete(collection_name, query, options).then(function(data){ - console.log("database-rest-server.js", "database response after DELETE statement:", data, "."); - reply(data); - }); - } -}); - -var db_biz_protocol = {}; - -db_biz_protocol.server = server; - -db_biz_protocol.pass_datastore_object = function(datastore_object){ - DatabaseAccess = datastore_object; -} - -module.exports = db_biz_protocol; \ No newline at end of file diff --git a/lib/dispatchers/db/dispatcher-db.js b/lib/dispatchers/db/dispatcher-db.js index 0e6e34c1..11b8dc40 100644 --- a/lib/dispatchers/db/dispatcher-db.js +++ b/lib/dispatchers/db/dispatcher-db.js @@ -1,24 +1,17 @@ -var Errors = require("../../response/error.js"); - -var MetadataManager = require("../../metadata-manager.js"); - var DispatcherDistributed = require("../dispatcher-distributed.js"); var DispatcherDistributedDB = new DispatcherDistributed("db"); -DispatcherDistributedDB.metadata_increment_variable = function() { - //... -} DispatcherDistributedDB.process_resource_manager_method = function(ResourceManager, method_name) { return function(){ - throw new Errors.Error("DispatcherDistributedDB tried to call a ResourceManager method, wchich is not allowed.") + throw new Sealious.Errors.Error("DispatcherDistributedDB tried to call a ResourceManager method, which is not allowed.") } } DispatcherDistributedDB.process_service_method = function(service, service_name, method_name) { return function(){ - throw new Errors.Error("DispatcherDistributedDB tried to call a service method, wchich is not allowed.") + throw new Sealious.Errors.Error("DispatcherDistributedDB tried to call a service method, which is not allowed.") } } diff --git a/lib/dispatchers/dispatcher-distributed.js b/lib/dispatchers/dispatcher-distributed.js index 2fdab15d..ed5abf6b 100644 --- a/lib/dispatchers/dispatcher-distributed.js +++ b/lib/dispatchers/dispatcher-distributed.js @@ -57,7 +57,6 @@ DispatcherDistributed.prototype.resolve_to_error = function(response_error){ DispatcherDistributed.prototype.call_over_socket = function(method_name, args){ - console.log("calling a remote procedure:", method_name, "with arguments:", args); var id = this.get_request_id(); this.socket_client.emit("request", { method_name: method_name, @@ -67,11 +66,10 @@ DispatcherDistributed.prototype.call_over_socket = function(method_name, args){ return new Promise(function(resolve, reject){ this.add_callback_to_queue(id, function(data){ - console.log("dispatcher-web.js data", data); resolve(data); }, function(error){ - console.log("error in promise:", error.error); + Sealious.Logger.error(error); reject(new Sealious.Errors.Error(error.error.status_message, error.error)); } ); @@ -91,7 +89,6 @@ DispatcherDistributed.prototype.connect_to_layer = function(layer_name){ this.resolve_to_callback(data); }.bind(this)); this.socket_client.on("throw_error", function(data){ - console.log("received error in response:", data); this.resolve_to_error(data); }.bind(this)); } @@ -101,20 +98,16 @@ DispatcherDistributed.prototype.listen = function(){ this.socket_server = io_server(); var cfg = ConfigManager.get_config().layer_config[this.layer_name]; this.socket_server.listen(cfg.port); - console.log(this.layer_name + " layer listening on :" + cfg.port); + Sealious.Logger.info(this.layer_name.toUpperCase() + " layer listening on port: " + cfg.port + "\n"); this.socket_server.on('connection', function(socket) { - console.log("dispatcher-distributed: a layer from above connected"); + Sealious.Logger.info("A layer from above connected"); socket.on("request", function(data) { var method_name = data.method_name; var arguments = data.arguments; - console.log(arguments); - console.log(Object.keys(arguments)); - var arguments_array = Object.keys(arguments).map(function (key) {console.log(data.arguments[key]); return data.arguments[key]}); + var arguments_array = Object.keys(arguments).map(function (key) {return data.arguments[key]}); var request_id = data.request_id; - console.log("received a request to call procedure `" + method_name + "` with arguments ", arguments_array); - var method_path = method_name.split("."); var method_to_call = that; for (var i = 0; i < method_path.length; i++) { @@ -128,21 +121,20 @@ DispatcherDistributed.prototype.listen = function(){ response.payload = result; socket.emit("response", response); }).catch(function(err) { - console.log("caught error:", err); + Sealious.Logger.error(err); var response = {}; response.type = "error"; response.error = err; response.request_id = request_id; - console.log("responding with ", response); - console.log(err instanceof Error, err.stack); socket.emit("throw_error", response); }); }); socket.on('logout', function() { + Sealious.Logger.info("Logging out."); socket.disconnect(); // zamknięcie połączenia }); socket.on('disconnect', function() { - console.log("Upper layer disconnected"); // event rozłączenia + Sealious.Logger.info("Upper layer disconnected"); // event rozłączenia }); }); @@ -152,8 +144,6 @@ DispatcherDistributed.prototype.layer_order = ["web", "biz", "db"] DispatcherDistributed.prototype.start = function(){ var current_layer_index = this.layer_order.indexOf(this.layer_name); - console.log("CURRENT LAYER NAME:", this.layer_name); - console.log("CURRENT LAYER INDEX:", current_layer_index); if(this.layer_order[current_layer_index+1]!=undefined){ //if we're not on the bottom-most layer this.connect_to_layer(this.layer_order[current_layer_index+1]) } diff --git a/lib/dispatchers/dispatcher.js b/lib/dispatchers/dispatcher.js index 8e16e388..ced8938d 100644 --- a/lib/dispatchers/dispatcher.js +++ b/lib/dispatchers/dispatcher.js @@ -1,6 +1,5 @@ var ChipManager = require("../chip-types/chip-manager.js"); var ResourceManager = require("../chip-types/resource-manager.js"); -var Errors = require("../response/error.js"); Dispatcher = function(){ this.datastore_chip = null; @@ -31,7 +30,7 @@ Dispatcher.prototype = new function(){ } } }else{ - throw new Errors.Error("Dispatcher should implement `process_resource_manager_method`"); + throw new Sealious.Errors.Error("Dispatcher should implement `process_resource_manager_method`"); } } @@ -40,7 +39,7 @@ Dispatcher.prototype = new function(){ var services = ChipManager.get_chips_by_type("service"); this.services = {}; for(var service_name in services){ - console.log("service_name:", service_name); + Sealious.Logger.info("service_name:", service_name); var service = services[service_name]; this.services[service_name] = {}; for(var method_name in service){ @@ -50,7 +49,7 @@ Dispatcher.prototype = new function(){ } } }else{ - throw new Errors.Error("Dispatcher should implement `process_service_method`"); + throw new Sealious.Errors.Error("Dispatcher should implement `process_service_method`"); } } @@ -63,7 +62,7 @@ Dispatcher.prototype = new function(){ } } }else{ - throw new Errors.Error("Dispatcher should implement `process_datastore_method`"); + throw new Sealious.Errors.Error("Dispatcher should implement `process_datastore_method`"); } } diff --git a/lib/dispatchers/local/dispatcher-local.js b/lib/dispatchers/local/dispatcher-local.js index 0eaeb471..904307ca 100644 --- a/lib/dispatchers/local/dispatcher-local.js +++ b/lib/dispatchers/local/dispatcher-local.js @@ -1,7 +1,6 @@ var Promise = require("bluebird"); var Dispatcher = require("../dispatcher.js"); -var MetadataManager = require("../../metadata-manager.js"); var DispatcherLocal= Object.create(Dispatcher.prototype); @@ -17,9 +16,6 @@ DispatcherLocal.process_datastore_method = function(datastore_chip, method_name) return datastore_chip[method_name].bind(datastore_chip); } -DispatcherLocal.metadata_increment_variable = function(){ - return MetadataManager.increment_variable.apply(MetadataManager, arguments); -} module.exports = DispatcherLocal; diff --git a/lib/logger/logger.js b/lib/logger/logger.js new file mode 100644 index 00000000..adeca8b4 --- /dev/null +++ b/lib/logger/logger.js @@ -0,0 +1,115 @@ +var winston = require('winston'); +var ConfigManager = require("../config/config-manager.js"); + +/* + This is the default configration of Sealious logger. + To retrieve a specifig setting, use "get_config()" function, ex. "ConfigManager.get_config().logger_config.logger_level". + + @logger_level - specifies from which log level (displayed below) onward should be displayed, + @logger_color - specifies if the log should be colorized, values "true" or "false" + @logger_file - defines a filename to save the logs, if a falsy value is given the logs will not be saved, + @logger_dirname - defines a default path to save the logs, + @logger_to_json - specifies the format of the saved logs, + @logger_rotation - defines the log rotation format, set to daily by default +*/ +ConfigManager.set_default_config( + "logger_config", + { + logger_level : "info", + logger_color : true, + logger_file : null, + logger_dirname: ".", + logger_to_json: false, + logger_rotation: '.yyyy-MM-Tdd' + }); + + +/* + This is the custom logger level and color configuration. + + @levels - default logger levels, 0 being the lowest importance, 4 being the highest: + * lazyseal - an Easter, or should we say: Sealious egg. Used only for humorous reasons, the lowest level of importance, default color: white, + * info - used for stating the current status or general information such as starting the server, default color: green, + * debug - used for debugging, default color: blue, + * warning - used to display warnings, default color: yellow, + * error - used to display errors, default color: red + +*/ +var custom = { + levels: { + lazyseal: 0, + info: 1, + debug: 2, + warning: 3, + error: 4 + }, + colors: { + lazyseal: "white", + info: "green", + debug: 'blue', + warning: 'yellow', + error: 'red' + } +}; + +/* + Returns the current date and time, default format: "yyyy-mm-dd hh:mm:ss.mmm", ex. "2000-01-01 20:00:00.000" +*/ +function getDateTime() { + + var date = new Date(); + + var hour = date.getHours(); + hour = (hour < 10 ? "0" : "") + hour; + + var min = date.getMinutes(); + min = (min < 10 ? "0" : "") + min; + + var sec = date.getSeconds(); + sec = (sec < 10 ? "0" : "") + sec; + + var milli = date.getMilliseconds(); + milli = (milli < 10 ? "00" : "") + milli; + milli = (milli < 100 && milli >=10 ? "0" : "") + milli; + + var year = date.getFullYear(); + + var month = date.getMonth() + 1; + month = (month < 10 ? "0" : "") + month; + + var day = date.getDate(); + day = (day < 10 ? "0" : "") + day; + + return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + "." + milli; + +} + +var transports_array = new Array(); +var logger_level = ConfigManager.get_config().logger_config.logger_level; +var logger_color = ConfigManager.get_config().logger_config.logger_color; +var logger_file = ConfigManager.get_config().logger_config.logger_file; +var logger_dirname = ConfigManager.get_config().logger_config.logger_dirname; +var logger_to_json = ConfigManager.get_config().logger_config.logger_to_json; +var logger_rotation = ConfigManager.get_config().logger_config.logger_rotation; + + +var winston_level = new (winston.transports.Console)({ level: logger_level, colorize: logger_color, timestamp: function() { return getDateTime(); } }); +transports_array.push(winston_level); + +if (logger_file) { + var winston_save_to_file = new (winston.transports.File)({ filename: logger_file, colorize: logger_color, timestamp: function() { return getDateTime(); }, dirname: logger_dirname, json: logger_to_json }); + var winston_daily_rotate = new (winston.transports.DailyRotateFile)( { filename : logger_file, datePattern: logger_rotation }); + transports_array.push(winston_save_to_file); + transports_array.push(winston_daily_rotate); +} + + +var logger = new (winston.Logger)( + { + levels: custom.levels, + colors: custom.colors, + transports: transports_array + } +); + +module.exports = logger; \ No newline at end of file diff --git a/lib/metadata-manager.js b/lib/metadata-manager.js deleted file mode 100644 index aafbafc1..00000000 --- a/lib/metadata-manager.js +++ /dev/null @@ -1,70 +0,0 @@ -var Promise = require("bluebird"); - -var MetadataManager = new function(){ - - var that = this; - - this.get_value = function(key, dispatcher){ - return new Promise(function(resolve, reject){ - dispatcher.datastore.find("meta", { "key": key }, {}).then(function(response){ - if(response.length==0){ - resolve(undefined); - }else{ - resolve(response[0].value); - } - }); - }) - } - - this.has_key = function(key, dispatcher){ - return new Promise(function(resolve, reject){ - dispatcher.datastore.find("meta", { key: key }, {}).then(function(response){ - if(response.length===0){ - resolve(false); - }else{ - resolve(true); - } - }); - }); - } - - this.set_value = function(key, value, dispatcher){ - return new Promise(function(resolve, reject){ - that.has_key(key, dispatcher).then(function(has){ - function actual_set(){ - dispatcher.datastore.update("meta", { key: key }, {key:key, value: value}).then(function(response){ - if(response.length==0){ - resolve(false); - }else{ - resolve(true); - } - }); - } - if(!has){ - dispatcher.datastore.insert("meta", {key: key, value: value}, {}).then(function(data){ - actual_set(); - }) - }else{ - actual_set(); - } - }) - }) - } - - this.increment_variable = function(key, dispatcher){ - return new Promise(function(resolve, reject){ - that.get_value(key, dispatcher).then(function(data){ - if(isNaN(data)){ - var new_id=0; - }else{ - var new_id = data+1; - } - that.set_value(key, new_id, dispatcher).then(function(dataL){ - resolve(new_id); - }); - }); - }) - } -} - -module.exports = MetadataManager; \ No newline at end of file diff --git a/lib/module/module-manager.js b/lib/module/module-manager.js index eea54e5f..d6051d61 100644 --- a/lib/module/module-manager.js +++ b/lib/module/module-manager.js @@ -5,26 +5,10 @@ var Promise = require("bluebird"); var Module = require("./module.js"); -function intersection_of_arrays(array1, array2){ - //console.log("comparing arrays, ", array1, array2) - array3 = array1.filter(function(n) { - return array2.indexOf(n) != -1; - }); - return array3; -} - var ModuleManager = new function(){ var modules_by_id = {}; - function get_module_count(){ - var c = 0; - for(var i in modules_by_id){ - c++; - } - return c; - } - this.add_module = function(sealious_module_json_file_path){ var module_dir = path.resolve(sealious_module_json_file_path, "../"); var current_module = new Module(module_dir); @@ -63,7 +47,6 @@ var ModuleManager = new function(){ required_chips.forEach(function(chip_id){ if(!defined_so_far_chip_ids.has(chip_id) && !chips_defined_by_current_module_set.has(chip_id)){ initialize_module = false; - console.log("cannot initialize ", module_id, "because of ", chip_id); } }) if(initialize_module){ @@ -82,13 +65,13 @@ var ModuleManager = new function(){ } this.initialize_all = function(dispatcher){ - console.log("Initializing modules..."); + Sealious.Logger.info("Initializing modules..."); var module_ids = decide_module_execution_order(); for(var i in module_ids){ var module_id = module_ids[i]; modules_by_id[module_id].initialize(dispatcher); } - console.log("Modules initialized!"); + Sealious.Logger.info("Modules initialized!"); } this.start = function(chip_types_to_start){ diff --git a/lib/module/module.js b/lib/module/module.js index 8ddcf014..21ed2794 100644 --- a/lib/module/module.js +++ b/lib/module/module.js @@ -45,7 +45,6 @@ ChipActionDescription.prototype = new function(){ } var Module = function(path_to_module){ - //console.log("module.js path_to_module", path_to_module); this.path = path_to_module; this.info = null; this.load_info(); diff --git a/lib/response/error.js b/lib/response/error.js index 3715b7ed..f4bc31c6 100644 --- a/lib/response/error.js +++ b/lib/response/error.js @@ -2,7 +2,7 @@ var Response = require("./response.js"); var SealiousErrors = {}; -SealiousErrors.Error = function(message, params){ +SealiousErrors.Error = function(message, params, data){ var ret = new Error(message); params = params || {}; ret.is_sealious_error = true; @@ -12,56 +12,40 @@ SealiousErrors.Error = function(message, params){ ret.is_developer_fault = params.is_developer_fault===undefined? false : params.is_developer_fault; ret.type = params.type===undefined? "error" : params.type; ret.http_code = params.http_code===undefined? 500 : params.http_code; - - ret.toResponse = function(){ - console.log("1.1"); - return new Response({}, true, this.type, this.status_message); - } + ret.data = data || params.data || {}; return ret; } -/* -SealiousErrors.Error.prototype = new function(){ - - - this.is_error = true; - - - this.toString = function(){ - - } -} -*/ - -SealiousErrors.ValidationError = function(message){ - var err = new SealiousErrors.Error(message); +SealiousErrors.ValidationError = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); err.status_message = message; err.is_user_fault = true; err.type="validation"; + err.http_code = 403; return err; } -SealiousErrors.ValueExists = function(message){ - var err = new SealiousErrors.Error(message); +SealiousErrors.ValueExists = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); err.status_message = message; err.is_user_fault = true; err.type="valueExists"; - this.http_code = 409; + err.http_code = 409; return err; } -SealiousErrors.InvalidCredentials = function(message){ - var err = new SealiousErrors.Error(message); +SealiousErrors.InvalidCredentials = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); err.status_message = message; err.is_user_fault = true; - err.type="validation"; + err.type="authorization"; err.http_code = 401; return err; } -SealiousErrors.NotFound = function(message){ - var err = new SealiousErrors.Error(message); +SealiousErrors.NotFound = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); err.status_message = message; err.is_user_fault = true; err.type="not_found"; @@ -69,8 +53,8 @@ SealiousErrors.NotFound = function(message){ return err; } -SealiousErrors.InternalConnectionError = function(message){ - var err = new SealiousErrors.Error(message); +SealiousErrors.InternalConnectionError = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); err.status_message = message; err.is_user_fault = false; err.type="internal_connection_error"; @@ -78,8 +62,8 @@ SealiousErrors.InternalConnectionError = function(message){ return err; } -SealiousErrors.DependencyError = function(message){ - var err = new SealiousErrors.Error(message); +SealiousErrors.DependencyError = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); err.status_message = message; err.is_user_fault = false; err.is_developer_fault = true; @@ -88,6 +72,24 @@ SealiousErrors.DependencyError = function(message){ return err; } +SealiousErrors.UnauthorizedRequest = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); + err.status_message = message; + err.is_user_fault = true; + err.type="unauthorized_request"; + err.http_code = 401; + return err; +} + +SealiousErrors.DeveloperError = function(message, data){ + var err = new SealiousErrors.Error(message, {}, data); + err.status_message = message; + err.is_user_fault = false; + err.is_developer_fault = true; + err.type="dev_error"; + return err; +} + /* process.on('uncaughtException', function (exception) { switch(exception.code){ diff --git a/lib/response/exception-handler.js b/lib/response/exception-handler.js deleted file mode 100644 index e7c91cfb..00000000 --- a/lib/response/exception-handler.js +++ /dev/null @@ -1,44 +0,0 @@ -var ExceptionHandler = new function(){ - var function_array = []; - - this.addErrorParser = function(function_to_add){ - function_array.push(function_to_add); - } - - this.processError = function(err){ - var found_suitable_function = false; - for(var i in function_array){ - var current_function = function_array[i]; - var function_output = current_function(err); - if(function_output!=null){ - console.error("===ERROR=== ", function_output); - //console.error(err.stack); - found_suitable_function = true; - break; - } - } - if(!found_suitable_function){ - /*if (err.code == "unresolved_dependencies") { - console.error("Unresolved dependencies error!"); - console.error(err.err_message); - console.error("Module: "+err.module); - }*/ - console.error("===ERROR===:", err.console_message || err.message); - console.error(err.stack); - } - } -} - -process.on('uncaughtException', function(err) { - ExceptionHandler.processError(err); -}); - -/* - console.log("\n\n*****ERROR*****"); - console.log("Message: " + this.err_message + "\nCode: " + this.err_code + "\nModule: " + this.err_module); - console.log("***************\n\n"); - */ - - - -module.exports = ExceptionHandler; diff --git a/lib/response/response.js b/lib/response/response.js index 4c3355f7..f179702a 100644 --- a/lib/response/response.js +++ b/lib/response/response.js @@ -7,7 +7,7 @@ function Response(data, is_error, type, status_message){ Response.fromError = function(sealious_error){ return { - data: {}, + data: sealious_error.data || {}, is_error: true, type: sealious_error.type, status_message: sealious_error.status_message diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 8e70ab88..761140fa --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sealious", - "version": "0.2.1", + "version": "0.3.0", "description": "", "main": "./main.js", "scripts": { @@ -21,11 +21,11 @@ "dependencies": { "Set": "~0.4.1", "bluebird": "~2.9.9", - "ip": "~0.3.2", "merge": "^1.2.0", - "open": "0.0.5", "socket.io": "~1.2.0", - "socket.io-client": "~1.2.0" + "socket.io-client": "~1.2.0", + "winston": "^1.0.0", + "uid": "0.0.2" }, "devDependencies": { "blanket": "1.1.6", diff --git a/sealious.sublime-project b/sealious.sublime-project index ce005e9c..03d876d4 100644 --- a/sealious.sublime-project +++ b/sealious.sublime-project @@ -2,16 +2,13 @@ "folders": [ { - "follow_symlinks": true, "path": "." }, { - "follow_symlinks": true, - "path": "/home/kuba/Dropbox/Desktop/Sealious/sealious-example-app" + "path": "C:\\Github\\sealious-base-chips" }, { - "follow_symlinks": true, - "path": "/home/kuba/Dropbox/Desktop/Sealious/sealious-base-chips" + "path": "C:\\Github\\sealious-example-app" } ] } diff --git a/shell.js b/shell.js index f9d7489f..17fb2b52 100755 --- a/shell.js +++ b/shell.js @@ -14,5 +14,4 @@ if(argument && argument.slice(0,2)=="--"){ } app_location = process.argv[index]; - SealiousCore.start(mode, layer_name, app_location); \ No newline at end of file