diff --git a/lib/core/engine.js b/lib/core/engine.js index ad248a7c6..8765d6d27 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -1,11 +1,13 @@ +var http = require('http'); +var utils = require('./utils.js'); + var Events = require('./events.js'); var Logger = require('./logger.js'); var Config = require('./config.js'); var DeployManager = require('../contracts/deploy_manager.js'); var ABIGenerator = require('../contracts/abi.js'); -var Dashboard = require('../dashboard/dashboard.js'); -var ServicesMonitor = require('./services.js'); +var ServicesMonitor = require('./services_monitor.js'); var Pipeline = require('../pipeline/pipeline.js'); var Server = require('../pipeline/server.js'); var Watch = require('../pipeline/watch.js'); @@ -19,24 +21,34 @@ var Engine = function(options) { }; Engine.prototype.init = function(_options) { + var self = this; var options = _options || {}; this.events = new Events(); this.logger = options.logger || new Logger({logLevel: 'debug'}); this.config = new Config({env: this.env, logger: this.logger, events: this.events}); this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs}); this.plugins = this.config.plugins; + + this.servicesMonitor = new ServicesMonitor({events: this.events, logger: this.logger}); + this.servicesMonitor.addCheck('embarkVersion', function(cb) { + return cb({name: 'Embark ' + self.version, status: 'green'}); + }); +}; + +Engine.prototype.startMonitor = function() { + this.servicesMonitor.startMonitor(); }; Engine.prototype.startService = function(serviceName, _options) { var options = _options || {}; var services = { - "monitor": this.monitorService, "pipeline": this.pipelineService, "abi": this.abiService, "deployment": this.deploymentService, "fileWatcher": this.fileWatchService, - "webServer": this.webServerService + "webServer": this.webServerService, + "ipfs": this.ipfsService }; var service = services[serviceName]; @@ -50,18 +62,6 @@ Engine.prototype.startService = function(serviceName, _options) { return service.apply(this, [options]); }; -Engine.prototype.monitorService = function(options) { - var servicesMonitor = new ServicesMonitor({ - logger: this.logger, - config: this.config, - serverHost: options.serverHost, - serverPort: options.serverPort, - runWebserver: options.runWebserver, - version: this.version - }); - servicesMonitor.startMonitor(); -}; - Engine.prototype.pipelineService = function(options) { var self = this; this.logger.setStatus("Building Assets"); @@ -134,15 +134,68 @@ Engine.prototype.fileWatchService = function(options) { }; Engine.prototype.webServerService = function(options) { + var self = this; var webServerConfig = this.config.webServerConfig; if (!webServerConfig.enabled) { return; } + + var host = options.host || webServerConfig.host; + var port = options.port || webServerConfig.port; + this.logger.setStatus("Starting Server"); var server = new Server({ logger: this.logger, - host: options.host || webServerConfig.host, - port: options.port || webServerConfig.port + host: host, + port: port + }); + + self.servicesMonitor.addCheck('Webserver', function(cb) { + var devServer = 'Webserver (http://' + host + ':' + port + ')'; + return cb({name: devServer, status: 'green'}); + }); + + server.start(function(){ + }); +}; + +Engine.prototype.ipfsService = function(options) { + var self = this; + self.servicesMonitor.addCheck('IPFS', function(cb) { + + utils.checkIsAvailable('http://localhost:5001', function(available) { + if (available) { + //Ideally this method should be in an IPFS API JSONRPC wrapper + //The URL should also be flexible to accept non-default IPFS url + self.logger.trace("Checking IPFS version..."); + http.get('http://localhost:5001/api/v0/version', function(res) { + var body = ''; + res.on('data', function(d) { + body += d; + }); + res.on('end', function() { + try{ + var parsed = JSON.parse(body); + if(parsed.Version){ + return cb({name: ("IPFS " + parsed.Version), status: 'green'}); + } + else{ + return cb({name: "IPFS ", status: 'green'}); + } + } + catch (e){ + return cb({name: "IPFS ", status: 'red'}); + } + }); + res.on('error', function(err) { + self.logger.trace("Check IPFS version error: " + err); + return cb({name: "IPFS ", status: 'red'}); + }); + }); + } + else { + return cb({name: "IPFS ", status: 'red'}); + } + }); }); - server.start(function(){}); }; module.exports = Engine; diff --git a/lib/core/logger.js b/lib/core/logger.js index 5007977c5..442544a70 100644 --- a/lib/core/logger.js +++ b/lib/core/logger.js @@ -5,7 +5,6 @@ var Logger = function(options) { this.logLevel = options.logLevel || 'info'; this.logFunction = options.logFunction || console.log; this.contractsState = options.contractsState || function() {}; - this.availableServices = options.availableServices || function() {}; this.setStatus = options.setStatus || console.log; }; diff --git a/lib/core/services.js b/lib/core/services.js deleted file mode 100644 index 6d4cce518..000000000 --- a/lib/core/services.js +++ /dev/null @@ -1,119 +0,0 @@ -var Web3 = require('web3'); -var async = require('async'); -var http = require('http'); -var utils = require('./utils.js'); - -// TODO: needs a refactor and be done in a different way -var ServicesMonitor = function(options) { - this.logger = options.logger; - this.interval = options.interval || 5000; - this.config = options.config; - this.serverHost = options.serverHost || 'localhost'; - this.serverPort = options.serverPort || 8000; - this.runWebserver = options.runWebserver; - this.version = options.version; -}; - -ServicesMonitor.prototype.startMonitor = function() { - this.check(); - this.monitor = setInterval(this.check.bind(this), this.interval); -}; - -ServicesMonitor.prototype.stopMonitor = function() { - clearInterval(this.monitor); -}; - -ServicesMonitor.prototype.check = function() { - var self = this; - async.waterfall([ - function connectWeb3(callback) { - self.logger.trace('connectWeb3'); - var web3 = new Web3(); - var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort; - web3.setProvider(new web3.providers.HttpProvider(web3Endpoint)); - callback(null, web3, []); - }, - function addEmbarkVersion(web3, result, callback) { - self.logger.trace('addEmbarkVersion'); - result.push(('Embark ' + self.version).green); - callback(null, web3, result); - }, - function checkEthereum(web3, result, callback) { - self.logger.trace('checkEthereum'); - var service; - if (web3.isConnected()) { - service = (web3.version.node.split("/")[0] + " " + web3.version.node.split("/")[1].split("-")[0] + " (Ethereum)").green; - } else { - service = "No Blockchain node found".red; - } - result.push(service); - callback(null, web3, result); - }, - function checkWhisper(web3, result, callback) { - self.logger.trace('checkWhisper'); - web3.version.getWhisper(function(err, res) { - var service = 'Whisper'; - result.push(err ? service.red : service.green); - callback(null, result); - }); - }, - function checkIPFS(result, callback) { - self.logger.trace('checkIPFS'); - - utils.checkIsAvailable('http://localhost:5001', function(available) { - if (available) { - //Ideally this method should be in an IPFS API JSONRPC wrapper - //The URL should also be flexible to accept non-default IPFS url - self.logger.trace("Checking IPFS version..."); - http.get('http://localhost:5001/api/v0/version', function(res) { - var body = ''; - res.on('data', function(d) { - body += d; - }); - res.on('end', function() { - try{ - var parsed = JSON.parse(body); - if(parsed.Version){ - result.push(("IPFS " + parsed.Version).green); - } - else{ - result.push("IPFS".green); - } - } - catch (e){ - result.push("IPFS".red); - } - callback(null, result); - }); - res.on('error', function(err) { - self.logger.trace("Check IPFS version error: " + err); - result.push("IPFS".red); - callback(null, result); - }); - }); - } - else { - result.push('IPFS'.red); - return callback(null, result); - } - }); - }, - function checkDevServer(result, callback) { - var host = self.serverHost || self.config.webServerConfig.host; - var port = self.serverPort || self.config.webServerConfig.port; - self.logger.trace('checkDevServer'); - var devServer = 'Webserver (http://' + host + ':' + port + ')'; - devServer = (self.runWebserver) ? devServer.green : devServer.red; - result.push(devServer); - callback(null, result); - } - ], function(err, result) { - if (err) { - self.logger.error(err.message); - } else { - self.logger.availableServices(result); - } - }); -}; - -module.exports = ServicesMonitor; diff --git a/lib/core/services_monitor.js b/lib/core/services_monitor.js new file mode 100644 index 000000000..65673a8b3 --- /dev/null +++ b/lib/core/services_monitor.js @@ -0,0 +1,84 @@ +var Web3 = require('web3'); +var async = require('async'); +var http = require('http'); +var utils = require('./utils.js'); + +var ServicesMonitor = function(options) { + this.events = options.events; + this.logger = options.logger; + this.checkList = {}; + this.checkTimers = {}; + this.checkState = {}; +}; + +ServicesMonitor.prototype.addCheck = function(name, checkFn, time) { + this.logger.info('add check'); + // TODO: check if a service with the same name already exists + this.checkList[name] = {fn: checkFn, interval: time || 5000}; +}; + +ServicesMonitor.prototype.startMonitor = function() { + var self = this; + var checkName; + + for (checkName in this.checkList) { + var check = this.checkList[checkName]; + + self.events.on('check:' + checkName, function(obj) { + self.logger.info(JSON.stringify(obj)); + self.checkState[checkName] = obj.name[obj.status]; + self.events.emit("servicesState", self.checkState); + }); + + this.checkTimers[checkName] = setInterval(function() { + check.fn.call(check.fn, function(obj) { + self.events.emit('check:' + checkName, obj); + }); + }, check.interval); + + check.fn.call(check.fn, function(obj) { + self.events.emit('check:' + checkName, obj); + }); + } +}; + +// TODO: old checks to be moved +ServicesMonitor.prototype.check = function() { + var self = this; + async.waterfall([ + function connectWeb3(callback) { + self.logger.trace('connectWeb3'); + var web3 = new Web3(); + var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort; + web3.setProvider(new web3.providers.HttpProvider(web3Endpoint)); + callback(null, web3, []); + }, + function checkEthereum(web3, result, callback) { + self.logger.trace('checkEthereum'); + var service; + if (web3.isConnected()) { + service = (web3.version.node.split("/")[0] + " " + web3.version.node.split("/")[1].split("-")[0] + " (Ethereum)").green; + } else { + service = "No Blockchain node found".red; + } + result.push(service); + callback(null, web3, result); + }, + function checkWhisper(web3, result, callback) { + self.logger.trace('checkWhisper'); + web3.version.getWhisper(function(err, res) { + var service = 'Whisper'; + result.push(err ? service.red : service.green); + callback(null, result); + }); + } + ], function(err, result) { + if (err) { + self.logger.error(err.message); + } else { + self.logger.availableServices(result); + } + }); +}; + +module.exports = ServicesMonitor; diff --git a/lib/dashboard/dashboard.js b/lib/dashboard/dashboard.js index d67b142d0..367b77b85 100644 --- a/lib/dashboard/dashboard.js +++ b/lib/dashboard/dashboard.js @@ -23,7 +23,6 @@ Dashboard.prototype.start = function(done) { monitor = new Monitor({env: self.env, console: console}); self.logger.logFunction = monitor.logEntry; self.logger.contractsState = monitor.setContracts; - self.logger.availableServices = monitor.availableServices; self.logger.setStatus = monitor.setStatus.bind(monitor); self.logger.info('========================'.bold.green); diff --git a/lib/dashboard/monitor.js b/lib/dashboard/monitor.js index 210fa7cec..c1ce4c8de 100644 --- a/lib/dashboard/monitor.js +++ b/lib/dashboard/monitor.js @@ -40,7 +40,15 @@ function Dashboard(options) { this.input.focus(); } -Dashboard.prototype.availableServices = function(services) { +Dashboard.prototype.availableServices = function(_services) { + var services = []; + var checkName; + for (checkName in _services) { + services.push(_services[checkName]); + } + + console.log(services); + this.progress.setContent(services.join('\n')); this.screen.render(); }; diff --git a/lib/index.js b/lib/index.js index 6b358d23b..926dc6e1d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -90,6 +90,12 @@ var Embark = { dashboard.console.runCode(abi); }); + engine.logger.info('dashboard start'); + engine.events.on('servicesState', function(servicesState) { + engine.logger.info('servicesState event'); + dashboard.monitor.availableServices(servicesState); + }); + callback(); }); }, @@ -99,16 +105,10 @@ var Embark = { engine.logger.info("loaded plugins: " + pluginList.join(", ")); } - if (options.useDashboard) { - engine.startService("monitor", { - serverHost: options.serverHost, - serverPort: options.serverPort, - runWebserver: options.runWebserver - }); - } engine.startService("pipeline"); engine.startService("abi"); engine.startService("deployment"); + engine.startService("ipfs"); engine.deployManager.deployContracts(function() { engine.startService("fileWatcher"); @@ -118,6 +118,7 @@ var Embark = { port: options.serverPort }); } + engine.startMonitor(); callback(); }); }