|  | 
|  | 1 | +/** | 
|  | 2 | + * Copyright Hitachi America, Ltd. All Rights Reserved. | 
|  | 3 | + * | 
|  | 4 | + * SPDX-License-Identifier: Apache-2.0 | 
|  | 5 | + */ | 
|  | 6 | + | 
|  | 7 | +'use strict'; | 
|  | 8 | +var util = require('util'); | 
|  | 9 | +var fs = require('fs'); | 
|  | 10 | +var path = require('path'); | 
|  | 11 | + | 
|  | 12 | +var helper = require('./helper.js'); | 
|  | 13 | +var logger = helper.getLogger('update-anchor-peers'); | 
|  | 14 | + | 
|  | 15 | +var updateAnchorPeers = async function(channelName, configUpdatePath, username, org_name) { | 
|  | 16 | +	logger.debug('\n====== Updating Anchor Peers on \'' + channelName + '\' ======\n'); | 
|  | 17 | +	var error_message = null; | 
|  | 18 | +	try { | 
|  | 19 | +		// first setup the client for this org | 
|  | 20 | +		var client = await helper.getClientForOrg(org_name, username); | 
|  | 21 | +		logger.debug('Successfully got the fabric client for the organization "%s"', org_name); | 
|  | 22 | +		var channel = client.getChannel(channelName); | 
|  | 23 | +		if(!channel) { | 
|  | 24 | +			let message = util.format('Channel %s was not defined in the connection profile', channelName); | 
|  | 25 | +			logger.error(message); | 
|  | 26 | +			throw new Error(message); | 
|  | 27 | +		} | 
|  | 28 | + | 
|  | 29 | +		// read in the envelope for the channel config raw bytes | 
|  | 30 | +		var envelope = fs.readFileSync(path.join(__dirname, configUpdatePath)); | 
|  | 31 | +		// extract the channel config bytes from the envelope to be signed | 
|  | 32 | +		var channelConfig = client.extractChannelConfig(envelope); | 
|  | 33 | + | 
|  | 34 | +		//Acting as a client in the given organization provided with "orgName" param | 
|  | 35 | +		// sign the channel config bytes as "endorsement", this is required by | 
|  | 36 | +		// the orderer's channel creation policy | 
|  | 37 | +		// this will use the admin identity assigned to the client when the connection profile was loaded | 
|  | 38 | +		let signature = client.signChannelConfig(channelConfig); | 
|  | 39 | + | 
|  | 40 | +		let request = { | 
|  | 41 | +			config: channelConfig, | 
|  | 42 | +			signatures: [signature], | 
|  | 43 | +			name: channelName, | 
|  | 44 | +			txId: client.newTransactionID(true) // get an admin based transactionID | 
|  | 45 | +		}; | 
|  | 46 | + | 
|  | 47 | +		var promises = []; | 
|  | 48 | +		let event_hubs = channel.getChannelEventHubsForOrg(); | 
|  | 49 | +		logger.debug('found %s eventhubs for this organization %s',event_hubs.length, org_name); | 
|  | 50 | +		event_hubs.forEach((eh) => { | 
|  | 51 | +			let anchorUpdateEventPromise = new Promise((resolve, reject) => { | 
|  | 52 | +				logger.debug('anchorUpdateEventPromise - setting up event'); | 
|  | 53 | +				let event_timeout = setTimeout(() => { | 
|  | 54 | +					let message = 'REQUEST_TIMEOUT:' + eh.getPeerAddr(); | 
|  | 55 | +					logger.error(message); | 
|  | 56 | +					eh.disconnect(); | 
|  | 57 | +				}, 60000); | 
|  | 58 | +				eh.registerBlockEvent((block) => { | 
|  | 59 | +					logger.info('The config update has been committed on peer %s',eh.getPeerAddr()); | 
|  | 60 | +					clearTimeout(event_timeout); | 
|  | 61 | +					resolve(); | 
|  | 62 | +				}, (err) => { | 
|  | 63 | +					clearTimeout(event_timeout); | 
|  | 64 | +					logger.error(err); | 
|  | 65 | +					reject(err); | 
|  | 66 | +				}, | 
|  | 67 | +					// the default for 'unregister' is true for block listeners | 
|  | 68 | +					// so no real need to set here, however for 'disconnect' | 
|  | 69 | +					// the default is false as most event hubs are long running | 
|  | 70 | +					// in this use case we are using it only once | 
|  | 71 | +					{unregister: true, disconnect: true} | 
|  | 72 | +				); | 
|  | 73 | +				eh.connect(); | 
|  | 74 | +			}); | 
|  | 75 | +			promises.push(anchorUpdateEventPromise); | 
|  | 76 | +		}); | 
|  | 77 | + | 
|  | 78 | +		var sendPromise = client.updateChannel(request); | 
|  | 79 | +		// put the send to the orderer last so that the events get registered and | 
|  | 80 | +		// are ready for the orderering and committing | 
|  | 81 | +		promises.push(sendPromise); | 
|  | 82 | +		let results = await Promise.all(promises); | 
|  | 83 | +		logger.debug(util.format('------->>> R E S P O N S E : %j', results)); | 
|  | 84 | +		let response = results.pop(); //  orderer results are last in the results | 
|  | 85 | + | 
|  | 86 | +		if (response && response.status === 'SUCCESS') { | 
|  | 87 | +			logger.info('Successfully update anchor peers to the channel %s', channelName); | 
|  | 88 | +		} else { | 
|  | 89 | +			error_message = util.format('Failed to update anchor peers to the channel %s', channelName); | 
|  | 90 | +			logger.error(error_message); | 
|  | 91 | +		} | 
|  | 92 | +	} catch (error) { | 
|  | 93 | +		logger.error('Failed to update anchor peers due to error: ' + error.stack ? error.stack :	error); | 
|  | 94 | +		error_message = error.toString(); | 
|  | 95 | +	} | 
|  | 96 | + | 
|  | 97 | +	if (!error_message) { | 
|  | 98 | +		let message = util.format( | 
|  | 99 | +			'Successfully update anchor peers in organization %s to the channel \'%s\'', | 
|  | 100 | +			org_name, channelName); | 
|  | 101 | +		logger.info(message); | 
|  | 102 | +		let response = { | 
|  | 103 | +			success: true, | 
|  | 104 | +			message: message | 
|  | 105 | +		}; | 
|  | 106 | +		return response; | 
|  | 107 | +	} else { | 
|  | 108 | +		let message = util.format('Failed to update anchor peers. cause:%s',error_message); | 
|  | 109 | +		logger.error(message); | 
|  | 110 | +		throw new Error(message); | 
|  | 111 | +	} | 
|  | 112 | +}; | 
|  | 113 | + | 
|  | 114 | +exports.updateAnchorPeers = updateAnchorPeers; | 
0 commit comments