From df311ce23aa9b9b77e8f9206b0f06d5538bc64d6 Mon Sep 17 00:00:00 2001 From: Yuki Kondo Date: Mon, 8 Oct 2018 23:55:46 +0000 Subject: [PATCH] [FAB-12173] balance-transfer: Update anchor peers Currently, balance-transfer does not have anchor peer configuration. As a result, users are unable to use private data and can't take advantage of service discovery. This CR adds a function and modifies a test script to update anchor peers at the setup. Change-Id: Icbd7e4eb2e3bbcb187a083e94c616ef4825c5fb4 Signed-off-by: Yuki Kondo --- balance-transfer/app.js | 20 +++ balance-transfer/app/update-anchor-peers.js | 114 ++++++++++++++++++ .../artifacts/channel/Org1MSPanchors.tx | Bin 0 -> 284 bytes .../artifacts/channel/Org2MSPanchors.tx | Bin 0 -> 284 bytes balance-transfer/testAPIs.sh | 24 ++++ 5 files changed, 158 insertions(+) create mode 100644 balance-transfer/app/update-anchor-peers.js create mode 100644 balance-transfer/artifacts/channel/Org1MSPanchors.tx create mode 100644 balance-transfer/artifacts/channel/Org2MSPanchors.tx diff --git a/balance-transfer/app.js b/balance-transfer/app.js index cffddce80a..83b1226ab4 100644 --- a/balance-transfer/app.js +++ b/balance-transfer/app.js @@ -34,6 +34,7 @@ var hfc = require('fabric-client'); var helper = require('./app/helper.js'); var createChannel = require('./app/create-channel.js'); var join = require('./app/join-channel.js'); +var updateAnchorPeers = require('./app/update-anchor-peers.js'); var install = require('./app/install-chaincode.js'); var instantiate = require('./app/instantiate-chaincode.js'); var invoke = require('./app/invoke-transaction.js'); @@ -179,6 +180,25 @@ app.post('/channels/:channelName/peers', async function(req, res) { let message = await join.joinChannel(channelName, peers, req.username, req.orgname); res.send(message); }); +// Update anchor peers +app.post('/channels/:channelName/anchorpeers', async function(req, res) { + logger.debug('==================== UPDATE ANCHOR PEERS =================='); + var channelName = req.params.channelName; + var configUpdatePath = req.body.configUpdatePath; + logger.debug('Channel name : ' + channelName); + logger.debug('configUpdatePath : ' + configUpdatePath); + if (!channelName) { + res.json(getErrorMessage('\'channelName\'')); + return; + } + if (!configUpdatePath) { + res.json(getErrorMessage('\'configUpdatePath\'')); + return; + } + + let message = await updateAnchorPeers.updateAnchorPeers(channelName, configUpdatePath, req.username, req.orgname); + res.send(message); +}); // Install chaincode on target peers app.post('/chaincodes', async function(req, res) { logger.debug('==================== INSTALL CHAINCODE =================='); diff --git a/balance-transfer/app/update-anchor-peers.js b/balance-transfer/app/update-anchor-peers.js new file mode 100644 index 0000000000..aa961c87c7 --- /dev/null +++ b/balance-transfer/app/update-anchor-peers.js @@ -0,0 +1,114 @@ +/** + * Copyright Hitachi America, Ltd. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; +var util = require('util'); +var fs = require('fs'); +var path = require('path'); + +var helper = require('./helper.js'); +var logger = helper.getLogger('update-anchor-peers'); + +var updateAnchorPeers = async function(channelName, configUpdatePath, username, org_name) { + logger.debug('\n====== Updating Anchor Peers on \'' + channelName + '\' ======\n'); + var error_message = null; + try { + // first setup the client for this org + var client = await helper.getClientForOrg(org_name, username); + logger.debug('Successfully got the fabric client for the organization "%s"', org_name); + var channel = client.getChannel(channelName); + if(!channel) { + let message = util.format('Channel %s was not defined in the connection profile', channelName); + logger.error(message); + throw new Error(message); + } + + // read in the envelope for the channel config raw bytes + var envelope = fs.readFileSync(path.join(__dirname, configUpdatePath)); + // extract the channel config bytes from the envelope to be signed + var channelConfig = client.extractChannelConfig(envelope); + + //Acting as a client in the given organization provided with "orgName" param + // sign the channel config bytes as "endorsement", this is required by + // the orderer's channel creation policy + // this will use the admin identity assigned to the client when the connection profile was loaded + let signature = client.signChannelConfig(channelConfig); + + let request = { + config: channelConfig, + signatures: [signature], + name: channelName, + txId: client.newTransactionID(true) // get an admin based transactionID + }; + + var promises = []; + let event_hubs = channel.getChannelEventHubsForOrg(); + logger.debug('found %s eventhubs for this organization %s',event_hubs.length, org_name); + event_hubs.forEach((eh) => { + let anchorUpdateEventPromise = new Promise((resolve, reject) => { + logger.debug('anchorUpdateEventPromise - setting up event'); + let event_timeout = setTimeout(() => { + let message = 'REQUEST_TIMEOUT:' + eh.getPeerAddr(); + logger.error(message); + eh.disconnect(); + }, 60000); + eh.registerBlockEvent((block) => { + logger.info('The config update has been committed on peer %s',eh.getPeerAddr()); + clearTimeout(event_timeout); + resolve(); + }, (err) => { + clearTimeout(event_timeout); + logger.error(err); + reject(err); + }, + // the default for 'unregister' is true for block listeners + // so no real need to set here, however for 'disconnect' + // the default is false as most event hubs are long running + // in this use case we are using it only once + {unregister: true, disconnect: true} + ); + eh.connect(); + }); + promises.push(anchorUpdateEventPromise); + }); + + var sendPromise = client.updateChannel(request); + // put the send to the orderer last so that the events get registered and + // are ready for the orderering and committing + promises.push(sendPromise); + let results = await Promise.all(promises); + logger.debug(util.format('------->>> R E S P O N S E : %j', results)); + let response = results.pop(); // orderer results are last in the results + + if (response && response.status === 'SUCCESS') { + logger.info('Successfully update anchor peers to the channel %s', channelName); + } else { + error_message = util.format('Failed to update anchor peers to the channel %s', channelName); + logger.error(error_message); + } + } catch (error) { + logger.error('Failed to update anchor peers due to error: ' + error.stack ? error.stack : error); + error_message = error.toString(); + } + + if (!error_message) { + let message = util.format( + 'Successfully update anchor peers in organization %s to the channel \'%s\'', + org_name, channelName); + logger.info(message); + let response = { + success: true, + message: message + }; + return response; + } else { + let message = util.format('Failed to update anchor peers. cause:%s',error_message); + logger.error(message); + throw new Error(message); + } +}; + +exports.updateAnchorPeers = updateAnchorPeers; diff --git a/balance-transfer/artifacts/channel/Org1MSPanchors.tx b/balance-transfer/artifacts/channel/Org1MSPanchors.tx new file mode 100644 index 0000000000000000000000000000000000000000..104ee50e05f779149e3447269ac3990a264bd081 GIT binary patch literal 284 zcmd;@$;8Fa#mm8@#F<-}oROH9mzpEg%EZ;g#DydfE)>ee?O0HdlbM`Yl9`_;8yp~{FU8Kq3}P@SadWW;r6#7N78OG{;YFDx5Dpg?n`26DW*$&N3(At3 z%_ua35!L7pMxfa>2(t@07~!T%nE}=2C1>Op1*C!uRTq-wlI9XC0CEiU@_~-gORY%E XEyzjLOU};~=r)&v+C!SFV6FoIk7Y?N literal 0 HcmV?d00001 diff --git a/balance-transfer/artifacts/channel/Org2MSPanchors.tx b/balance-transfer/artifacts/channel/Org2MSPanchors.tx new file mode 100644 index 0000000000000000000000000000000000000000..eaaf1d7f12187c6bbf19d3f405cba5f90dad353a GIT binary patch literal 284 zcmd;@$;8Fa#mm8@#F<-}oROH9mzpEg%EZ;g#DydfE)>ee?O0HdlbM`Yl9`_;2(t@07~!T%nE}=2C1>Op1*C!uRTq-wlI9XC0CEiU@_~-gORY%E XEyzjLOU};~=r)&v+C!SFV6FoIkqt>P literal 0 HcmV?d00001 diff --git a/balance-transfer/testAPIs.sh b/balance-transfer/testAPIs.sh index 8528924c32..e48ec039d3 100755 --- a/balance-transfer/testAPIs.sh +++ b/balance-transfer/testAPIs.sh @@ -112,6 +112,30 @@ curl -s -X POST \ echo echo +echo "POST request Update anchor peers on Org1" +echo +curl -s -X POST \ + http://localhost:4000/channels/mychannel/anchorpeers \ + -H "authorization: Bearer $ORG1_TOKEN" \ + -H "content-type: application/json" \ + -d '{ + "configUpdatePath":"../artifacts/channel/Org1MSPanchors.tx" +}' +echo +echo + +echo "POST request Update anchor peers on Org2" +echo +curl -s -X POST \ + http://localhost:4000/channels/mychannel/anchorpeers \ + -H "authorization: Bearer $ORG2_TOKEN" \ + -H "content-type: application/json" \ + -d '{ + "configUpdatePath":"../artifacts/channel/Org2MSPanchors.tx" +}' +echo +echo + echo "POST Install chaincode on Org1" echo curl -s -X POST \