2018-05-28 12:59:18 +00:00
2018-06-01 03:12:17 +00:00
const utils = require ( '../../utils/utils.js' ) ;
const fs = require ( '../../core/fs.js' ) ;
const _ = require ( 'underscore' ) ;
const async = require ( 'async' ) ;
const StorageProcessesLauncher = require ( '../../processes/storageProcesses/storageProcessesLauncher' ) ;
const constants = require ( '../../constants' ) ;
2018-05-28 12:59:18 +00:00
2018-07-07 16:29:04 +00:00
const IpfsModule = require ( '../ipfs' ) ;
const SwarmModule = require ( '../swarm' ) ;
2018-05-28 12:59:18 +00:00
class Storage {
2018-06-01 03:12:17 +00:00
constructor ( embark , options ) {
2018-07-07 15:11:45 +00:00
const self = this ;
2018-06-01 03:12:17 +00:00
this . _embark = embark ;
this . _options = options ;
this . _storageConfig = options . storageConfig ;
this . _webServerConfig = options . webServerConfig ;
this . _blockchainConfig = options . blockchainConfig ;
this . _servicesMonitor = options . servicesMonitor ;
this . _events = options . events ;
this . _logger = options . logger ;
2018-05-30 06:34:36 +00:00
2018-07-07 16:29:04 +00:00
if ( ! this . _storageConfig . enabled ) return ;
2018-06-26 04:18:55 +00:00
2018-07-07 16:29:04 +00:00
// // filter list of dapp connections based on available_providers set in config
// let hasSwarm = _.contains(this._storageConfig.available_providers, 'swarm'); // don't need to eval this in every loop iteration
// // contains valid dapp storage providers
// this._validDappProviders = _.filter(this._storageConfig.dappConnection, (conn) => {
// return _.contains(this._storageConfig.available_providers, conn.provider) || (conn === '$BZZ' && hasSwarm);
// });
2018-05-30 06:34:36 +00:00
2018-07-07 16:29:04 +00:00
// this.initStorageForEmbark();
// this.initStorageForDapp();
2018-05-28 12:59:18 +00:00
2018-07-07 16:29:04 +00:00
// // don't start storage processes on build command, only on upload or run
// if(_.contains(options.context, constants.contexts.upload) || _.contains(options.context, constants.contexts.run)){
// this.startStorageProcesses();
// }
new IpfsModule ( embark , options ) ; /*eslint no-new: "off"*/
new SwarmModule ( embark , options ) ; /*eslint no-new: "off"*/
2018-07-07 15:11:45 +00:00
embark . events . setCommandHandler ( 'storage:upload' , ( cb ) => {
let platform = options . storageConfig . upload . provider ;
if ( [ 'swarm' , 'ipfs' ] . indexOf ( platform ) === - 1 ) {
return cb ( { message : _ _ ( 'platform "{{platform}}" is specified as the upload provider, however no plugins have registered an upload command for "{{platform}}".' , { platform : platform } ) } ) ;
}
} ) ;
2018-06-01 03:12:17 +00:00
}
2018-05-30 06:34:36 +00:00
2018-06-01 03:12:17 +00:00
_checkStorageEndpoint ( platform , callback ) {
let checkFn ;
let self = this ;
self . _logger . trace ( ` Storage module: Checking ${ platform } availability... ` ) ;
_ . find ( self . _servicesMonitor . checkList , ( value , key ) => {
if ( key . toLowerCase ( ) === platform . toLowerCase ( ) ) {
checkFn = value ;
return true ;
}
} ) ;
if ( ! checkFn || typeof checkFn . fn !== 'function' ) {
self . _logger . trace ( ` Storage module: Check for ${ platform } node does not exist. ` ) ;
return callback ( ) ;
}
2018-05-28 12:59:18 +00:00
2018-06-01 03:12:17 +00:00
checkFn . fn ( function ( serviceCheckResult ) {
if ( ! serviceCheckResult . status || serviceCheckResult . status === 'off' ) {
self . _logger . trace ( ` Storage module: ${ platform } node not available. ` ) ;
return callback ( 'No node' ) ;
}
callback ( ) ;
} ) ;
}
2018-07-07 16:29:04 +00:00
2018-06-01 03:12:17 +00:00
_startStorageNode ( platform , callback ) {
let self = this ;
const storageProcessesLauncher = new StorageProcessesLauncher ( {
logger : self . _logger ,
events : self . _events ,
storageConfig : self . _storageConfig ,
webServerConfig : self . _webServerConfig ,
blockchainConfig : self . _blockchainConfig
} ) ;
self . _logger . trace ( ` Storage module: Launching ${ platform } process... ` ) ;
return storageProcessesLauncher . launchProcess ( platform . toLowerCase ( ) , ( err ) => {
if ( err ) {
return callback ( err ) ;
}
callback ( ) ;
} ) ;
}
2018-05-30 06:34:36 +00:00
2018-06-01 03:12:17 +00:00
/ * *
* Initializes a storage provider for EmbarkJS
*
* @ return { void }
* /
initStorageForDapp ( ) {
// now we need to add instantiate any dappConnection/available_providers storage providers to add
// their provider code to embarkjs
this . _validDappProviders . forEach ( dappConn => {
if ( ! dappConn . provider ) return ;
let storageProviderCls = require ( ` ../ ${ dappConn . provider } /index.js ` ) ;
// override options with dappConnection settings
let storageOptions = this . _options ;
storageOptions . protocol = dappConn . protocol ;
storageOptions . host = dappConn . host ;
storageOptions . port = dappConn . port ;
// then instantiate the storage provdier class
let storageProvider = new storageProviderCls ( this . _embark , storageOptions ) ; /*eslint no-new: "off"*/
// register the service check so we can use it to check if the process is running before spawning it
// check that it hasn't already been done above
if ( dappConn . provider !== this . _storageConfig . upload . provider ) {
if ( typeof storageProvider . setServiceCheck == 'function' ) storageProvider . setServiceCheck ( ) ;
}
// add __embarkSwarm and __embarkIPFS objects to EmbarkJS
if ( typeof storageProvider . addProviderToEmbarkJS == 'function' ) storageProvider . addProviderToEmbarkJS ( ) ;
} ) ;
// add the code to call setProviders in embarkjs after embark is ready
this . addSetProviders ( ) ;
}
/ * *
* Adds the code to call setProviders in embarkjs after embark is ready
*
* @ returns { void }
* /
addSetProviders ( ) {
2018-07-07 15:29:45 +00:00
let code = ` \n EmbarkJS.Storage.setProviders( ${ JSON . stringify ( this . _validDappProviders ) } ); ` ;
2018-06-01 03:12:17 +00:00
let shouldInit = ( storageConfig ) => {
return ( this . _validDappProviders !== undefined && this . _validDappProviders . length > 0 && storageConfig . enabled === true ) ;
} ;
this . _embark . addProviderInit ( 'storage' , code , shouldInit ) ;
}
2018-06-01 16:53:23 +00:00
checkStorageService ( platform , url , callback ) {
const self = this ;
// start the upload storage node
self . _checkStorageEndpoint ( platform , function ( err ) {
if ( ! err ) {
2018-06-15 06:35:05 +00:00
return callback ( null ) ;
2018-06-01 16:53:23 +00:00
}
self . _startStorageNode ( platform , ( err ) => {
if ( err ) {
2018-06-15 06:35:05 +00:00
return callback ( err ) ;
2018-06-01 16:53:23 +00:00
}
// Check endpoint again to see if really did start
self . _checkStorageEndpoint ( platform , ( err ) => {
if ( err ) {
2018-06-15 06:35:05 +00:00
return callback ( err ) ;
2018-06-01 16:53:23 +00:00
}
2018-06-15 06:35:05 +00:00
callback ( null ) ;
2018-06-01 16:53:23 +00:00
} ) ;
} ) ;
} ) ;
}
2018-06-01 03:12:17 +00:00
startStorageProcesses ( ) {
let platform = this . _storageConfig . upload . provider ;
let self = this ;
2018-06-15 06:35:05 +00:00
let withErrors = false ;
2018-06-01 03:12:17 +00:00
async . waterfall ( [
2018-06-01 16:53:23 +00:00
function _checkStorageService ( callback ) {
2018-06-15 06:35:05 +00:00
self . checkStorageService ( platform , utils . buildUrlFromConfig ( self . _storageConfig . upload ) , ( err ) => {
// log error and continue
if ( err ) {
self . _logger . error ( err ) ;
withErrors = true ;
}
callback ( null ) ;
} ) ;
2018-06-01 03:12:17 +00:00
} ,
function checkDappConnectionStorageService ( callback ) {
// start any dappConnection storage nodes
2018-06-15 06:35:05 +00:00
async . each ( self . _validDappProviders , function ( dappConn , cb ) {
if ( ! dappConn . provider || dappConn . provider === platform ) {
return cb ( null ) ;
} // don't start the process we've just started above
self . checkStorageService ( dappConn . provider , utils . buildUrlFromConfig ( dappConn ) , ( err ) => {
// log error and continue
if ( err ) {
self . _logger . error ( err ) ;
withErrors = true ;
}
cb ( null ) ;
} ) ;
} , callback ) ;
}
] , function ( ) {
let strComplete = _ _ ( 'Finished starting all storage providers' ) ;
if ( withErrors ) {
strComplete += ', ' + _ _ ( 'with errors.' ) ;
return self . _logger . warn ( strComplete ) ;
2018-06-01 03:12:17 +00:00
}
2018-06-15 06:35:05 +00:00
self . _logger . info ( strComplete + '.' ) ;
} ) ;
2018-06-01 03:12:17 +00:00
}
2018-05-28 12:59:18 +00:00
}
module . exports = Storage ;