/** * 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'); const 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) { if (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 with status: %s reason: %s', channelName, response.status, response.info); logger.error(error_message); } } 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); const response = { success: true, message: message }; return response; } else { let message = util.format('Failed to update anchor peers. cause:%s',error_message); logger.error(message); const response = { success: false, message: message }; return response; } }; exports.updateAnchorPeers = updateAnchorPeers;