diff --git a/app/middleware/auth-check.js b/app/middleware/auth-check.js index 6f8cc66b2..815bcf666 100644 --- a/app/middleware/auth-check.js +++ b/app/middleware/auth-check.js @@ -26,9 +26,10 @@ module.exports = (req, res, next) => { return res.status(401).end(); } - const userId = decoded.sub; + const userId = decoded.user; req.userId = userId; + req.network = decoded.network; // TODO: check if a user exists, otherwise error diff --git a/app/passport/local-login.js b/app/passport/local-login.js index 8818a7797..a632581bb 100644 --- a/app/passport/local-login.js +++ b/app/passport/local-login.js @@ -35,7 +35,8 @@ const strategy = function(platform) { const userInfo = await proxy.authenticate(reqUser); const payload = { - sub: userInfo.user + user: userInfo.user, + network: userInfo.network }; if (userInfo && !userInfo.authenticated) { @@ -53,7 +54,8 @@ const strategy = function(platform) { // @ts-check const data = { message: 'logged in', - name: userData.user + name: userData.user, + network: userData.network }; return done(null, token, data); diff --git a/app/persistence/fabric/CRUDService.js b/app/persistence/fabric/CRUDService.js index 8602c0720..8c4196753 100644 --- a/app/persistence/fabric/CRUDService.js +++ b/app/persistence/fabric/CRUDService.js @@ -25,9 +25,9 @@ class CRUDService { * @memberof CRUDService */ - getTxCountByBlockNum(channel_genesis_hash, blockNum) { + getTxCountByBlockNum(network_name, channel_genesis_hash, blockNum) { return this.sql.getRowByPkOne( - `select blocknum ,txcount from blocks where channel_genesis_hash='${channel_genesis_hash}' and blocknum=${blockNum} ` + `select blocknum ,txcount from blocks where channel_genesis_hash='${channel_genesis_hash}' and blocknum=${blockNum} and network_name = '${network_name}' ` ); } @@ -39,9 +39,10 @@ class CRUDService { * @returns * @memberof CRUDService */ - getTransactionByID(channel_genesis_hash, txhash) { + getTransactionByID(network_name, channel_genesis_hash, txhash) { const sqlTxById = ` select t.txhash,t.validation_code,t.payload_proposal_hash,t.creator_msp_id,t.endorser_msp_id,t.chaincodename,t.type,t.createdt,t.read_set, - t.write_set,channel.name as channelName from TRANSACTIONS as t inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash where t.txhash = '${txhash}' `; + t.write_set,channel.name as channelName from TRANSACTIONS as t inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash and t.network_name=channel.network_name + where t.txhash = '${txhash}' and t.network_name = '${network_name}' `; return this.sql.getRowByPkOne(sqlTxById); } @@ -53,12 +54,12 @@ class CRUDService { * @memberof CRUDService */ - getBlockActivityList(channel_genesis_hash) { + getBlockActivityList(network_name, channel_genesis_hash) { const sqlBlockActivityList = `select blocks.blocknum,blocks.txcount ,blocks.datahash ,blocks.blockhash ,blocks.prehash,blocks.createdt, ( SELECT array_agg(txhash) as txhash FROM transactions where blockid = blocks.blocknum and - channel_genesis_hash = '${channel_genesis_hash}' group by transactions.blockid ), + channel_genesis_hash = '${channel_genesis_hash}' and network_name = '${network_name}' group by transactions.blockid ), channel.name as channelname from blocks inner join channel on blocks.channel_genesis_hash = channel.channel_genesis_hash where - blocks.channel_genesis_hash ='${channel_genesis_hash}' and blocknum >= 0 + blocks.channel_genesis_hash ='${channel_genesis_hash}' and blocknum >= 0 and blocks.network_name = '${network_name}' order by blocks.blocknum desc limit 3`; return this.sql.getRowsBySQlQuery(sqlBlockActivityList); } @@ -75,22 +76,21 @@ class CRUDService { * @returns * @memberof CRUDService */ - getTxList(channel_genesis_hash, blockNum, txid, from, to, orgs) { + getTxList(network_name, channel_genesis_hash, blockNum, txid, from, to, orgs) { let byOrgs = false; if (orgs && orgs !== '') { byOrgs = true; } - logger.debug('getTxList.byOrgs ', byOrgs); logger.debug('getTxList.byOrgs ', byOrgs); const sqlTxListByOrgs = ` select t.creator_msp_id,t.txhash,t.type,t.chaincodename,t.createdt,channel.name as channelName from transactions as t - inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash where t.blockid >= ${blockNum} and t.id >= ${txid} and t.creator_msp_id in (${orgs}) and - t.channel_genesis_hash = '${channel_genesis_hash}' and t.createdt between '${from}' and '${to}' order by t.id desc`; + inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash and t.network_name = channel.network_name where t.blockid >= ${blockNum} and t.id >= ${txid} and t.creator_msp_id in (${orgs}) and + t.channel_genesis_hash = '${channel_genesis_hash}' and t.network_name = '${network_name}' and t.createdt between '${from}' and '${to}' order by t.id desc`; const sqlTxList = ` select t.creator_msp_id,t.txhash,t.type,t.chaincodename,t.createdt,channel.name as channelName from transactions as t - inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash where t.blockid >= ${blockNum} and t.id >= ${txid} and - t.channel_genesis_hash = '${channel_genesis_hash}' and t.createdt between '${from}' and '${to}' order by t.id desc`; + inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash and t.network_name = channel.network_name where t.blockid >= ${blockNum} and t.id >= ${txid} and + t.channel_genesis_hash = '${channel_genesis_hash}' and t.network_name = '${network_name}' and t.createdt between '${from}' and '${to}' order by t.id desc`; if (byOrgs) { return this.sql.getRowsBySQlQuery(sqlTxListByOrgs); @@ -110,35 +110,46 @@ class CRUDService { * @returns * @memberof CRUDService */ - getBlockAndTxList(channel_genesis_hash, blockNum, from, to, orgs) { + getBlockAndTxList( + network_name, + channel_genesis_hash, + blockNum, + from, + to, + orgs + ) { let byOrgs = false; // workaround for SQL injection if (orgs && orgs !== '') { byOrgs = true; } - logger.debug('getBlockAndTxList.byOrgs ', byOrgs); logger.debug('getBlockAndTxList.byOrgs ', byOrgs); const sqlBlockTxList = `select a.* from ( select (select c.name from channel c where c.channel_genesis_hash = - '${channel_genesis_hash}' ) as channelname, blocks.blocknum,blocks.txcount ,blocks.datahash ,blocks.blockhash ,blocks.prehash,blocks.createdt, blocks.blksize, ( + '${channel_genesis_hash}' and c.network_name = '${network_name}') as channelname, blocks.blocknum,blocks.txcount ,blocks.datahash ,blocks.blockhash ,blocks.prehash,blocks.createdt, blocks.blksize, ( SELECT array_agg(txhash) as txhash FROM transactions where blockid = blocks.blocknum and - channel_genesis_hash = '${channel_genesis_hash}' and createdt between '${from}' and '${to}') from blocks where - blocks.channel_genesis_hash ='${channel_genesis_hash}' and blocknum >= 0 and blocks.createdt between '${from}' and '${to}' + channel_genesis_hash = '${channel_genesis_hash}' and network_name = '${network_name}' and createdt between '${from}' and '${to}') from blocks where + blocks.channel_genesis_hash ='${channel_genesis_hash}' and blocks.network_name = '${network_name}' and blocknum >= 0 and blocks.createdt between '${from}' and '${to}' order by blocks.blocknum desc) a where a.txhash IS NOT NULL`; + logger.debug('sqlBlockTxList ', sqlBlockTxList); + const sqlBlockTxListByOrgs = `select a.* from ( select (select c.name from channel c where c.channel_genesis_hash = - '${channel_genesis_hash}' ) as channelname, blocks.blocknum,blocks.txcount ,blocks.datahash ,blocks.blockhash ,blocks.prehash,blocks.createdt, blocks.blksize, ( + '${channel_genesis_hash}' and c.network_name = '${network_name}' ) as channelname, blocks.blocknum,blocks.txcount ,blocks.datahash ,blocks.blockhash ,blocks.prehash,blocks.createdt, blocks.blksize, ( SELECT array_agg(txhash) as txhash FROM transactions where blockid = blocks.blocknum and creator_msp_id in (${orgs}) and - channel_genesis_hash = '${channel_genesis_hash}' and createdt between '${from}' and '${to}') from blocks where - blocks.channel_genesis_hash ='${channel_genesis_hash}' and blocknum >= 0 and blocks.createdt between '${from}' and '${to}' + channel_genesis_hash = '${channel_genesis_hash}' and network_name = '${network_name}' and createdt between '${from}' and '${to}') from blocks where + blocks.channel_genesis_hash ='${channel_genesis_hash}' and blocks.network_name = '${network_name}' and blocknum >= 0 and blocks.createdt between '${from}' and '${to}' order by blocks.blocknum desc) a where a.txhash IS NOT NULL`; if (byOrgs) { return this.sql.getRowsBySQlQuery(sqlBlockTxListByOrgs); } - return this.sql.getRowsBySQlQuery(sqlBlockTxList); + const ret = this.sql.getRowsBySQlQuery(sqlBlockTxList); + logger.debug('Finished sqlBlockTxList ', ret); + + return ret; } /** @@ -149,9 +160,9 @@ class CRUDService { * @memberof CRUDService */ - async getChannelConfig(channel_genesis_hash) { + async getChannelConfig(network_name, channel_genesis_hash) { const channelConfig = await this.sql.getRowsBySQlCase( - ` select * from channel where channel_genesis_hash ='${channel_genesis_hash}' ` + ` select * from channel where channel_genesis_hash ='${channel_genesis_hash}' and network_name = '${network_name}' ` ); return channelConfig; } @@ -164,9 +175,9 @@ class CRUDService { * @returns * @memberof CRUDService */ - async getChannel(channelname, channel_genesis_hash) { + async getChannel(network_name, channelname, channel_genesis_hash) { const channel = await this.sql.getRowsBySQlCase( - ` select * from channel where name='${channelname}' and channel_genesis_hash='${channel_genesis_hash}' ` + ` select * from channel where name='${channelname}' and channel_genesis_hash='${channel_genesis_hash}' and network_name = '${network_name}' ` ); return channel; } @@ -177,9 +188,9 @@ class CRUDService { * @returns * @memberof CRUDService */ - async existChannel(channelname) { + async existChannel(network_name, channelname) { const channel = await this.sql.getRowsBySQlCase( - ` select count(1) from channel where name='${channelname}' ` + ` select count(1) from channel where name='${channelname}' and network_name = '${network_name}' ` ); return channel; } @@ -193,21 +204,24 @@ class CRUDService { */ /* eslint-disable */ - async saveBlock(block) { + async saveBlock(network_name, block) { const c = await this.sql .getRowByPkOne(`select count(1) as c from blocks where blocknum='${ block.blocknum }' and txcount='${block.txcount}' - and channel_genesis_hash='${block.channel_genesis_hash}' and prehash='${ + and channel_genesis_hash='${ + block.channel_genesis_hash + }' and network_name = '${network_name}' and prehash='${ block.prehash }' and datahash='${block.datahash}' `); if (isValidRow(c)) { + block.network_name = network_name; await this.sql.saveRow('blocks', block); await this.sql.updateBySql( `update channel set blocks =blocks+1 where channel_genesis_hash='${ block.channel_genesis_hash - }'` + }' and network_name = '${network_name}' ` ); return true; } @@ -224,13 +238,13 @@ class CRUDService { * @returns * @memberof CRUDService */ - async saveTransaction(transaction) { + async saveTransaction(network_name, transaction) { const c = await this.sql.getRowByPkOne( `select count(1) as c from transactions where blockid='${ transaction.blockid }' and txhash='${transaction.txhash}' and channel_genesis_hash='${ transaction.channel_genesis_hash - }'` + }' and network_name = '${network_name}' ` ); if (isValidRow(c)) { @@ -238,12 +252,14 @@ class CRUDService { await this.sql.updateBySql( `update chaincodes set txcount =txcount+1 where channel_genesis_hash='${ transaction.channel_genesis_hash - }' and name='${transaction.chaincodename}'` + }' and network_name = '${network_name}' and name='${ + transaction.chaincodename + }'` ); await this.sql.updateBySql( `update channel set trans =trans+1 where channel_genesis_hash='${ transaction.channel_genesis_hash - }'` + }' and network_name = '${network_name}' ` ); return true; } @@ -258,11 +274,11 @@ class CRUDService { * @returns * @memberof CRUDService */ - async getCurBlockNum(channel_genesis_hash) { + async getCurBlockNum(network_name, channel_genesis_hash) { let curBlockNum; try { const row = await this.sql.getRowsBySQlCase( - `select max(blocknum) as blocknum from blocks where channel_genesis_hash='${channel_genesis_hash}'` + `select max(blocknum) as blocknum from blocks where channel_genesis_hash='${channel_genesis_hash}' and network_name = '${network_name}' ` ); if (row && row.blocknum) { @@ -285,16 +301,19 @@ class CRUDService { * @param {*} chaincode * @memberof CRUDService */ - async saveChaincode(chaincode) { + async saveChaincode(network_name, chaincode) { const c = await this.sql .getRowByPkOne(`select count(1) as c from chaincodes where name='${ chaincode.name }' and - channel_genesis_hash='${chaincode.channel_genesis_hash}' and version='${ + channel_genesis_hash='${ + chaincode.channel_genesis_hash + }' and network_name = '${network_name}' and version='${ chaincode.version }' and path='${chaincode.path}'`); if (isValidRow(c)) { + chaincode.network_name = network_name; await this.sql.saveRow('chaincodes', chaincode); } } @@ -307,9 +326,9 @@ class CRUDService { * @returns * @memberof CRUDService */ - getChannelByGenesisBlockHash(channel_genesis_hash) { + getChannelByGenesisBlockHash(network_name, channel_genesis_hash) { return this.sql.getRowByPkOne( - `select name from channel where channel_genesis_hash='${channel_genesis_hash}'` + `select name from channel where channel_genesis_hash='${channel_genesis_hash}' and network_name = '${network_name}' ` ); } @@ -319,7 +338,7 @@ class CRUDService { * @param {*} peers_ref_chaincode * @memberof CRUDService */ - async saveChaincodPeerRef(peers_ref_chaincode) { + async saveChaincodPeerRef(network_name, peers_ref_chaincode) { const c = await this.sql.getRowByPkOne( `select count(1) as c from peer_ref_chaincode prc where prc.peerid= '${ peers_ref_chaincode.peerid @@ -327,10 +346,11 @@ class CRUDService { peers_ref_chaincode.chaincodeid }' and cc_version='${peers_ref_chaincode.cc_version}' and channelid='${ peers_ref_chaincode.channelid - }'` + }' and network_name = '${network_name}' ` ); if (isValidRow(c)) { + peers_ref_chaincode.network_name = network_name; await this.sql.saveRow('peer_ref_chaincode', peers_ref_chaincode); } } @@ -341,11 +361,13 @@ class CRUDService { * @param {*} channel * @memberof CRUDService */ - async saveChannel(channel) { + async saveChannel(network_name, channel) { const c = await this.sql.getRowByPkOne( `select count(1) as c from channel where name='${ channel.name - }' and channel_genesis_hash='${channel.channel_genesis_hash}'` + }' and channel_genesis_hash='${ + channel.channel_genesis_hash + }' and network_name = '${network_name}' ` ); if (isValidRow(c)) { @@ -355,7 +377,8 @@ class CRUDService { blocks: channel.blocks, trans: channel.trans, channel_hash: channel.channel_hash, - channel_genesis_hash: channel.channel_genesis_hash + channel_genesis_hash: channel.channel_genesis_hash, + network_name: network_name }); } else { await this.sql.updateBySql( @@ -363,7 +386,9 @@ class CRUDService { channel.trans }',channel_hash='${channel.channel_hash}' where name='${ channel.name - }'and channel_genesis_hash='${channel.channel_genesis_hash}'` + }'and channel_genesis_hash='${ + channel.channel_genesis_hash + }' and network_name = '${network_name}' ` ); } } @@ -374,14 +399,17 @@ class CRUDService { * @param {*} peer * @memberof CRUDService */ - async savePeer(peer) { + async savePeer(network_name, peer) { const c = await this.sql.getRowByPkOne( `select count(1) as c from peer where channel_genesis_hash='${ peer.channel_genesis_hash - }' and server_hostname='${peer.server_hostname}' ` + }' and network_name = '${network_name}' and server_hostname='${ + peer.server_hostname + }' ` ); if (isValidRow(c)) { + peer.network_name = network_name; await this.sql.saveRow('peer', peer); } } @@ -392,14 +420,17 @@ class CRUDService { * @param {*} peers_ref_Channel * @memberof CRUDService */ - async savePeerChannelRef(peers_ref_Channel) { + async savePeerChannelRef(network_name, peers_ref_Channel) { const c = await this.sql.getRowByPkOne( `select count(1) as c from peer_ref_channel prc where prc.peerid = '${ peers_ref_Channel.peerid - }' and prc.channelid='${peers_ref_Channel.channelid}' ` + }' and network_name = '${network_name}' and prc.channelid='${ + peers_ref_Channel.channelid + }' ` ); if (isValidRow(c)) { + peers_ref_Channel.network_name = network_name; await this.sql.saveRow('peer_ref_channel', peers_ref_Channel); } } @@ -411,10 +442,10 @@ class CRUDService { * @returns * @memberof CRUDService */ - async getChannelsInfo(peerid) { + async getChannelsInfo(network_name, peerid) { const channels = await this.sql .getRowsBySQlNoCondition(` select c.id as id,c.name as channelName,c.blocks as blocks ,c.channel_genesis_hash as channel_genesis_hash,c.trans as transactions,c.createdt as createdat,c.channel_hash as channel_hash from channel c, - peer_ref_channel pc where c.channel_genesis_hash = pc.channelid and pc.peerid='${peerid}' group by c.id ,c.name ,c.blocks ,c.trans ,c.createdt ,c.channel_hash,c.channel_genesis_hash order by c.name `); + peer_ref_channel pc where c.channel_genesis_hash = pc.channelid and c.network_name = '${network_name}' and pc.peerid='${peerid}' group by c.id ,c.name ,c.blocks ,c.trans ,c.createdt ,c.channel_hash,c.channel_genesis_hash order by c.name `); return channels; } @@ -426,11 +457,14 @@ class CRUDService { * @param {*} orderer * @memberof CRUDService */ - async saveOrderer(orderer) { + async saveOrderer(network_name, orderer) { const c = await this.sql.getRowByPkOne( - `select count(1) as c from orderer where requests='${orderer.requests}' ` + `select count(1) as c from orderer where requests='${ + orderer.requests + }' and network_name = '${network_name}' ` ); if (isValidRow(c)) { + orderer.network_name = network_name; await this.sql.saveRow('orderer', orderer); } } diff --git a/app/persistence/fabric/MetricService.js b/app/persistence/fabric/MetricService.js index ee83c9e72..948306f79 100644 --- a/app/persistence/fabric/MetricService.js +++ b/app/persistence/fabric/MetricService.js @@ -23,9 +23,9 @@ class MetricService { * @returns * @memberof MetricService */ - getChaincodeCount(channel_genesis_hash) { + getChaincodeCount(network_name, channel_genesis_hash) { return this.sql.getRowsBySQlCase( - `select count(1) c from chaincodes where channel_genesis_hash='${channel_genesis_hash}' ` + `select count(1) c from chaincodes where channel_genesis_hash='${channel_genesis_hash}' and network_name='${network_name}' ` ); } @@ -36,9 +36,9 @@ class MetricService { * @returns * @memberof MetricService */ - getPeerlistCount(channel_genesis_hash) { + getPeerlistCount(network_name, channel_genesis_hash) { return this.sql.getRowsBySQlCase( - `select count(1) c from peer where channel_genesis_hash='${channel_genesis_hash}' and peer_type='PEER' ` + `select count(1) c from peer where channel_genesis_hash='${channel_genesis_hash}' and peer_type='PEER' and network_name='${network_name}' ` ); } @@ -49,9 +49,9 @@ class MetricService { * @returns * @memberof MetricService */ - getTxCount(channel_genesis_hash) { + getTxCount(network_name, channel_genesis_hash) { return this.sql.getRowsBySQlCase( - `select count(1) c from transactions where channel_genesis_hash='${channel_genesis_hash}'` + `select count(1) c from transactions where channel_genesis_hash='${channel_genesis_hash}' and network_name='${network_name}' ` ); } @@ -62,9 +62,9 @@ class MetricService { * @returns * @memberof MetricService */ - getBlockCount(channel_genesis_hash) { + getBlockCount(network_name, channel_genesis_hash) { return this.sql.getRowsBySQlCase( - `select count(1) c from blocks where channel_genesis_hash='${channel_genesis_hash}'` + `select count(1) c from blocks where channel_genesis_hash='${channel_genesis_hash}' and network_name='${network_name}' ` ); } @@ -75,12 +75,12 @@ class MetricService { * @returns * @memberof MetricService */ - async getPeerData(channel_genesis_hash) { + async getPeerData(network_name, channel_genesis_hash) { const peerArray = []; const c1 = await this.sql .getRowsBySQlNoCondition(`select channel.name as channelName,c.requests as requests,c.channel_genesis_hash as channel_genesis_hash , c.server_hostname as server_hostname, c.mspid as mspid, c.peer_type as peer_type from peer as c inner join channel on - c.channel_genesis_hash=channel.channel_genesis_hash where c.channel_genesis_hash='${channel_genesis_hash}'`); + c.channel_genesis_hash=channel.channel_genesis_hash where c.channel_genesis_hash='${channel_genesis_hash}' and c.network_name='${network_name}' `); for (let i = 0, len = c1.length; i < len; i++) { const item = c1[i]; peerArray.push({ @@ -101,10 +101,10 @@ class MetricService { * @returns * @memberof MetricService */ - async getOrdererData() { + async getOrdererData(network_name) { const ordererArray = []; const c1 = await this.sql.getRowsBySQlNoCondition( - 'select c.requests as requests,c.server_hostname as server_hostname,c.channel_genesis_hash as channel_genesis_hash from orderer c' + `select c.requests as requests,c.server_hostname as server_hostname,c.channel_genesis_hash as channel_genesis_hash from orderer c where network_name='${network_name}' ` ); for (let i = 0, len = c1.length; i < len; i++) { const item = c1[i]; @@ -124,11 +124,11 @@ class MetricService { * @returns * @memberof MetricService */ - async getTxPerChaincodeGenerate(channel_genesis_hash) { + async getTxPerChaincodeGenerate(network_name, channel_genesis_hash) { const txArray = []; const c = await this.sql .getRowsBySQlNoCondition(`select c.name as chaincodename,channel.name as channelname ,c.version as version,c.channel_genesis_hash - as channel_genesis_hash,c.path as path ,txcount as c from chaincodes as c inner join channel on c.channel_genesis_hash=channel.channel_genesis_hash where c.channel_genesis_hash='${channel_genesis_hash}' `); + as channel_genesis_hash,c.path as path ,txcount as c from chaincodes as c inner join channel on c.channel_genesis_hash=channel.channel_genesis_hash where c.channel_genesis_hash='${channel_genesis_hash}' and c.network_name='${network_name}' `); if (c) { c.forEach((item, index) => { logger.debug(' item ------------> ', item); @@ -152,10 +152,10 @@ class MetricService { * @returns * @memberof MetricService */ - async getOrgsData(channel_genesis_hash) { + async getOrgsData(network_name, channel_genesis_hash) { const orgs = []; const rows = await this.sql.getRowsBySQlNoCondition( - `select distinct on (mspid) mspid from peer where channel_genesis_hash='${channel_genesis_hash}'` + `select distinct on (mspid) mspid from peer where channel_genesis_hash='${channel_genesis_hash}' and network_name='${network_name}'` ); for (let i = 0, len = rows.length; i < len; i++) { orgs.push(rows[i].mspid); @@ -171,9 +171,12 @@ class MetricService { * @returns * @memberof MetricService */ - async getTxPerChaincode(channel_genesis_hash, cb) { + async getTxPerChaincode(network_name, channel_genesis_hash, cb) { try { - const txArray = await this.getTxPerChaincodeGenerate(channel_genesis_hash); + const txArray = await this.getTxPerChaincodeGenerate( + network_name, + channel_genesis_hash + ); return cb(txArray); } catch (err) { logger.error(err); @@ -188,22 +191,28 @@ class MetricService { * @returns * @memberof MetricService */ - async getStatusGenerate(channel_genesis_hash) { - let chaincodeCount = await this.getChaincodeCount(channel_genesis_hash); + async getStatusGenerate(network_name, channel_genesis_hash) { + let chaincodeCount = await this.getChaincodeCount( + network_name, + channel_genesis_hash + ); if (!chaincodeCount) { chaincodeCount = 0; } - let txCount = await this.getTxCount(channel_genesis_hash); + let txCount = await this.getTxCount(network_name, channel_genesis_hash); if (!txCount) { txCount = 0; } txCount.c = txCount.c ? txCount.c : 0; - let blockCount = await this.getBlockCount(channel_genesis_hash); + let blockCount = await this.getBlockCount(network_name, channel_genesis_hash); if (!blockCount) { blockCount = 0; } blockCount.c = blockCount.c ? blockCount.c : 0; - let peerCount = await this.getPeerlistCount(channel_genesis_hash); + let peerCount = await this.getPeerlistCount( + network_name, + channel_genesis_hash + ); if (!peerCount) { peerCount = 0; } @@ -224,9 +233,12 @@ class MetricService { * @returns * @memberof MetricService */ - async getStatus(channel_genesis_hash, cb) { + async getStatus(network_name, channel_genesis_hash, cb) { try { - const data = await this.getStatusGenerate(channel_genesis_hash); + const data = await this.getStatusGenerate( + network_name, + channel_genesis_hash + ); return cb(data); } catch (err) { logger.error(err); @@ -242,9 +254,9 @@ class MetricService { * @returns * @memberof MetricService */ - async getPeerList(channel_genesis_hash, cb) { + async getPeerList(network_name, channel_genesis_hash, cb) { try { - const peerArray = await this.getPeerData(channel_genesis_hash); + const peerArray = await this.getPeerData(network_name, channel_genesis_hash); if (cb) { return cb(peerArray); } @@ -262,9 +274,9 @@ class MetricService { * @returns * @memberof MetricService */ - async getOrdererList(cb) { + async getOrdererList(network_name, cb) { try { - const ordererArray = await this.getOrdererData(); + const ordererArray = await this.getOrdererData(network_name); return cb(ordererArray); } catch (err) { logger.error(err); @@ -280,7 +292,7 @@ class MetricService { * @returns * @memberof MetricService */ - getTxByMinute(channel_genesis_hash, hours) { + getTxByMinute(network_name, channel_genesis_hash, hours) { const sqlPerMinute = ` with minutes as ( select generate_series( date_trunc('min', now()) - '${hours}hour'::interval, @@ -292,7 +304,7 @@ class MetricService { minutes.datetime, count(createdt) from minutes - left join TRANSACTIONS on date_trunc('min', TRANSACTIONS.createdt) = minutes.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join TRANSACTIONS on date_trunc('min', TRANSACTIONS.createdt) = minutes.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -307,7 +319,7 @@ class MetricService { * @returns * @memberof MetricService */ - getTxByHour(channel_genesis_hash, day) { + getTxByHour(network_name, channel_genesis_hash, day) { const sqlPerHour = ` with hours as ( select generate_series( date_trunc('hour', now()) - '${day}day'::interval, @@ -319,7 +331,7 @@ class MetricService { hours.datetime, count(createdt) from hours - left join TRANSACTIONS on date_trunc('hour', TRANSACTIONS.createdt) = hours.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join TRANSACTIONS on date_trunc('hour', TRANSACTIONS.createdt) = hours.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -334,7 +346,7 @@ class MetricService { * @returns * @memberof MetricService */ - getTxByDay(channel_genesis_hash, days) { + getTxByDay(network_name, channel_genesis_hash, days) { const sqlPerDay = ` with days as ( select generate_series( date_trunc('day', now()) - '${days}day'::interval, @@ -346,7 +358,7 @@ class MetricService { days.datetime, count(createdt) from days - left join TRANSACTIONS on date_trunc('day', TRANSACTIONS.createdt) =days.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join TRANSACTIONS on date_trunc('day', TRANSACTIONS.createdt) =days.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -361,7 +373,7 @@ class MetricService { * @returns * @memberof MetricService */ - getTxByWeek(channel_genesis_hash, weeks) { + getTxByWeek(network_name, channel_genesis_hash, weeks) { const sqlPerWeek = ` with weeks as ( select generate_series( date_trunc('week', now()) - '${weeks}week'::interval, @@ -373,7 +385,7 @@ class MetricService { weeks.datetime, count(createdt) from weeks - left join TRANSACTIONS on date_trunc('week', TRANSACTIONS.createdt) =weeks.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join TRANSACTIONS on date_trunc('week', TRANSACTIONS.createdt) =weeks.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -388,7 +400,7 @@ class MetricService { * @returns * @memberof MetricService */ - getTxByMonth(channel_genesis_hash, months) { + getTxByMonth(network_name, channel_genesis_hash, months) { const sqlPerMonth = ` with months as ( select generate_series( date_trunc('month', now()) - '${months}month'::interval, @@ -401,7 +413,7 @@ class MetricService { months.datetime, count(createdt) from months - left join TRANSACTIONS on date_trunc('month', TRANSACTIONS.createdt) =months.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join TRANSACTIONS on date_trunc('month', TRANSACTIONS.createdt) =months.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -416,7 +428,7 @@ class MetricService { * @returns * @memberof MetricService */ - getTxByYear(channel_genesis_hash, years) { + getTxByYear(network_name, channel_genesis_hash, years) { const sqlPerYear = ` with years as ( select generate_series( date_trunc('year', now()) - '${years}year'::interval, @@ -428,7 +440,7 @@ class MetricService { years.year, count(createdt) from years - left join TRANSACTIONS on date_trunc('year', TRANSACTIONS.createdt) =years.year and channel_genesis_hash ='${channel_genesis_hash}' + left join TRANSACTIONS on date_trunc('year', TRANSACTIONS.createdt) =years.year and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -444,7 +456,7 @@ class MetricService { * @returns * @memberof MetricService */ - getBlocksByMinute(channel_genesis_hash, hours) { + getBlocksByMinute(network_name, channel_genesis_hash, hours) { const sqlPerMinute = ` with minutes as ( select generate_series( date_trunc('min', now()) - '${hours} hour'::interval, @@ -456,7 +468,7 @@ class MetricService { minutes.datetime, count(createdt) from minutes - left join BLOCKS on date_trunc('min', BLOCKS.createdt) = minutes.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join BLOCKS on date_trunc('min', BLOCKS.createdt) = minutes.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -471,7 +483,7 @@ class MetricService { * @returns * @memberof MetricService */ - getBlocksByHour(channel_genesis_hash, days) { + getBlocksByHour(network_name, channel_genesis_hash, days) { const sqlPerHour = ` with hours as ( select generate_series( date_trunc('hour', now()) - '${days}day'::interval, @@ -483,7 +495,7 @@ class MetricService { hours.datetime, count(createdt) from hours - left join BLOCKS on date_trunc('hour', BLOCKS.createdt) = hours.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join BLOCKS on date_trunc('hour', BLOCKS.createdt) = hours.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -498,7 +510,7 @@ class MetricService { * @returns * @memberof MetricService */ - getBlocksByDay(channel_genesis_hash, days) { + getBlocksByDay(network_name, channel_genesis_hash, days) { const sqlPerDay = ` with days as ( select generate_series( date_trunc('day', now()) - '${days}day'::interval, @@ -510,7 +522,7 @@ class MetricService { days.datetime, count(createdt) from days - left join BLOCKS on date_trunc('day', BLOCKS.createdt) =days.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join BLOCKS on date_trunc('day', BLOCKS.createdt) =days.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -525,7 +537,7 @@ class MetricService { * @returns * @memberof MetricService */ - getBlocksByWeek(channel_genesis_hash, weeks) { + getBlocksByWeek(network_name, channel_genesis_hash, weeks) { const sqlPerWeek = ` with weeks as ( select generate_series( date_trunc('week', now()) - '${weeks}week'::interval, @@ -537,7 +549,7 @@ class MetricService { weeks.datetime, count(createdt) from weeks - left join BLOCKS on date_trunc('week', BLOCKS.createdt) =weeks.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join BLOCKS on date_trunc('week', BLOCKS.createdt) =weeks.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -552,7 +564,7 @@ class MetricService { * @returns * @memberof MetricService */ - getBlocksByMonth(channel_genesis_hash, months) { + getBlocksByMonth(network_name, channel_genesis_hash, months) { const sqlPerMonth = ` with months as ( select generate_series( date_trunc('month', now()) - '${months}month'::interval, @@ -564,7 +576,7 @@ class MetricService { months.datetime, count(createdt) from months - left join BLOCKS on date_trunc('month', BLOCKS.createdt) =months.datetime and channel_genesis_hash ='${channel_genesis_hash}' + left join BLOCKS on date_trunc('month', BLOCKS.createdt) =months.datetime and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -579,7 +591,7 @@ class MetricService { * @returns * @memberof MetricService */ - getBlocksByYear(channel_genesis_hash, years) { + getBlocksByYear(network_name, channel_genesis_hash, years) { const sqlPerYear = ` with years as ( select generate_series( date_trunc('year', now()) - '${years}year'::interval, @@ -591,7 +603,7 @@ class MetricService { years.year, count(createdt) from years - left join BLOCKS on date_trunc('year', BLOCKS.createdt) =years.year and channel_genesis_hash ='${channel_genesis_hash}' + left join BLOCKS on date_trunc('year', BLOCKS.createdt) =years.year and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by 1 order by 1 `; @@ -605,10 +617,10 @@ class MetricService { * @returns * @memberof MetricService */ - getTxByOrgs(channel_genesis_hash) { + getTxByOrgs(network_name, channel_genesis_hash) { const sqlPerOrg = ` select count(creator_msp_id), creator_msp_id from transactions - where channel_genesis_hash ='${channel_genesis_hash}' + where channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' group by creator_msp_id`; return this.sql.getRowsBySQlQuery(sqlPerOrg); @@ -622,9 +634,9 @@ class MetricService { * @returns * @memberof MetricService */ - async findMissingBlockNumber(channel_genesis_hash, maxHeight) { + async findMissingBlockNumber(network_name, channel_genesis_hash, maxHeight) { const sqlQuery = `SELECT s.id AS missing_id - FROM generate_series(0, ${maxHeight}) s(id) WHERE NOT EXISTS (SELECT 1 FROM blocks WHERE blocknum = s.id and channel_genesis_hash ='${channel_genesis_hash}' )`; + FROM generate_series(0, ${maxHeight}) s(id) WHERE NOT EXISTS (SELECT 1 FROM blocks WHERE blocknum = s.id and channel_genesis_hash ='${channel_genesis_hash}' and network_name='${network_name}' )`; return this.sql.getRowsBySQlQuery(sqlQuery); } diff --git a/app/persistence/fabric/postgreSQL/db/explorerpg.sql b/app/persistence/fabric/postgreSQL/db/explorerpg.sql index 8cd5b0ba5..7f06cad56 100644 --- a/app/persistence/fabric/postgreSQL/db/explorerpg.sql +++ b/app/persistence/fabric/postgreSQL/db/explorerpg.sql @@ -25,7 +25,8 @@ CREATE TABLE blocks prev_blockhash character varying(256) DEFAULT NULL, blockhash character varying(256) DEFAULT NULL, channel_genesis_hash character varying(256) DEFAULT NULL, - blksize integer DEFAULT NULL + blksize integer DEFAULT NULL, + network_name varchar(255) ); ALTER table blocks owner to :user; @@ -43,7 +44,8 @@ CREATE TABLE chaincodes path character varying(255) DEFAULT NULL, channel_genesis_hash character varying(256) DEFAULT NULL, txcount integer DEFAULT 0, - createdt Timestamp DEFAULT NULL + createdt Timestamp DEFAULT NULL, + network_name varchar(255) ); ALTER table chaincodes owner to :user; @@ -61,7 +63,8 @@ CREATE TABLE peer_ref_chaincode chaincodeid varchar(64) DEFAULT NULL, cc_version varchar(64) DEFAULT NULL, channelid character varying(256) DEFAULT NULL, - createdt Timestamp DEFAULT NULL + createdt Timestamp DEFAULT NULL, + network_name varchar(255) ); ALTER table peer_ref_chaincode owner to :user; @@ -84,7 +87,8 @@ CREATE TABLE channel channel_config bytea default NULL, channel_block bytea DEFAULT NULL, channel_tx bytea DEFAULT NULL, - channel_version character varying(128) DEFAULT NULL + channel_version character varying(128) DEFAULT NULL, + network_name varchar(255) ); ALTER table channel owner to :user; @@ -106,7 +110,8 @@ CREATE TABLE peer events varchar(64) DEFAULT NULL, server_hostname varchar(64) DEFAULT NULL, createdt timestamp DEFAULT NULL, - peer_type character varying(64) DEFAULT NULL + peer_type character varying(64) DEFAULT NULL, + network_name varchar(255) ); ALTER table peer owner to :user; -- --------------------------- @@ -120,7 +125,8 @@ CREATE TABLE peer_ref_channel createdt Timestamp DEFAULT NULL, peerid varchar(64), channelid character varying(256), - peer_type character varying(64) DEFAULT NULL + peer_type character varying(64) DEFAULT NULL, + network_name varchar(255) ); ALTER table peer_ref_channel owner to :user; @@ -137,7 +143,8 @@ CREATE TABLE orderer id SERIAL PRIMARY KEY, requests varchar(64) DEFAULT NULL, server_hostname varchar(64) DEFAULT NULL, - createdt timestamp DEFAULT NULL + createdt timestamp DEFAULT NULL, + network_name varchar(255) ); ALTER table orderer owner to :user; @@ -170,7 +177,8 @@ CREATE TABLE transactions tx_response character varying DEFAULT NULL, payload_proposal_hash character varying DEFAULT NULL, endorser_id_bytes character varying DEFAULT NULL, - endorser_signature character varying DEFAULT NULL + endorser_signature character varying DEFAULT NULL, + network_name varchar(255) ); ALTER table transactions owner to :user; diff --git a/app/persistence/postgreSQL/PgService.js b/app/persistence/postgreSQL/PgService.js index bb2195eb5..682c20ab7 100644 --- a/app/persistence/postgreSQL/PgService.js +++ b/app/persistence/postgreSQL/PgService.js @@ -72,9 +72,7 @@ class PgService { } // don't log password - const connectionString = `postgres://${this.pgconfig.username}:******@${ - this.pgconfig.host - }:${this.pgconfig.port}/${this.pgconfig.database}`; + const connectionString = `postgres://${this.pgconfig.username}:******@${this.pgconfig.host}:${this.pgconfig.port}/${this.pgconfig.database}`; logger.info(`connecting to Postgresql ${connectionString}`); diff --git a/app/platform/fabric/FabricClient.js b/app/platform/fabric/FabricClient.js index ca010dc7c..4ed2eb8a9 100644 --- a/app/platform/fabric/FabricClient.js +++ b/app/platform/fabric/FabricClient.js @@ -32,7 +32,8 @@ class FabricClient { * @param {*} client_name * @memberof FabricClient */ - constructor(client_name) { + constructor(network_name, client_name) { + this.network_name = network_name; this.client_name = client_name; this.hfc_client = null; this.fabricGateway = null; @@ -213,7 +214,7 @@ class FabricClient { const default_peer_name = defaultPeerConfig.name; const channels = await persistence .getCrudService() - .getChannelsInfo(default_peer_name); + .getChannelsInfo(this.network_name, default_peer_name); const default_channel_name = fabricConfig.getDefaultChannel(); @@ -225,7 +226,7 @@ class FabricClient { this.setChannelGenHash(channel.channelname, channel.channel_genesis_hash); const nodes = await persistence .getMetricService() - .getPeerList(channel.channel_genesis_hash); + .getPeerList(this.network_name, channel.channel_genesis_hash); let newchannel; try { newchannel = this.hfc_client.getChannel(channel.channelname); diff --git a/app/platform/fabric/Platform.js b/app/platform/fabric/Platform.js index c6a6adf7f..144dbf40d 100644 --- a/app/platform/fabric/Platform.js +++ b/app/platform/fabric/Platform.js @@ -106,7 +106,7 @@ class Platform { } for (const network_name in this.network_configs) { - this.networks.set(network_name, new Map()); + // this.networks.set(network_name, new Map()); const client_configs = this.network_configs[network_name]; // Console.log('network_name ', network_name, ' client_configs ', client_configs) if (!this.defaultNetwork) { @@ -138,6 +138,7 @@ class Platform { logger.info('FabricUtils.createFabricClient '); client = await FabricUtils.createFabricClient( client_configs, + network_name, client_name, this.persistence ); @@ -145,16 +146,15 @@ class Platform { logger.info('FabricUtils.createDetachClient '); client = await FabricUtils.createDetachClient( client_configs, + network_name, client_name, this.persistence ); } if (client) { // Set client into clients map - logger.info('FabricUtils.createDetachClient '); - const clients = this.networks.get(network_name); - clients.set(client_name, client); - // Console.log('clients ', clients); + const clientObj = { name: client_name, instance: client }; + this.networks.set(network_name, clientObj); } // } } @@ -168,19 +168,19 @@ class Platform { */ initializeListener(syncconfig) { /* eslint-disable */ - for (const [network_name, clients] of this.networks.entries()) { - for (const [client_name, client] of clients.entries()) { - logger.info( - 'initializeListener, client_name, client ', - client_name, - client.client_config - ); - if (this.getClient(network_name, client_name).getStatus()) { - const explorerListener = new ExplorerListener(this, syncconfig); - explorerListener.initialize([network_name, client_name, '1']); - explorerListener.send('Successfully send a message to child process'); - this.explorerListeners.push(explorerListener); - } + for (const [network_name, clientObj] of this.networks.entries()) { + const client_name = clientObj.name; + const client = clientObj.instance; + logger.info( + 'initializeListener, client_name, client ', + client_name, + client.client_config + ); + if (this.getClient(network_name).getStatus()) { + const explorerListener = new ExplorerListener(this, syncconfig); + explorerListener.initialize([network_name, client_name, '1']); + explorerListener.send('Successfully send a message to child process'); + this.explorerListeners.push(explorerListener); } } /* eslint-enable */ @@ -210,25 +210,11 @@ class Platform { * @returns * @memberof Platform */ - changeNetwork(network_name, client_name, channel_name) { - const network = this.networks.get(network_name); - if (network) { + changeNetwork(network_name, channel_name) { + const clientObj = this.networks.get(network_name); + if (clientObj) { this.defaultNetwork = network_name; - let client; - if (client_name) { - client = network.get(client_name); - if (client) { - this.defaultClient = client_name; - } else { - return `Client [${network_name}] is not found in network`; - } - } else { - const iterator = network.values(); - client = iterator.next().value; - if (!client) { - return `Client [${network_name}] is not found in network`; - } - } + const client = clientObj.instance; if (channel_name) { client.setDefaultChannel(channel_name); } @@ -255,10 +241,9 @@ class Platform { * @returns * @memberof Platform */ - getClient(network_name, client_name) { - return this.networks - .get(network_name || this.defaultNetwork) - .get(client_name || this.defaultClient); + getClient(network_name) { + const clientObj = this.networks.get(network_name || this.defaultNetwork); + return clientObj.instance; } /** diff --git a/app/platform/fabric/Proxy.js b/app/platform/fabric/Proxy.js index fd2261518..0b2b3196b 100644 --- a/app/platform/fabric/Proxy.js +++ b/app/platform/fabric/Proxy.js @@ -74,8 +74,10 @@ class Proxy { * @returns * @memberof Proxy */ - async getCurrentChannel() { - const client = await this.platform.getClient(); + async getCurrentChannel(network_name) { + logger.debug('getCurrentChannel: network_name', network_name); + + const client = await this.platform.getClient(network_name); const channel = client.getDefaultChannel(); const channel_genesis_hash = client.getChannelGenHash(channel.getName()); let respose; @@ -101,12 +103,12 @@ class Proxy { * @returns * @memberof Proxy */ - async getPeersStatus(channel_genesis_hash) { - const client = await this.platform.getClient(); + async getPeersStatus(network_name, channel_genesis_hash) { + const client = await this.platform.getClient(network_name); const channel = client.getDefaultChannel(); const nodes = await this.persistence .getMetricService() - .getPeerList(channel_genesis_hash); + .getPeerList(network_name, channel_genesis_hash); let discover_results; if (client.status) { try { @@ -161,8 +163,8 @@ class Proxy { * @returns * @memberof Proxy */ - async changeChannel(channel_genesis_hash) { - const client = this.platform.getClient(); + async changeChannel(network_name, channel_genesis_hash) { + const client = this.platform.getClient(network_name); const respose = client.setDefaultChannelByHash(channel_genesis_hash); logger.debug('changeChannel >> %s', respose); return respose; @@ -174,11 +176,11 @@ class Proxy { * @returns * @memberof Proxy */ - async getChannelsInfo() { - const client = this.platform.getClient(); + async getChannelsInfo(network_name) { + const client = this.platform.getClient(network_name); const channels = await this.persistence .getCrudService() - .getChannelsInfo(client.getDefaultPeer()); + .getChannelsInfo(network_name, client.getDefaultPeer()); const currentchannels = []; for (const channel of channels) { const channel_genesis_hash = client.getChannelGenHash(channel.channelname); @@ -200,13 +202,13 @@ class Proxy { * @returns * @memberof Proxy */ - async getTxByOrgs(channel_genesis_hash) { + async getTxByOrgs(network_name, channel_genesis_hash) { const rows = await this.persistence .getMetricService() - .getTxByOrgs(channel_genesis_hash); + .getTxByOrgs(network_name, channel_genesis_hash); const organizations = await this.persistence .getMetricService() - .getOrgsData(channel_genesis_hash); + .getOrgsData(network_name, channel_genesis_hash); for (const organization of rows) { const index = organizations.indexOf(organization.creator_msp_id); @@ -231,15 +233,20 @@ class Proxy { * @returns * @memberof Proxy */ - async getBlockByNumber(channel_genesis_hash, number) { - const client = this.platform.getClient(); + async getBlockByNumber(network_name, channel_genesis_hash, number) { + const client = this.platform.getClient(network_name); const channel = client.getChannelByHash(channel_genesis_hash); + let block; - const block = channel.queryBlock( - parseInt(number), - client.getDefaultPeer(), - true - ); + try { + block = await channel.queryBlock( + parseInt(number), + client.getDefaultPeer(), + true + ); + } catch (e) { + logger.debug('queryBlock >> ', e); + } if (block) { return block; @@ -265,20 +272,18 @@ class Proxy { * @returns * @memberof Proxy */ - async getChannels() { - const client = this.platform.getClient(); + async getChannels(network_name) { + const client = this.platform.getClient(network_name); const client_channels = client.getChannelNames(); const channels = await this.persistence .getCrudService() - .getChannelsInfo(client.getDefaultPeer()); + .getChannelsInfo(network_name, client.getDefaultPeer()); const respose = []; for (let i = 0; i < channels.length; i++) { const index = client_channels.indexOf(channels[i].channelname); if (!(index > -1)) { - await this.platform - .getClient() - .initializeNewChannel(channels[i].channelname); + await client.initializeNewChannel(channels[i].channelname); } respose.push(channels[i].channelname); } @@ -326,9 +331,7 @@ class Proxy { if (fabric_const.NOTITY_TYPE_NEWCHANNEL === msg.notify_type) { // Initialize new channel instance in parent if (msg.network_name && msg.client_name) { - const client = this.platform.networks - .get(msg.network_name) - .get(msg.client_name); + const client = this.platform.getClient(msg.network_name); if (msg.channel_name) { client.initializeNewChannel(msg.channel_name); } else { @@ -347,9 +350,7 @@ class Proxy { ) { // Update channel details in parent if (msg.network_name && msg.client_name) { - const client = this.platform.networks - .get(msg.network_name) - .get(msg.client_name); + const client = this.platform.getClient(msg.network_name); if (msg.channel_name) { client.initializeChannelFromDiscover(msg.channel_name); } else { diff --git a/app/platform/fabric/e2e-test/configs/connection-profile/org2-network.json b/app/platform/fabric/e2e-test/configs/connection-profile/org2-network.json index 36f80de5d..b70a4b8cc 100644 --- a/app/platform/fabric/e2e-test/configs/connection-profile/org2-network.json +++ b/app/platform/fabric/e2e-test/configs/connection-profile/org2-network.json @@ -6,8 +6,8 @@ "tlsEnable": true, "adminUser": "admin", "adminPassword": "adminpw", - "enableAuthentication": true, "organization": "org2", + "enableAuthentication": false, "connection": { "timeout": { "peer": { @@ -18,7 +18,7 @@ } }, "channels": { - "testorgschannel0": { + "commonchannel": { "peers": { "peer0-org2": {} }, @@ -40,6 +40,7 @@ "adminPrivateKey": { "path": "/tmp/crypto/peerOrganizations/org2/users/Admin@org2/msp/keystore/priv_sk" }, + "certificateAuthorities": ["ca0"], "signedCert": { "path": "/tmp/crypto/peerOrganizations/org2/users/Admin@org2/msp/signcerts/Admin@org2-cert.pem" } @@ -50,10 +51,22 @@ "tlsCACerts": { "path": "/tmp/crypto/peerOrganizations/org2/peers/peer0-org2.org2/tls/ca.crt" }, - "url": "grpcs://peer0-org2:31000", + "url": "grpcs://peer0-org2:31002", "grpcOptions": { "ssl-target-name-override": "peer0-org2" } } + }, + "certificateAuthorities": { + "ca0": { + "url": "https://ca0-org2:7054", + "httpOptions": { + "verify": false + }, + "tlsCACerts": { + "path": "/tmp/crypto/peerOrganizations/org2/ca/ca.org2-cert.pem" + }, + "caName": "ca0-org2" + } } } diff --git a/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-common.yml b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-common.yml new file mode 100644 index 000000000..226684801 --- /dev/null +++ b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-common.yml @@ -0,0 +1,31 @@ +organizations: + - name: org1 +#! For smoke test suite, connection-profile are read from smoke directory + connProfilePath: ./connection-profile/connection_profile_org1.yaml + - name: org2 + connProfilePath: ./connection-profile/connection_profile_org2.yaml + +invokes: + - channelName: commonchannel + name: samplecc + targetPeers: OrgAnchor + nProcPerOrg: 1 + nRequest: 1 + runDur: 0 + organizations: org1 + txnOpt: + - mode: constant + options: + constFreq: 0 + devFreq: 0 + queryCheck: 100 + eventOpt: + type: FilteredBlock + listener: Block + timeout: 240000 + ccOpt: + ccType: ccchecker + keyStart: 0 + payLoadMin: 1024 + payLoadMax: 2048 + args: "put,a1,1" diff --git a/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org1.yml b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org1.yml new file mode 100644 index 000000000..ef17c7218 --- /dev/null +++ b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org1.yml @@ -0,0 +1,31 @@ +organizations: + - name: org1 +#! For smoke test suite, connection-profile are read from smoke directory + connProfilePath: ./connection-profile/connection_profile_org1.yaml + - name: org2 + connProfilePath: ./connection-profile/connection_profile_org2.yaml + +invokes: + - channelName: org1channel + name: samplecc + targetPeers: OrgAnchor + nProcPerOrg: 1 + nRequest: 1 + runDur: 0 + organizations: org1 + txnOpt: + - mode: constant + options: + constFreq: 0 + devFreq: 0 + queryCheck: 100 + eventOpt: + type: FilteredBlock + listener: Block + timeout: 240000 + ccOpt: + ccType: ccchecker + keyStart: 0 + payLoadMin: 1024 + payLoadMax: 2048 + args: "put,a1,1" diff --git a/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org2.yml b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org2.yml new file mode 100644 index 000000000..8888ca721 --- /dev/null +++ b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org2.yml @@ -0,0 +1,31 @@ +organizations: + - name: org1 +#! For smoke test suite, connection-profile are read from smoke directory + connProfilePath: ./connection-profile/connection_profile_org1.yaml + - name: org2 + connProfilePath: ./connection-profile/connection_profile_org2.yaml + +invokes: + - channelName: org2channel + name: samplecc + targetPeers: OrgAnchor + nProcPerOrg: 1 + nRequest: 1 + runDur: 0 + organizations: org2 + txnOpt: + - mode: constant + options: + constFreq: 0 + devFreq: 0 + queryCheck: 100 + eventOpt: + type: FilteredBlock + listener: Block + timeout: 240000 + ccOpt: + ccType: ccchecker + keyStart: 0 + payLoadMin: 1024 + payLoadMax: 2048 + args: "put,a1,1" diff --git a/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile.yml b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile.yml index 0ebc37eae..d8aa3ba46 100644 --- a/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile.yml +++ b/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile.yml @@ -62,13 +62,27 @@ installChaincode: metadataPath: "" instantiateChaincode: - - channelName: testorgschannel0 + - channelName: commonchannel name: samplecc version: v1 args: "" organizations: org1 endorsementPolicy: 2of(org1,org2) collectionPath: "" + - channelName: org1channel + name: samplecc + version: v1 + args: "" + organizations: org1 + endorsementPolicy: 1of(org1) + collectionPath: "" + - channelName: org2channel + name: samplecc + version: v1 + args: "" + organizations: org2 + endorsementPolicy: 1of(org2) + collectionPath: "" upgradeChaincode: - channelName: testorgschannel0 @@ -80,11 +94,11 @@ upgradeChaincode: collectionPath: "" invokes: - - channelName: testorgschannel0 + - channelName: commonchannel name: samplecc targetPeers: OrgAnchor - nProcPerOrg: 2 - nRequest: 10 + nProcPerOrg: 1 + nRequest: 1 runDur: 0 organizations: org1,org2 txnOpt: diff --git a/app/platform/fabric/e2e-test/specs/apitest_def_test.go b/app/platform/fabric/e2e-test/specs/apitest_def_test.go new file mode 100644 index 000000000..04e78bee6 --- /dev/null +++ b/app/platform/fabric/e2e-test/specs/apitest_def_test.go @@ -0,0 +1,114 @@ +package apitest + +type UserData struct { + Message string `json:"message"` + Name string `json:"name"` +} + +type LoginResponse struct { + Status int `json:"status"` + Success bool `json:"success"` + Message string `json:"message"` + Token string `json:"token"` + User UserData `json:"user"` +} + +type RegisterResp struct { + Status int `json:"status"` + Message string `json:"message"` +} + +type ChannelData struct { + ID int `json:"id"` + Channelname string `json:"channelname"` + Blocks int `json:"blocks"` + ChannelGenesisHash string `json:"channel_genesis_hash"` + Transactions int `json:"transactions"` + Createdat string `json:"createdat"` + ChannelHash string `json:"channel_hash"` +} + +type ChannelsInfoResp struct { + Status int `json:"status"` + Channels []ChannelData `json:"channels"` +} + +func (ch *ChannelsInfoResp) getChannelList() []string { + chList := []string{} + for _, val := range ch.Channels { + chList = append(chList, val.Channelname) + } + return chList +} + +func (ch *ChannelsInfoResp) getChannelData(channelID string) *ChannelData { + var info *ChannelData + for _, val := range ch.Channels { + if val.Channelname == channelID { + info = &val + break + } + } + return info +} + +func (ch *ChannelsInfoResp) getGenesisHash(channelID string) string { + var hash string + for _, val := range ch.Channels { + if val.Channelname == channelID { + hash = val.ChannelGenesisHash + break + } + } + return hash +} + +func (ch *ChannelsInfoResp) getBlockHeight(channelID string) int { + + var height int + for _, val := range ch.Channels { + if val.Channelname == channelID { + height = val.Blocks + break + } + } + return height +} + +type ChannelsResponse struct { + Status int `json:"status"` + Channels []string `json:"channels"` +} + +type BlockData struct { + Blocknum int `json:"blocknum"` + Txcount int `json:"txcount"` + Datahash string `json:"datahash"` + Blockhash string `json:"blockhash"` + Prehash string `json:"prehash"` + Createdt string `json:"createdt"` + Txhash []string `json:"txhash"` + Channelname string `json:"channelname"` +} + +type BlockActivityResp struct { + Status int `json:"status"` + Row []BlockData `json:"row"` +} + +type BlockResp struct { + Status int `json:"status"` + Number string `json:"number"` + PreviousHash string `json:"previous_hash"` + DataHash string `json:"data_hash"` + Transactions []interface{} `json:"transactions"` +} + +type PeersStatusResp struct { + Status int `json:"status"` + Peers []interface{} `json:"peers"` +} + +type NetworklistInfo struct { + NetworkList [][]interface{} `json:"networkList"` +} diff --git a/app/platform/fabric/e2e-test/specs/apitest_suite_test.go b/app/platform/fabric/e2e-test/specs/apitest_suite_test.go index a61fa8b6e..a957075f7 100644 --- a/app/platform/fabric/e2e-test/specs/apitest_suite_test.go +++ b/app/platform/fabric/e2e-test/specs/apitest_suite_test.go @@ -4,12 +4,10 @@ import ( "strings" "testing" + "github.com/hyperledger/fabric-test/tools/operator/networkclient" . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/reporters" . "github.com/onsi/gomega" - - "github.com/hyperledger/fabric-test/tools/operator/launcher" - "github.com/hyperledger/fabric-test/tools/operator/networkclient" ) func TestRestApi(t *testing.T) { @@ -20,17 +18,11 @@ func TestRestApi(t *testing.T) { // Bringing up network using BeforeSuite var _ = BeforeSuite(func() { - networkSpecPath := "apitest-network-spec.yml" - err := launcher.Launcher("up", "docker", "", networkSpecPath) - Expect(err).NotTo(HaveOccurred()) }) // Cleaning up network launched from BeforeSuite and removing all chaincode containers // and chaincode container images using AfterSuite var _ = AfterSuite(func() { - networkSpecPath := "apitest-network-spec.yml" - err := launcher.Launcher("down", "docker", "", networkSpecPath) - Expect(err).NotTo(HaveOccurred()) dockerList := []string{"ps", "-aq", "-f", "status=exited"} containerList, _ := networkclient.ExecuteCommand("docker", dockerList, false) diff --git a/app/platform/fabric/e2e-test/specs/apitest_test.go b/app/platform/fabric/e2e-test/specs/apitest_test.go index 7c415e857..6af1a6949 100644 --- a/app/platform/fabric/e2e-test/specs/apitest_test.go +++ b/app/platform/fabric/e2e-test/specs/apitest_test.go @@ -6,55 +6,21 @@ import ( "os/exec" "strconv" "strings" + "time" "github.com/go-resty/resty/v2" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/hyperledger/fabric-test/tools/operator/launcher" "github.com/hyperledger/fabric-test/tools/operator/networkclient" "github.com/hyperledger/fabric-test/tools/operator/testclient" ) -type UserData struct { - Message string `json:"message"` - Name string `json:"name"` -} - -type LoginResponse struct { - Status int `json:"status"` - Success bool `json:"success"` - Message string `json:"message"` - Token string `json:"token"` - User UserData `json:"user"` -} - -type RegisterResp struct { - Status int `json:"status"` - Message string `json:"message"` -} - -type ChannelData struct { - ID int `json:"id"` - Channelname string `json:"channelname"` - Blocks int `json:"blocks"` - ChannelGenesisHash string `json:"channel_genesis_hash"` - Transactions int `json:"transactions"` - Createdat string `json:"createdat"` - ChannelHash string `json:"channel_hash"` -} - -type ChannelsInfoResp struct { - Status int `json:"status"` - Channels []ChannelData `json:"channels"` -} - -type ChannelsResponse struct { - Status int `json:"status"` - Channels []string `json:"channels"` -} - var ( - channelMonitored string + channelMonitored string + org1CurrentBlockNum int + org2CurrentBlockNum int ) func CheckHowManyEventHubRegistered() int { @@ -87,16 +53,81 @@ func StopNode(nodeName string) { } } -var _ = Describe("REST API Test Suite", func() { +func restGet(path string, data interface{}) *resty.Response { + return restGetWithToken(path, data, "") +} + +func restGetWithToken(path string, data interface{}, token string) *resty.Response { + client := resty.New() + if len(token) != 0 { + client.SetAuthToken(token) + } + + resp, err := client.R(). + EnableTrace(). + SetResult(data). + Get("http://localhost:8090" + path) + + Expect(err).ShouldNot(HaveOccurred()) + return resp +} + +func compareChannelsInfoBlockCount(before *ChannelsInfoResp, after *ChannelsInfoResp, channel string, expectDiff int) { + beforeData := before.getChannelData(channel) + Expect(beforeData).ShouldNot(Equal(nil)) + afterData := after.getChannelData(channel) + Expect(afterData).ShouldNot(Equal(nil)) + diff := afterData.Blocks - beforeData.Blocks + Expect(diff).Should(Equal(expectDiff)) +} + +func compareChannelsInfoTxCount(before *ChannelsInfoResp, after *ChannelsInfoResp, channel string, expectDiff int) { + beforeData := before.getChannelData(channel) + Expect(beforeData).ShouldNot(Equal(nil)) + afterData := after.getChannelData(channel) + Expect(afterData).ShouldNot(Equal(nil)) + diff := afterData.Transactions - beforeData.Transactions + Expect(diff).Should(Equal(expectDiff)) +} + +func restPost(path string, body interface{}, data interface{}) *resty.Response { + return restPostWithToken(path, body, data, "") +} + +func restPostWithToken(path string, body interface{}, data interface{}, token string) *resty.Response { + client := resty.New() + if len(token) != 0 { + client.SetAuthToken(token) + } + resp, err := client.R(). + EnableTrace(). + SetHeader("Content-Type", "application/json"). + SetBody(body). + SetResult(data). + Post("http://localhost:8090" + path) + + Expect(err).ShouldNot(HaveOccurred()) + return resp +} + +var _ = Describe("REST API Test Suite - Single profile", func() { Describe("Running REST API Test Suite in fabric-test", func() { var ( action string + networkSpecPath string inputSpecPath string token string channelGenesisHash string blockHeight int ) + + It("Starting fabric network", func() { + networkSpecPath = "apitest-network-spec.yml" + err := launcher.Launcher("up", "docker", "", networkSpecPath) + Expect(err).NotTo(HaveOccurred()) + }) + It("starting fabric network", func() { out, err := exec.Command("pwd").Output() if err != nil { @@ -152,19 +183,8 @@ var _ = Describe("REST API Test Suite", func() { }) It("get network list", func() { - type NetworklistInfo struct { - NetworkList [][]interface{} `json:"networkList"` - } - - // Create a Resty Client - client := resty.New() - resp, err := client.R(). - EnableTrace(). - SetResult(&NetworklistInfo{}). - Get("http://localhost:8090/auth/networklist") - - Expect(err).ShouldNot(HaveOccurred()) + resp := restGet("/auth/networklist", &NetworklistInfo{}) result := resp.Result().(*NetworklistInfo) list := []string{} @@ -173,22 +193,11 @@ var _ = Describe("REST API Test Suite", func() { } Expect(list).Should(HaveLen(1)) Expect(list).Should(ContainElements([]string{"org1-network"})) - }) It("login to org1-network", func() { - client := resty.New() - - resp, err := client.R(). - EnableTrace(). - SetHeader("Content-Type", "application/json"). - SetBody(map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org1-network"}). - SetResult(&LoginResponse{}). - Post("http://localhost:8090/auth/login") - - Expect(err).ShouldNot(HaveOccurred()) - + resp := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org1-network"}, &LoginResponse{}) result := resp.Result().(*LoginResponse) token = result.Token @@ -197,156 +206,49 @@ var _ = Describe("REST API Test Suite", func() { }) It("get channels", func() { - - client := resty.New() - client.SetAuthToken(token) - - resp, err := client.R(). - EnableTrace(). - SetResult(&ChannelsResponse{}). - Get("http://localhost:8090/api/channels") - - Expect(err).ShouldNot(HaveOccurred()) - + resp := restGetWithToken("/api/channels", &ChannelsResponse{}, token) result := resp.Result().(*ChannelsResponse) - Expect(result.Channels).Should(ContainElements([]string{"org1channel", "commonchannel"})) - + Expect(len(result.Channels)).Should(Equal(2)) }) It("get channels info", func() { - - client := resty.New() - client.SetAuthToken(token) - - resp, err := client.R(). - EnableTrace(). - SetResult(&ChannelsInfoResp{}). - Get("http://localhost:8090/api/channels/info") - - Expect(err).ShouldNot(HaveOccurred()) - + resp := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) result := resp.Result().(*ChannelsInfoResp) - chList := []string{} - for _, ch := range result.Channels { - chList = append(chList, ch.Channelname) - if ch.Channelname == "commonchannel" { - channelGenesisHash = ch.ChannelGenesisHash - blockHeight = ch.Blocks - 1 - } - } - // Expect(result.Channels[0].Channelname).Should(Equal("commonchannel")) + chList := result.getChannelList() + channelGenesisHash = result.getGenesisHash("commonchannel") + blockHeight = result.getBlockHeight("commonchannel") - 1 Expect(chList).Should(ContainElements([]string{"commonchannel", "org1channel"})) - + Expect(len(chList)).Should(Equal(2)) }) It("get block info", func() { - type BlockResp struct { - Status int `json:"status"` - Number string `json:"number"` - PreviousHash string `json:"previous_hash"` - DataHash string `json:"data_hash"` - Transactions []interface{} `json:"transactions"` - } - - client := resty.New() - client.SetAuthToken(token) - - resp, err := client.R(). - EnableTrace(). - SetResult(&BlockResp{}). - Get("http://localhost:8090/api/block/" + channelGenesisHash + "/" + strconv.Itoa(blockHeight)) - - Expect(err).ShouldNot(HaveOccurred()) + resp := restGetWithToken("/api/block/"+channelGenesisHash+"/"+strconv.Itoa(blockHeight), &BlockResp{}, token) result := resp.Result().(*BlockResp) Expect(result.Status).Should(Equal(200)) - }) It("get status of peers within commonchannel", func() { - type PeersStatusResp struct { - Status int `json:"status"` - Peers []interface{} `json:"peers"` - } - - client := resty.New() - client.SetAuthToken(token) - - resp, err := client.R(). - EnableTrace(). - SetResult(&PeersStatusResp{}). - Get("http://localhost:8090/api/peersStatus/" + "commonchannel") - - Expect(err).ShouldNot(HaveOccurred()) + resp := restGetWithToken("/api/peersStatus/"+"commonchannel", &PeersStatusResp{}, token) result := resp.Result().(*PeersStatusResp) Expect(result.Status).Should(Equal(200)) }) It("get block activity", func() { - type BlockData struct { - Blocknum int `json:"blocknum"` - Txcount int `json:"txcount"` - Datahash string `json:"datahash"` - Blockhash string `json:"blockhash"` - Prehash string `json:"prehash"` - Createdt string `json:"createdt"` - Txhash []string `json:"txhash"` - Channelname string `json:"channelname"` - } - - type BlockActivityResp struct { - Status int `json:"status"` - Row []BlockData `json:"row"` - } - - client := resty.New() - client.SetAuthToken(token) - - resp, err := client.R(). - EnableTrace(). - SetResult(&BlockActivityResp{}). - Get("http://localhost:8090/api/blockActivity/" + channelGenesisHash) - - Expect(err).ShouldNot(HaveOccurred()) + resp := restGetWithToken("/api/blockActivity/"+channelGenesisHash, &BlockActivityResp{}, token) result := resp.Result().(*BlockActivityResp) Expect(result.Status).Should(Equal(200)) Expect(result.Row[0].Channelname).Should(Equal("commonchannel")) }) It("register user", func() { - type RegisterResp struct { - Status int `json:"status"` - Message string `json:"message"` - } - - client := resty.New() - client.SetAuthToken(token) - resp, err := client.R(). - EnableTrace(). - SetHeader("Content-Type", "application/json"). - SetBody(map[string]interface{}{"user": "test", "password": "test", "affiliation": "department2", "role": "admin"}). - SetResult(&RegisterResp{}). - Post("http://localhost:8090/api/register") - - Expect(err).ShouldNot(HaveOccurred()) + resp := restPostWithToken("/api/register", map[string]interface{}{"user": "test", "password": "test", "affiliation": "department2", "role": "admin"}, &RegisterResp{}, token) resultRegister := resp.Result().(*RegisterResp) Expect(resultRegister.Status).Should(Equal(200)) }) It("login with newly registered user", func() { - - client := resty.New() - client.SetAuthToken(token) - - resp, err := client.R(). - EnableTrace(). - SetHeader("Content-Type", "application/json"). - SetBody(map[string]interface{}{"user": "test", "password": "test", "network": "org1-network"}). - SetResult(&LoginResponse{}). - Post("http://localhost:8090/auth/login") - - Expect(err).ShouldNot(HaveOccurred()) - + resp := restPost("/auth/login", map[string]interface{}{"user": "test", "password": "test", "network": "org1-network"}, &LoginResponse{}) resultLogin := resp.Result().(*LoginResponse) Expect(resultLogin.User.Message).Should(Equal("logged in")) @@ -354,17 +256,7 @@ var _ = Describe("REST API Test Suite", func() { }) It("fail to register duplicate user", func() { - - client := resty.New() - client.SetAuthToken(token) - resp, err := client.R(). - EnableTrace(). - SetHeader("Content-Type", "application/json"). - SetBody(map[string]interface{}{"user": "test", "password": "test", "affiliation": "department2", "role": "admin"}). - SetResult(&RegisterResp{}). - Post("http://localhost:8090/api/register") - - Expect(err).ShouldNot(HaveOccurred()) + resp := restPostWithToken("/api/register", map[string]interface{}{"user": "test", "password": "test", "affiliation": "department2", "role": "admin"}, &RegisterResp{}, token) resultRegister := resp.Result().(*RegisterResp) Expect(resultRegister.Status).Should(Equal(400)) Expect(resultRegister.Message).Should(Equal("Error: already exists")) @@ -404,27 +296,12 @@ var _ = Describe("REST API Test Suite", func() { action = "invoke" err = testclient.Testclient(action, inputSpecPath) Expect(err).NotTo(HaveOccurred()) - - By("7) Retrieving channels again") - client := resty.New() - client.SetAuthToken(token) - }) It("Should include the newly added channel when retrieving channels again", func() { - - client := resty.New() - client.SetAuthToken(token) - - resp, err := client.R(). - EnableTrace(). - SetResult(&ChannelsResponse{}). - Get("http://localhost:8090/api/channels") - Expect(err).ShouldNot(HaveOccurred()) - + resp := restGetWithToken("/api/channels", &ChannelsResponse{}, token) result := resp.Result().(*ChannelsResponse) Expect(result.Channels).Should(ContainElements([]string{"org1channel", "commonchannel", "channel2422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422"})) - }) It("Should create a new event hub for the newly added channel within 60s", func() { @@ -450,5 +327,421 @@ var _ = Describe("REST API Test Suite", func() { Expect(err).NotTo(HaveOccurred()) }) + It("Shutdown network", func() { + err := launcher.Launcher("down", "docker", "", networkSpecPath) + Expect(err).NotTo(HaveOccurred()) + + dockerList := []string{"ps", "-aq", "-f", "status=exited"} + containerList, _ := networkclient.ExecuteCommand("docker", dockerList, false) + if containerList != "" { + list := strings.Split(containerList, "\n") + containerArgs := []string{"rm", "-f"} + containerArgs = append(containerArgs, list...) + networkclient.ExecuteCommand("docker", containerArgs, true) + } + ccimagesList := []string{"images", "-q", "--filter=reference=dev*"} + images, _ := networkclient.ExecuteCommand("docker", ccimagesList, false) + if images != "" { + list := strings.Split(images, "\n") + imageArgs := []string{"rmi", "-f"} + imageArgs = append(imageArgs, list...) + networkclient.ExecuteCommand("docker", imageArgs, true) + } + }) + + }) +}) + +var _ = Describe("REST API Test Suite - Multiple profile", func() { + + Describe("Running REST API Test Suite in fabric-test", func() { + var ( + action string + networkSpecPath string + inputSpecPath string + ) + + It("Starting fabric network", func() { + networkSpecPath = "apitest-network-spec.yml" + err := launcher.Launcher("up", "docker", "", networkSpecPath) + Expect(err).NotTo(HaveOccurred()) + }) + + It("Setup fabric network", func() { + + inputSpecPath = "apitest-input-multiprofile.yml" + + By("0) Generating channel artifacts") + _, err := networkclient.ExecuteCommand("./genchannelartifacts.sh", []string{}, true) + Expect(err).NotTo(HaveOccurred()) + + By("1) Creating channel") + action = "create" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + By("2) Joining Peers to channel") + action = "join" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + By("3) Updating channel with anchor peers") + action = "anchorpeer" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + By("4) Installing Chaincode on Peers") + action = "install" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + By("5) Instantiating Chaincode") + action = "instantiate" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + By("6) Sending Invokes") + action = "invoke" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + }) + + It("launch explorer", func() { + _, err := networkclient.ExecuteCommand("./runexplorer.sh", []string{"multi"}, true) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("/auth/networklist", func() { + It("get network list", func() { + resp := restGet("/auth/networklist", &NetworklistInfo{}) + result := resp.Result().(*NetworklistInfo) + list := []string{} + for _, val := range result.NetworkList { + list = append(list, val[0].(string)) + } + Expect(list).Should(HaveLen(2)) + Expect(list).Should(ContainElements([]string{"org1-network", "org2-network"})) + + }) + }) + + Context("/auth/login", func() { + It("login to org1-network", func() { + resp := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org1-network"}, &LoginResponse{}) + result := resp.Result().(*LoginResponse) + Expect(result.User.Message).Should(Equal("logged in")) + Expect(result.User.Name).Should(Equal("admin")) + }) + + It("login to org2-network", func() { + resp := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org2-network"}, &LoginResponse{}) + result := resp.Result().(*LoginResponse) + Expect(result.User.Message).Should(Equal("logged in")) + Expect(result.User.Name).Should(Equal("admin")) + }) + }) + + Context("/api/channels", func() { + It("get channels for Org1", func() { + // For org1 + resp := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org1-network"}, &LoginResponse{}) + resultLogin := resp.Result().(*LoginResponse) + token := resultLogin.Token + Expect(resultLogin.User.Message).Should(Equal("logged in")) + + resp = restGetWithToken("/api/channels", &ChannelsResponse{}, token) + result := resp.Result().(*ChannelsResponse) + Expect(result.Channels).Should(ContainElements([]string{"org1channel", "commonchannel"})) + Expect(len(result.Channels)).Should(Equal(2)) + }) + + It("get channels for Org2", func() { + // For org2 + resp := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org2-network"}, &LoginResponse{}) + resultLogin := resp.Result().(*LoginResponse) + token := resultLogin.Token + Expect(resultLogin.User.Message).Should(Equal("logged in")) + + resp = restGetWithToken("/api/channels", &ChannelsResponse{}, token) + result := resp.Result().(*ChannelsResponse) + Expect(result.Channels).Should(ContainElements([]string{"org2channel", "commonchannel"})) + Expect(len(result.Channels)).Should(Equal(2)) + }) + }) + + Context("/api/channels/info", func() { + + It("get channels info for org1", func() { + resp1 := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org1-network"}, &LoginResponse{}) + result1 := resp1.Result().(*LoginResponse) + token := result1.Token + Expect(result1.User.Message).Should(Equal("logged in")) + + resp2 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result2 := resp2.Result().(*ChannelsInfoResp) + chList := result2.getChannelList() + Expect(chList).Should(ContainElements([]string{"commonchannel", "org1channel"})) + Expect(len(chList)).Should(Equal(2)) + + action := "invoke" + inputSpecPath = "apitest-input-multiprofile-invoke-org1.yml" + err := testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(2 * time.Second) + + resp3 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result3 := resp3.Result().(*ChannelsInfoResp) + + compareChannelsInfoBlockCount(result2, result3, "commonchannel", 0) + compareChannelsInfoBlockCount(result2, result3, "org1channel", 1) + compareChannelsInfoTxCount(result2, result3, "commonchannel", 0) + compareChannelsInfoTxCount(result2, result3, "org1channel", 1) + + action = "invoke" + inputSpecPath = "apitest-input-multiprofile-invoke-org2.yml" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(2 * time.Second) + + resp4 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result4 := resp4.Result().(*ChannelsInfoResp) + + compareChannelsInfoBlockCount(result3, result4, "commonchannel", 0) + compareChannelsInfoBlockCount(result3, result4, "org1channel", 0) + compareChannelsInfoTxCount(result3, result4, "commonchannel", 0) + compareChannelsInfoTxCount(result3, result4, "org1channel", 0) + + action = "invoke" + inputSpecPath = "apitest-input-multiprofile-invoke-common.yml" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(2 * time.Second) + + resp5 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result5 := resp5.Result().(*ChannelsInfoResp) + + compareChannelsInfoBlockCount(result4, result5, "commonchannel", 1) + compareChannelsInfoBlockCount(result4, result5, "org1channel", 0) + compareChannelsInfoTxCount(result4, result5, "commonchannel", 1) + compareChannelsInfoTxCount(result4, result5, "org1channel", 0) + }) + + It("get channels info for org2", func() { + resp1 := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org2-network"}, &LoginResponse{}) + result1 := resp1.Result().(*LoginResponse) + token := result1.Token + Expect(result1.User.Message).Should(Equal("logged in")) + + resp2 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result2 := resp2.Result().(*ChannelsInfoResp) + chList := result2.getChannelList() + Expect(chList).Should(ContainElements([]string{"commonchannel", "org2channel"})) + Expect(len(chList)).Should(Equal(2)) + + action := "invoke" + inputSpecPath = "apitest-input-multiprofile-invoke-org1.yml" + err := testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(2 * time.Second) + + resp3 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result3 := resp3.Result().(*ChannelsInfoResp) + + compareChannelsInfoBlockCount(result2, result3, "commonchannel", 0) + compareChannelsInfoBlockCount(result2, result3, "org2channel", 0) + compareChannelsInfoTxCount(result2, result3, "commonchannel", 0) + compareChannelsInfoTxCount(result2, result3, "org2channel", 0) + + action = "invoke" + inputSpecPath = "apitest-input-multiprofile-invoke-org2.yml" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(2 * time.Second) + + resp4 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result4 := resp4.Result().(*ChannelsInfoResp) + + compareChannelsInfoBlockCount(result3, result4, "commonchannel", 0) + compareChannelsInfoBlockCount(result3, result4, "org2channel", 1) + compareChannelsInfoTxCount(result3, result4, "commonchannel", 0) + compareChannelsInfoTxCount(result3, result4, "org2channel", 1) + + action = "invoke" + inputSpecPath = "apitest-input-multiprofile-invoke-common.yml" + err = testclient.Testclient(action, inputSpecPath) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(2 * time.Second) + + resp5 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result5 := resp5.Result().(*ChannelsInfoResp) + + compareChannelsInfoBlockCount(result4, result5, "commonchannel", 1) + compareChannelsInfoBlockCount(result4, result5, "org2channel", 0) + compareChannelsInfoTxCount(result4, result5, "commonchannel", 1) + compareChannelsInfoTxCount(result4, result5, "org2channel", 0) + }) + }) + + Context("/api/block/(channelHash)/(blockHeight)", func() { + + It("get block info for org1", func() { + + resp1 := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org1-network"}, &LoginResponse{}) + result1 := resp1.Result().(*LoginResponse) + token := result1.Token + Expect(result1.User.Message).Should(Equal("logged in")) + + resp2 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result2 := resp2.Result().(*ChannelsInfoResp) + + channelGenesisHash := result2.getGenesisHash("org1channel") + latestBlockNum := result2.getBlockHeight("org1channel") - 1 + Expect(len(channelGenesisHash)).ShouldNot(Equal(0)) + + resp3 := restGetWithToken("/api/block/"+channelGenesisHash+"/"+strconv.Itoa(latestBlockNum), &BlockResp{}, token) + result3 := resp3.Result().(*BlockResp) + Expect(result3.Status).Should(Equal(200)) + Expect(strconv.Atoi(result3.Number)).Should(Equal(latestBlockNum)) + Expect(len(result3.Transactions)).Should(Equal(1)) + + channelGenesisHash = result2.getGenesisHash("commonchannel") + latestBlockNum = result2.getBlockHeight("commonchannel") - 1 + Expect(len(channelGenesisHash)).ShouldNot(Equal(0)) + + resp3 = restGetWithToken("/api/block/"+channelGenesisHash+"/"+strconv.Itoa(latestBlockNum), &BlockResp{}, token) + result3 = resp3.Result().(*BlockResp) + Expect(result3.Status).Should(Equal(200)) + Expect(strconv.Atoi(result3.Number)).Should(Equal(latestBlockNum)) + Expect(len(result3.Transactions)).Should(Equal(1)) + }) + + It("get block info for org2", func() { + + resp1 := restPost("/auth/login", map[string]interface{}{"user": "admin", "password": "adminpw", "network": "org2-network"}, &LoginResponse{}) + result1 := resp1.Result().(*LoginResponse) + token := result1.Token + Expect(result1.User.Message).Should(Equal("logged in")) + + resp2 := restGetWithToken("/api/channels/info", &ChannelsInfoResp{}, token) + result2 := resp2.Result().(*ChannelsInfoResp) + + channelGenesisHash := result2.getGenesisHash("org2channel") + latestBlockNum := result2.getBlockHeight("org2channel") - 1 + Expect(len(channelGenesisHash)).ShouldNot(Equal(0)) + + resp3 := restGetWithToken("/api/block/"+channelGenesisHash+"/"+strconv.Itoa(latestBlockNum), &BlockResp{}, token) + result3 := resp3.Result().(*BlockResp) + Expect(result3.Status).Should(Equal(200)) + Expect(strconv.Atoi(result3.Number)).Should(Equal(latestBlockNum)) + Expect(len(result3.Transactions)).Should(Equal(1)) + + channelGenesisHash = result2.getGenesisHash("commonchannel") + latestBlockNum = result2.getBlockHeight("commonchannel") - 1 + Expect(len(channelGenesisHash)).ShouldNot(Equal(0)) + + resp3 = restGetWithToken("/api/block/"+channelGenesisHash+"/"+strconv.Itoa(latestBlockNum), &BlockResp{}, token) + result3 = resp3.Result().(*BlockResp) + Expect(result3.Status).Should(Equal(200)) + Expect(strconv.Atoi(result3.Number)).Should(Equal(latestBlockNum)) + Expect(len(result3.Transactions)).Should(Equal(1)) + }) + }) + + // It("get status of peers within org2channel", func() { + // resp := restGetWithToken("/api/peersStatus/"+"org2channel", &PeersStatusResp{}, token) + // result := resp.Result().(*PeersStatusResp) + // Expect(result.Status).Should(Equal(200)) + // }) + + // It("get block activity", func() { + // resp := restGetWithToken("/api/blockActivity/"+channelGenesisHash, &BlockActivityResp{}, token) + // result := resp.Result().(*BlockActivityResp) + // Expect(result.Status).Should(Equal(200)) + // Expect(result.Row[0].Channelname).Should(Equal("org2channel")) + // org2CurrentBlockNum = result.Row[0].Blocknum + // }) + + // It("Update block on org1channel and should not have any changes on org2channel", func() { + // resp := restGetWithToken("/blockActivity/"+channelGenesisHash,& + // action = "invoke" + // inputSpecPath = "apitest-input-multiprofile-invoke-org1.yml" + // err := testclient.Testclient(action, inputSpecPath) + // Expect(err).NotTo(HaveOccurred()) + + // resp := restGetWithToken("/api/blockActivity/"+channelGenesisHash, &BlockActivityResp{}, token) + // result := resp.Result().(*BlockActivityResp) + // Expect(result.Status).Should(Equal(200)) + // Expect(result.Row[0].Channelname).Should(Equal("org2channel")) + // Expect(result.Row[0].Blocknum).Should(Equal(org2CurrentBlockNum)) + // }) + + // It("Update block on org2channel and should have some changes on org2channel", func() { + // action = "invoke" + // inputSpecPath = "apitest-input-multiprofile-invoke-org2.yml" + // err := testclient.Testclient(action, inputSpecPath) + // Expect(err).NotTo(HaveOccurred()) + + // resp := restGetWithToken("/api/blockActivity/"+channelGenesisHash, &BlockActivityResp{}, token) + // result := resp.Result().(*BlockActivityResp) + // Expect(result.Status).Should(Equal(200)) + // Expect(result.Row[0].Channelname).Should(Equal("org2channel")) + // Expect(result.Row[0].Blocknum).Should(Equal(org2CurrentBlockNum + 1)) + // }) + + // XIt("register user", func() { + // resp := restPostWithToken("/api/register", map[string]interface{}{"user": "test", "password": "test", "affiliation": "department2", "role": "admin"}, &RegisterResp{}, token) + // resultRegister := resp.Result().(*RegisterResp) + // Expect(resultRegister.Status).Should(Equal(200)) + // }) + + // XIt("login with newly registered user", func() { + // resp := restPost("/auth/login", map[string]interface{}{"user": "test", "password": "test", "network": "org2-network"}, &LoginResponse{}) + // resultLogin := resp.Result().(*LoginResponse) + + // Expect(resultLogin.User.Message).Should(Equal("logged in")) + // Expect(resultLogin.User.Name).Should(Equal("test")) + // }) + + // XIt("fail to register duplicate user", func() { + // resp := restPostWithToken("/api/register", map[string]interface{}{"user": "test", "password": "test", "affiliation": "department2", "role": "admin"}, &RegisterResp{}, token) + // resultRegister := resp.Result().(*RegisterResp) + // Expect(resultRegister.Status).Should(Equal(400)) + // Expect(resultRegister.Message).Should(Equal("Error: already exists")) + // }) + + It("stop explorer", func() { + _, err := networkclient.ExecuteCommand("./stopexplorer.sh", []string{}, true) + Expect(err).NotTo(HaveOccurred()) + }) + + It("Shutdown network", func() { + err := launcher.Launcher("down", "docker", "", networkSpecPath) + Expect(err).NotTo(HaveOccurred()) + + dockerList := []string{"ps", "-aq", "-f", "status=exited"} + containerList, _ := networkclient.ExecuteCommand("docker", dockerList, false) + if containerList != "" { + list := strings.Split(containerList, "\n") + containerArgs := []string{"rm", "-f"} + containerArgs = append(containerArgs, list...) + networkclient.ExecuteCommand("docker", containerArgs, true) + } + ccimagesList := []string{"images", "-q", "--filter=reference=dev*"} + images, _ := networkclient.ExecuteCommand("docker", ccimagesList, false) + if images != "" { + list := strings.Split(images, "\n") + imageArgs := []string{"rmi", "-f"} + imageArgs = append(imageArgs, list...) + networkclient.ExecuteCommand("docker", imageArgs, true) + } + }) }) + }) diff --git a/app/platform/fabric/service/NetworkService.js b/app/platform/fabric/service/NetworkService.js index f70801628..cce4b85a3 100644 --- a/app/platform/fabric/service/NetworkService.js +++ b/app/platform/fabric/service/NetworkService.js @@ -31,12 +31,15 @@ class NetworkService { // Get the list of the networks from the configuration that was loaded from the config.json const networklist = []; const networks = this.platform.getNetworks(); + logger.debug('Network list ', networks); const iterator = networks.entries(); for (const value of iterator) { - networklist.push(value); + const network_name = value[0]; + logger.debug('Network list ', network_name); + networklist.push([network_name]); } - logger.log('Network list ', networklist); + logger.debug('Network list ', networklist); return networklist; } } diff --git a/app/platform/fabric/service/UserService.js b/app/platform/fabric/service/UserService.js index 286e0f646..d493d0cf8 100644 --- a/app/platform/fabric/service/UserService.js +++ b/app/platform/fabric/service/UserService.js @@ -45,20 +45,16 @@ class UserService { let adminPassword = null; if (user.user && user.password && user.network) { logger.log('user.network ', user.network); - const network = this.platform.getNetworks().get(user.network); + const clientObj = this.platform.getNetworks().get(user.network); // TODO, need review maybe there is a better way to get the client config enableAuthentication - for (const [network_name, clients] of network.entries()) { - if (clients.config && clients.config.client) { - enableAuth = clients.config.client.enableAuthentication; - if (typeof enableAuth !== 'undefined' && enableAuth !== null) { - logger.info( - `Network: ${network_name} enableAuthentication ${enableAuth}` - ); - adminUser = clients.config.client.adminUser; - adminPassword = clients.config.client.adminPassword; - break; - } + let client = clientObj.instance; + if (client.config && client.config.client) { + enableAuth = client.config.client.enableAuthentication; + if (typeof enableAuth !== 'undefined' && enableAuth !== null) { + logger.info(`Network: ${user.network} enableAuthentication ${enableAuth}`); + adminUser = client.config.client.adminUser; + adminPassword = client.config.client.adminPassword; } } @@ -67,7 +63,8 @@ class UserService { return { authenticated: true, user: user.user, - enableAuthentication: enableAuth + enableAuthentication: enableAuth, + network: user.network }; } @@ -76,7 +73,8 @@ class UserService { return { authenticated: true, user: user.user, - enableAuthentication: enableAuth + enableAuthentication: enableAuth, + network: user.network }; } else { return { @@ -276,10 +274,7 @@ class UserService { fabricGw.gateway.disconnect(); // Connect to gateway - await fabricGw.gateway.connect( - fabricGw.config, - connectionOptions - ); + await fabricGw.gateway.connect(fabricGw.config, connectionOptions); logger.debug('Successfully reconnected with ', username); } catch (err) { throw new Error('Failed to reconnect: ' + err.toString()); diff --git a/app/platform/fabric/sync/SyncPlatform.js b/app/platform/fabric/sync/SyncPlatform.js index 1029775da..fd1827d3b 100644 --- a/app/platform/fabric/sync/SyncPlatform.js +++ b/app/platform/fabric/sync/SyncPlatform.js @@ -100,12 +100,15 @@ class SyncPlatform { this.client = await FabricUtils.createFabricClient( this.client_configs, + this.network_name, this.client_name ); if (!this.client) { throw new ExplorerError(explorer_mess.error.ERROR_2011); } + this.client.network_name = this.network_name; + // Updating the client network and other details to DB const res = await this.syncService.synchNetworkConfigToDB(this.client); if (!res) { diff --git a/app/platform/fabric/sync/SyncService.js b/app/platform/fabric/sync/SyncService.js index e237f4385..f4b33f317 100644 --- a/app/platform/fabric/sync/SyncService.js +++ b/app/platform/fabric/sync/SyncService.js @@ -118,15 +118,15 @@ class SyncServices { */ async insertNewChannel(client, channel, block, channel_genesis_hash) { const channel_name = channel.getName(); - + const network_name = client.network_name; const channelInfo = await this.persistence .getCrudService() - .getChannel(channel_name, channel_genesis_hash); + .getChannel(network_name, channel_name, channel_genesis_hash); if (!channelInfo) { const count = await this.persistence .getCrudService() - .existChannel(channel_name); + .existChannel(network_name, channel_name); if (count.count === '0') { if (block.data && block.data.data.length > 0 && block.data.data[0]) { const createdt = await FabricUtils.getBlockTimeStamp( @@ -141,7 +141,9 @@ class SyncServices { channel_version: block.data.data[0].payload.header.channel_header.version, channel_genesis_hash }; - await this.persistence.getCrudService().saveChannel(channel_row); + await this.persistence + .getCrudService() + .saveChannel(network_name, channel_row); } } else { const notify = { @@ -211,6 +213,7 @@ class SyncServices { async insertNewPeer(peer, channel_genesis_hash, client) { let eventurl = ''; let requesturl = peer.endpoint; + const network_name = client.network_name; const host_port = peer.endpoint.split(':'); if ( client.client_config.peers && @@ -235,12 +238,14 @@ class SyncServices { channel_genesis_hash, peer_type: 'PEER' }; - await this.persistence.getCrudService().savePeer(peer_row); + await this.persistence.getCrudService().savePeer(network_name, peer_row); const channel_peer_row = { peerid: host_port[0], channelid: channel_genesis_hash }; - await this.persistence.getCrudService().savePeerChannelRef(channel_peer_row); + await this.persistence + .getCrudService() + .savePeerChannelRef(network_name, channel_peer_row); } /** @@ -252,6 +257,7 @@ class SyncServices { * @memberof SyncServices */ async insertNewOrderers(orderer, channel_genesis_hash, client) { + const network_name = client.network_name; const discoveryProtocol = client.hfc_client.getConfigSetting( 'discovery-protocol' ); @@ -270,14 +276,14 @@ class SyncServices { channel_genesis_hash, peer_type: 'ORDERER' }; - await this.persistence.getCrudService().savePeer(orderer_row); + await this.persistence.getCrudService().savePeer(network_name, orderer_row); const channel_orderer_row = { peerid: orderer.host, channelid: channel_genesis_hash }; await this.persistence .getCrudService() - .savePeerChannelRef(channel_orderer_row); + .savePeerChannelRef(network_name, channel_orderer_row); } /** @@ -295,6 +301,7 @@ class SyncServices { channel_genesis_hash, discoveryResults ) { + const network_name = client.network_name; const chaincodes = await channel.queryInstantiatedChaincodes( client.getDefaultPeer(), true @@ -308,7 +315,9 @@ class SyncServices { createdt: new Date(), channel_genesis_hash }; - await this.persistence.getCrudService().saveChaincode(chaincode_row); + await this.persistence + .getCrudService() + .saveChaincode(network_name, chaincode_row); if (discoveryResults && discoveryResults.peers_by_org) { for (const org_name in discoveryResults.peers_by_org) { const org = discoveryResults.peers_by_org[org_name]; @@ -319,6 +328,7 @@ class SyncServices { c_code.version === chaincode.version ) { await this.insertNewChaincodePeerRef( + client, c_code, peer.endpoint, channel_genesis_hash @@ -339,7 +349,13 @@ class SyncServices { * @param {*} channel_genesis_hash * @memberof SyncServices */ - async insertNewChaincodePeerRef(chaincode, endpoint, channel_genesis_hash) { + async insertNewChaincodePeerRef( + client, + chaincode, + endpoint, + channel_genesis_hash + ) { + const network_name = client.network_name; const host_port = endpoint.split(':'); const chaincode_peer_row = { chaincodeid: chaincode.name, @@ -349,10 +365,11 @@ class SyncServices { }; await this.persistence .getCrudService() - .saveChaincodPeerRef(chaincode_peer_row); + .saveChaincodPeerRef(network_name, chaincode_peer_row); } async synchBlocks(client, channel) { + const network_name = client.network_name; const client_name = client.getClientName(); const channel_name = channel.getName(); @@ -373,7 +390,7 @@ class SyncServices { // Query missing blocks from DB const results = await this.persistence .getMetricService() - .findMissingBlockNumber(channel_genesis_hash, blockHeight); + .findMissingBlockNumber(network_name, channel_genesis_hash, blockHeight); if (results) { for (const result of results) { @@ -400,6 +417,7 @@ class SyncServices { * @memberof SyncServices */ async processBlockEvent(client, block) { + const network_name = client.network_name; const _self = this; // Get the first transaction const first_tx = block.data.data[0]; @@ -633,20 +651,23 @@ class SyncServices { endorser_signature, creator_id_bytes, payload_proposal_hash, - endorser_id_bytes + endorser_id_bytes, + network_name }; // Insert transaction const res = await this.persistence .getCrudService() - .saveTransaction(transaction_row); + .saveTransaction(network_name, transaction_row); logger.debug('saveTransaction ', res); } // Insert block logger.info('block_row.blocknum ', block_row.blocknum); - const status = await this.persistence.getCrudService().saveBlock(block_row); + const status = await this.persistence + .getCrudService() + .saveBlock(network_name, block_row); logger.debug('status ', status); if (status) { diff --git a/app/platform/fabric/utils/FabricUtils.js b/app/platform/fabric/utils/FabricUtils.js index 8de48b5f6..5961f1e0a 100644 --- a/app/platform/fabric/utils/FabricUtils.js +++ b/app/platform/fabric/utils/FabricUtils.js @@ -15,9 +15,14 @@ const helper = require('../../../common/helper'); const logger = helper.getLogger('FabricUtils'); -async function createFabricClient(client_configs, client_name, persistence) { +async function createFabricClient( + client_configs, + network_name, + client_name, + persistence +) { // Create new FabricClient - const client = new FabricClient(client_name); + const client = new FabricClient(network_name, client_name); // Initialize fabric client logger.debug( '************ Initializing fabric client for [%s]************', @@ -31,11 +36,16 @@ async function createFabricClient(client_configs, client_name, persistence) { } } -async function createDetachClient(client_configs, client_name, persistence) { +async function createDetachClient( + client_configs, + network_name, + client_name, + persistence +) { // Clone global.hfc.config configuration const client_config = cloneConfig(client_configs, client_name); - const client = new FabricClient(client_name); + const client = new FabricClient(network_name, client_name); await client.initializeDetachClient(client_config, persistence); return client; } diff --git a/app/rest/dbroutes.js b/app/rest/dbroutes.js index a3317efc5..d15a0e5d2 100644 --- a/app/rest/dbroutes.js +++ b/app/rest/dbroutes.js @@ -3,6 +3,9 @@ */ const requtil = require('./requestutils.js'); +const helper = require('./../common/helper'); + +const logger = helper.getLogger('dbroutes'); /** * @@ -17,7 +20,7 @@ const dbroutes = (router, platform) => { router.get('/status/:channel_genesis_hash', (req, res) => { const channel_genesis_hash = req.params.channel_genesis_hash; if (channel_genesis_hash) { - dbStatusMetrics.getStatus(channel_genesis_hash, data => { + dbStatusMetrics.getStatus(req.network, channel_genesis_hash, data => { if (data && (data.chaincodeCount && data.txCount && data.peerCount)) { return res.send(data); } @@ -45,6 +48,7 @@ const dbroutes = (router, platform) => { const channel_genesis_hash = req.params.channel_genesis_hash; if (!isNaN(number) && channel_genesis_hash) { const row = await dbCrudService.getTxCountByBlockNum( + req.network, channel_genesis_hash, number ); @@ -78,12 +82,14 @@ const dbroutes = (router, platform) => { const txid = req.params.txid; const channel_genesis_hash = req.params.channel_genesis_hash; if (txid && txid !== '0' && channel_genesis_hash) { - dbCrudService.getTransactionByID(channel_genesis_hash, txid).then(row => { - if (row) { - row.createdt = new Date(row.createdt).toISOString(); - return res.send({ status: 200, row }); - } - }); + dbCrudService + .getTransactionByID(req.network, channel_genesis_hash, txid) + .then(row => { + if (row) { + row.createdt = new Date(row.createdt).toISOString(); + return res.send({ status: 200, row }); + } + }); } else { return requtil.invalidRequest(req, res); } @@ -92,11 +98,13 @@ const dbroutes = (router, platform) => { router.get('/blockActivity/:channel_genesis_hash', (req, res) => { const channel_genesis_hash = req.params.channel_genesis_hash; if (channel_genesis_hash) { - dbCrudService.getBlockActivityList(channel_genesis_hash).then(row => { - if (row) { - return res.send({ status: 200, row }); - } - }); + dbCrudService + .getBlockActivityList(req.network, channel_genesis_hash) + .then(row => { + if (row) { + return res.send({ status: 200, row }); + } + }); } else { return requtil.invalidRequest(req, res); } @@ -128,7 +136,15 @@ const dbroutes = (router, platform) => { } if (channel_genesis_hash) { dbCrudService - .getTxList(channel_genesis_hash, blockNum, txid, from, to, orgs) + .getTxList( + req.network, + channel_genesis_hash, + blockNum, + txid, + from, + to, + orgs + ) .then(rows => { if (rows) { return res.send({ status: 200, rows }); @@ -158,7 +174,7 @@ const dbroutes = (router, platform) => { router.get('/chaincode/:channel', (req, res) => { const channelName = req.params.channel; if (channelName) { - dbStatusMetrics.getTxPerChaincode(channelName, async data => { + dbStatusMetrics.getTxPerChaincode(req.network, channelName, async data => { res.send({ status: 200, chaincode: data @@ -184,7 +200,7 @@ const dbroutes = (router, platform) => { router.get('/peers/:channel_genesis_hash', (req, res) => { const channel_genesis_hash = req.params.channel_genesis_hash; if (channel_genesis_hash) { - dbStatusMetrics.getPeerList(channel_genesis_hash, data => { + dbStatusMetrics.getPeerList(req.network, channel_genesis_hash, data => { res.send({ status: 200, peers: data }); }); } else { @@ -214,8 +230,16 @@ const dbroutes = (router, platform) => { ); if (channel_genesis_hash && !isNaN(blockNum)) { dbCrudService - .getBlockAndTxList(channel_genesis_hash, blockNum, from, to, orgs) + .getBlockAndTxList( + req.network, + channel_genesis_hash, + blockNum, + from, + to, + orgs + ) .then(rows => { + logger.debug('Return getBlockAndTxList ', rows); if (rows) { return res.send({ status: 200, rows }); } @@ -243,12 +267,14 @@ const dbroutes = (router, platform) => { const hours = parseInt(req.params.hours); if (channel_genesis_hash && !isNaN(hours)) { - dbStatusMetrics.getTxByMinute(channel_genesis_hash, hours).then(rows => { - if (rows) { - return res.send({ status: 200, rows }); - } - return requtil.notFound(req, res); - }); + dbStatusMetrics + .getTxByMinute(req.network, channel_genesis_hash, hours) + .then(rows => { + if (rows) { + return res.send({ status: 200, rows }); + } + return requtil.notFound(req, res); + }); } else { return requtil.invalidRequest(req, res); } @@ -268,12 +294,14 @@ const dbroutes = (router, platform) => { const days = parseInt(req.params.days); if (channel_genesis_hash && !isNaN(days)) { - dbStatusMetrics.getTxByHour(channel_genesis_hash, days).then(rows => { - if (rows) { - return res.send({ status: 200, rows }); - } - return requtil.notFound(req, res); - }); + dbStatusMetrics + .getTxByHour(req.network, channel_genesis_hash, days) + .then(rows => { + if (rows) { + return res.send({ status: 200, rows }); + } + return requtil.notFound(req, res); + }); } else { return requtil.invalidRequest(req, res); } @@ -292,12 +320,14 @@ const dbroutes = (router, platform) => { const hours = parseInt(req.params.hours); if (channel_genesis_hash && !isNaN(hours)) { - dbStatusMetrics.getBlocksByMinute(channel_genesis_hash, hours).then(rows => { - if (rows) { - return res.send({ status: 200, rows }); - } - return requtil.notFound(req, res); - }); + dbStatusMetrics + .getBlocksByMinute(req.network, channel_genesis_hash, hours) + .then(rows => { + if (rows) { + return res.send({ status: 200, rows }); + } + return requtil.notFound(req, res); + }); } else { return requtil.invalidRequest(req, res); } @@ -316,12 +346,14 @@ const dbroutes = (router, platform) => { const days = parseInt(req.params.days); if (channel_genesis_hash && !isNaN(days)) { - dbStatusMetrics.getBlocksByHour(channel_genesis_hash, days).then(rows => { - if (rows) { - return res.send({ status: 200, rows }); - } - return requtil.notFound(req, res); - }); + dbStatusMetrics + .getBlocksByHour(req.network, channel_genesis_hash, days) + .then(rows => { + if (rows) { + return res.send({ status: 200, rows }); + } + return requtil.notFound(req, res); + }); } else { return requtil.invalidRequest(req, res); } diff --git a/app/rest/platformroutes.js b/app/rest/platformroutes.js index 902a65629..2c8f86b25 100644 --- a/app/rest/platformroutes.js +++ b/app/rest/platformroutes.js @@ -25,7 +25,7 @@ const platformroutes = async function(router, platform) { if (channel_genesis_hash) { proxy - .getTxByOrgs(channel_genesis_hash) + .getTxByOrgs(req.network, channel_genesis_hash) .then(rows => res.send({ status: 200, rows })); } else { return requtil.invalidRequest(req, res); @@ -47,7 +47,7 @@ const platformroutes = async function(router, platform) { */ router.get('/channels/info', (req, res) => { proxy - .getChannelsInfo() + .getChannelsInfo(req.network) .then(data => { data.forEach(element => { element.createdat = new Date(element.createdat).toISOString(); @@ -72,7 +72,7 @@ const platformroutes = async function(router, platform) { router.get('/peersStatus/:channel', (req, res) => { const channelName = req.params.channel; if (channelName) { - proxy.getPeersStatus(channelName).then(data => { + proxy.getPeersStatus(req.network, channelName).then(data => { res.send({ status: 200, peers: data }); }); } else { @@ -90,15 +90,21 @@ const platformroutes = async function(router, platform) { const number = parseInt(req.params.number); const channel_genesis_hash = req.params.channel_genesis_hash; if (!isNaN(number) && channel_genesis_hash) { - proxy.getBlockByNumber(channel_genesis_hash, number).then(block => { - res.send({ - status: 200, - number: block.header.number.toString(), - previous_hash: block.header.previous_hash, - data_hash: block.header.data_hash, - transactions: block.data.data + proxy + .getBlockByNumber(req.network, channel_genesis_hash, number) + .then(block => { + if (typeof block === 'string') { + res.send({ status: 500, error: block }); + } else { + res.send({ + status: 200, + number: block.header.number.toString(), + previous_hash: block.header.previous_hash, + data_hash: block.header.data_hash, + transactions: block.data.data + }); + } }); - }); } else { return requtil.invalidRequest(req, res); } @@ -118,7 +124,7 @@ const platformroutes = async function(router, platform) { * } */ router.get('/channels', (req, res) => { - proxy.getChannels().then(channels => { + proxy.getChannels(req.network).then(channels => { const response = { status: 200 }; @@ -133,7 +139,7 @@ const platformroutes = async function(router, platform) { * curl -i 'http://:/curChannel' */ router.get('/curChannel', (req, res) => { - proxy.getCurrentChannel().then(data => { + proxy.getCurrentChannel(req.network).then(data => { res.send(data); }); }); @@ -145,36 +151,12 @@ const platformroutes = async function(router, platform) { */ router.get('/changeChannel/:channel_genesis_hash', (req, res) => { const channel_genesis_hash = req.params.channel_genesis_hash; - proxy.changeChannel(channel_genesis_hash).then(data => { + proxy.changeChannel(req.network, channel_genesis_hash).then(data => { res.send({ currentChannel: data }); }); }); - - /** - * *Peer Status List - * GET /peerlist -> /peersStatus - * curl -i 'http://:/peersStatus/' - * Response: - * [ - * { - * 'requests': 'grpcs://127.0.0.1:7051', - * 'server_hostname': 'peer0.org1.example.com' - * } - * ] - */ - - router.get('/peersStatus/:channel', (req, res) => { - const channelName = req.params.channel; - if (channelName) { - proxy.getPeersStatus(channelName).then(data => { - res.send({ status: 200, peers: data }); - }); - } else { - return requtil.invalidRequest(req, res); - } - }); }; // End platformroutes() module.exports = platformroutes; diff --git a/ci/azure-pipelines.yml b/ci/azure-pipelines.yml index 284dd097c..693f049e4 100644 --- a/ci/azure-pipelines.yml +++ b/ci/azure-pipelines.yml @@ -3,6 +3,8 @@ name: $(SourceBranchName)-$(Date:yyyyMMdd)$(Rev:.rrr) trigger: - master +pr: +- master variables: GOPATH: $(Agent.BuildDirectory)/go diff --git a/client/e2e-test/docker-compose-explorer.yaml b/client/e2e-test/docker-compose-explorer.yaml index 2f38d8d31..7fcf6968a 100644 --- a/client/e2e-test/docker-compose-explorer.yaml +++ b/client/e2e-test/docker-compose-explorer.yaml @@ -24,7 +24,6 @@ services: - DATABASE_USERNAME=hppoc - DATABASE_PASSWORD=password volumes: - - ./../../app/persistence/fabric/postgreSQL/db/createdb.sh:/docker-entrypoint-initdb.d/createdb.sh - pgdata:/var/lib/postgresql/data networks: - mynetwork.com diff --git a/docker-compose.yaml b/docker-compose.yaml index 111662e92..86b30c5a0 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -29,7 +29,6 @@ services: timeout: 10s retries: 5 volumes: - - ./app/persistence/fabric/postgreSQL/db/createdb.sh:/docker-entrypoint-initdb.d/createdb.sh - pgdata:/var/lib/postgresql/data networks: - mynetwork.com diff --git a/examples/net1/config.json b/examples/net1/config.json index b0b36e226..29b9812cb 100644 --- a/examples/net1/config.json +++ b/examples/net1/config.json @@ -1,7 +1,7 @@ { "network-configs": { "first-network": { - "name": "firstnetwork", + "name": "first-network", "profile": "./connection-profile/first-network.json" } }, diff --git a/postgres-Dockerfile b/postgres-Dockerfile index 465e564d0..503561326 100644 --- a/postgres-Dockerfile +++ b/postgres-Dockerfile @@ -23,7 +23,7 @@ RUN apk update \ WORKDIR /opt # Copy files -COPY app/persistence/fabric/postgreSQL/db/explorerpg.sql /opt/explorerpg.sql -COPY app/persistence/fabric/postgreSQL/db/updatepg.sql /opt/updatepg.sql -COPY app/persistence/fabric/postgreSQL/db/createdb.sh /opt/createdb.sh -COPY app/persistence/fabric/postgreSQL/db/processenv.js /opt/processenv.js \ No newline at end of file +COPY app/persistence/fabric/postgreSQL/db/explorerpg.sql /opt/explorerpg.sql +COPY app/persistence/fabric/postgreSQL/db/updatepg.sql /opt/updatepg.sql +COPY app/persistence/fabric/postgreSQL/db/createdb.sh /docker-entrypoint-initdb.d/createdb.sh +COPY app/persistence/fabric/postgreSQL/db/processenv.js /opt/processenv.js \ No newline at end of file