github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/bddtests/steps/bootstrap_impl.py (about) 1 # Copyright IBM Corp. 2016 All Rights Reserved. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # 15 16 from behave import * 17 import endorser_util 18 import bootstrap_util 19 import orderer_util 20 import compose 21 import time 22 23 @given(u'the orderer network has organizations') 24 def step_impl(context): 25 assert 'table' in context, "Expected table of orderer organizations" 26 directory = bootstrap_util.getDirectory(context) 27 for row in context.table.rows: 28 org = directory.getOrganization(row['Organization'], shouldCreate = True) 29 org.addToNetwork(bootstrap_util.Network.Orderer) 30 31 32 @given(u'user requests role of orderer admin by creating a key and csr for orderer and acquires signed certificate from organization') 33 def step_impl(context): 34 assert 'table' in context, "Expected table with triplet of User/Orderer/Organization" 35 directory = bootstrap_util.getDirectory(context) 36 for row in context.table.rows: 37 directory.registerOrdererAdminTuple(row['User'], row['Orderer'], row['Organization']) 38 39 @given(u'user requests role for peer by creating a key and csr for peer and acquires signed certificate from organization') 40 def step_impl(context): 41 assert 'table' in context, "Expected table with triplet of User/Peer/Organization" 42 directory = bootstrap_util.getDirectory(context) 43 for row in context.table.rows: 44 nodeAdminTuple = directory.registerOrdererAdminTuple(row['User'], row['Peer'], row['Organization']) 45 aliasToSaveUnder = row['AliasSavedUnder'] 46 if aliasToSaveUnder != "": 47 directory.getUser(row['User']).setTagValue(aliasToSaveUnder, nodeAdminTuple) 48 49 50 @given(u'the peer network has organizations') 51 def step_impl(context): 52 assert 'table' in context, "Expected table of peer network organizations" 53 directory = bootstrap_util.getDirectory(context) 54 for row in context.table.rows: 55 org = directory.getOrganization(row['Organization'], shouldCreate = True) 56 org.addToNetwork(bootstrap_util.Network.Peer) 57 58 @given(u'a ordererBootstrapAdmin is identified and given access to all public certificates and orderer node info') 59 def step_impl(context): 60 directory = bootstrap_util.getDirectory(context) 61 assert len(directory.ordererAdminTuples) > 0, "No orderer admin tuples defined!!!" 62 # Simply create the user 63 bootstrap_util.getOrdererBootstrapAdmin(context, shouldCreate=True) 64 65 @given(u'the ordererBootstrapAdmin using cert alias "{certAlias}" creates the genesis block "{ordererGenesisBlockName}" for chain "{ordererSystemChainIdName}" for network config policy "{networkConfigPolicy}" and consensus "{consensusType}" using consortiums') 66 def step_impl(context, certAlias, ordererGenesisBlockName, ordererSystemChainIdName, networkConfigPolicy, consensusType): 67 directory = bootstrap_util.getDirectory(context=context) 68 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 69 ordererSystemChainIdGUUID = ordererBootstrapAdmin.tags[ordererSystemChainIdName] 70 # Now collect the named signed config items 71 configGroups =[] 72 for row in context.table.rows: 73 configGroupName = row['Consortium'] 74 configGroups += ordererBootstrapAdmin.tags[configGroupName] 75 # Concatenate signedConfigItems 76 77 # Construct block 78 nodeAdminTuple = ordererBootstrapAdmin.tags[certAlias] 79 bootstrapCert = directory.findCertForNodeAdminTuple(nodeAdminTuple=nodeAdminTuple) 80 (genesisBlock, envelope, genesis_block_channel_config) = bootstrap_util.createGenesisBlock(context, ordererSystemChainIdGUUID, consensusType, 81 nodeAdminTuple=nodeAdminTuple, 82 signedConfigItems=configGroups) 83 ordererBootstrapAdmin.setTagValue(ordererGenesisBlockName + "_genesis_channel_config", genesis_block_channel_config) 84 ordererBootstrapAdmin.setTagValue(ordererGenesisBlockName, genesisBlock) 85 ordererBootstrapAdmin.setTagValue("ConsensusType", consensusType) 86 bootstrap_util.OrdererGensisBlockCompositionCallback(context, genesisBlock) 87 bootstrap_util.PeerCompositionCallback(context) 88 89 @given(u'the orderer admins inspect and approve the genesis block for chain "{chainId}"') 90 def step_impl(context, chainId): 91 pass 92 93 @given(u'the orderer admins use the genesis block for chain "{chainId}" to configure orderers') 94 def step_impl(context, chainId): 95 pass 96 #raise NotImplementedError(u'STEP: Given the orderer admins use the genesis block for chain "testchainid" to configure orderers') 97 98 @given(u'the ordererBootstrapAdmin generates a GUUID to identify the orderer system chain and refer to it by name as "{ordererSystemChainId}"') 99 def step_impl(context, ordererSystemChainId): 100 directory = bootstrap_util.getDirectory(context) 101 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 102 ordererBootstrapAdmin.setTagValue(ordererSystemChainId, bootstrap_util.GetUUID()) 103 104 105 @given(u'the ordererBootstrapAdmin creates a consortium "{consortiumName}" (network name) for peer orgs who wish to form a network') 106 def step_impl(context, consortiumName): 107 directory = bootstrap_util.getDirectory(context) 108 109 110 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 111 112 # Collect the orgs from the table 113 orgNames = [row['Organization'] for row in context.table.rows] 114 bootstrap_util.addOrdererBootstrapAdminOrgReferences(context, consortiumName, orgNames) 115 116 consortium = bootstrap_util.createConsortium(context=context, consortium_name=consortiumName, org_names=orgNames) 117 ordererBootstrapAdmin.setTagValue(consortiumName, [consortium]) 118 119 @given(u'the user "{userName}" creates a peer template "{templateName}" with chaincode deployment policy using consortium "{chainCreatePolicyName}" and peer organizations') 120 def step_impl(context, userName, templateName, chainCreatePolicyName): 121 ' At the moment, only really defining MSP Config Items (NOT SIGNED)' 122 directory = bootstrap_util.getDirectory(context) 123 user = directory.getUser(userName) 124 user.setTagValue(templateName, [directory.getOrganization(row['Organization']) for row in context.table.rows]) 125 126 127 @given(u'the user "{userName}" creates a ConfigUpdateEnvelope "{createChannelSignedConfigEnvelope}"') 128 def step_impl(context, userName, createChannelSignedConfigEnvelope): 129 directory = bootstrap_util.getDirectory(context) 130 user = directory.getUser(userName) 131 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 132 133 134 channelID = context.table.rows[0]["ChannelID"] 135 consortium_name = context.table.rows[0]["Consortium"] 136 templateName = context.table.rows[0]["Template"] 137 # Loop through templates referenced orgs 138 mspOrgNames = [org.name for org in user.tags[templateName]] 139 signedMspConfigItems = bootstrap_util.getSignedMSPConfigItems(context=context, orgNames=mspOrgNames, channel_version=0) 140 user.setTagValue(createChannelSignedConfigEnvelope + "_signedMspConfigItems", signedMspConfigItems) 141 142 # Add the anchors signed config Items 143 anchorSignedConfigItemsName = context.table.rows[0]["Anchors"] 144 signedAnchorsConfigItems = user.tags[anchorSignedConfigItemsName] 145 146 # Intermediate step until template tool is ready 147 consensus_type = ordererBootstrapAdmin.tags["ConsensusType"] 148 channel_config_groups = bootstrap_util.createSignedConfigItems(directory=directory, 149 consensus_type=consensus_type, 150 consortium_name=consortium_name, 151 version=1, 152 channel_version=0, 153 channel_consortium_version=0, 154 configGroups=signedMspConfigItems) 155 user.setTagValue(createChannelSignedConfigEnvelope + "_channel_config_groups", channel_config_groups) 156 # bootstrap_util.setMetaPolicy(channelId=channelID, channgel_config_groups=channgel_config_groups) 157 158 #NOTE: Conidered passing signing key for appDeveloper, but decided that the peer org signatures they need to collect subsequently should be proper way 159 config_update_envelope = bootstrap_util.createNewConfigUpdateEnvelope(channelConfig=channel_config_groups, chainId=channelID) 160 161 user.setTagValue(createChannelSignedConfigEnvelope, config_update_envelope) 162 163 # Construct TX Config Envelope, broadcast, expect success, and then connect to deliver to revtrieve block. 164 # Make sure the blockdata exactly the TxConfigEnvelope I submitted. 165 # txConfigEnvelope = bootstrap_util.createConfigTxEnvelope(chainId=channelID, signedConfigEnvelope=signedConfigEnvelope) 166 167 168 @given(u'the following application developers are defined for peer organizations and each saves their cert as alias') 169 def step_impl(context): 170 assert 'table' in context, "Expected table with triplet of Developer/Consortium/Organization" 171 directory = bootstrap_util.getDirectory(context) 172 for row in context.table.rows: 173 userName = row['Developer'] 174 nodeAdminNamedTuple = directory.registerOrdererAdminTuple(userName, row['Consortium'], row['Organization']) 175 user = directory.getUser(userName) 176 user.setTagValue(row['AliasSavedUnder'], nodeAdminNamedTuple) 177 178 @given(u'the user "{userName}" collects signatures for ConfigUpdateEnvelope "{createChannelSignedConfigEnvelopeName}" from developers') 179 def step_impl(context, userName, createChannelSignedConfigEnvelopeName): 180 assert 'table' in context, "Expected table of peer organizations" 181 directory = bootstrap_util.getDirectory(context) 182 user = directory.getUser(userName=userName) 183 config_update_envelope = user.tags[createChannelSignedConfigEnvelopeName] 184 for row in context.table.rows: 185 user = directory.getUser(row['Developer']) 186 namedAdminTuple = user.tags[row['Cert Alias']] 187 cert = directory.findCertForNodeAdminTuple(namedAdminTuple) 188 # assert bootstrap_util.Network.Peer in org.networks, "Organization '{0}' not in Peer network".format(org.name) 189 bootstrap_util.BootstrapHelper.addSignatureToSignedConfigItem(config_update_envelope, (user, namedAdminTuple.organization, cert)) 190 # print("Signatures for signedConfigEnvelope:\n {0}\n".format(signedConfigEnvelope.Items[0])) 191 192 @given(u'the user "{userName}" creates a ConfigUpdate Tx "{configUpdateTxName}" using cert alias "{certAlias}" using signed ConfigUpdateEnvelope "{createChannelSignedConfigEnvelopeName}"') 193 def step_impl(context, userName, certAlias, configUpdateTxName, createChannelSignedConfigEnvelopeName): 194 directory = bootstrap_util.getDirectory(context) 195 user = directory.getUser(userName=userName) 196 namedAdminTuple = user.tags[certAlias] 197 cert = directory.findCertForNodeAdminTuple(namedAdminTuple) 198 config_update_envelope = user.tags[createChannelSignedConfigEnvelopeName] 199 config_update = bootstrap_util.getChannelIdFromConfigUpdateEnvelope(config_update_envelope) 200 envelope_for_config_update = bootstrap_util.createEnvelopeForMsg(directory=directory, 201 nodeAdminTuple=namedAdminTuple, 202 chainId=config_update.channel_id, 203 msg=config_update_envelope, 204 typeAsString="CONFIG_UPDATE") 205 user.setTagValue(configUpdateTxName, envelope_for_config_update) 206 207 @given(u'the user "{userName}" using cert alias "{certAlias}" broadcasts ConfigUpdate Tx "{configTxName}" to orderer "{orderer}" to create channel "{channelId}"') 208 def step_impl(context, userName, certAlias, configTxName, orderer, channelId): 209 directory = bootstrap_util.getDirectory(context) 210 user = directory.getUser(userName=userName) 211 configTxEnvelope = user.tags[configTxName] 212 bootstrap_util.broadcastCreateChannelConfigTx(context=context,certAlias=certAlias, composeService=orderer, chainId=channelId, user=user, configTxEnvelope=configTxEnvelope) 213 214 @when(u'the user "{userName}" broadcasts transaction "{transactionAlias}" to orderer "{orderer}" on channel "{channelId}"') 215 def step_impl(context, userName, transactionAlias, orderer, channelId): 216 directory = bootstrap_util.getDirectory(context) 217 user = directory.getUser(userName=userName) 218 transaction = user.tags[transactionAlias] 219 bootstrap_util.broadcastCreateChannelConfigTx(context=context, certAlias=None, composeService=orderer, chainId=channelId, user=user, configTxEnvelope=transaction) 220 221 222 @when(u'user "{userName}" using cert alias "{certAlias}" connects to deliver function on orderer "{composeService}"') 223 def step_impl(context, userName, certAlias, composeService): 224 directory = bootstrap_util.getDirectory(context) 225 user = directory.getUser(userName=userName) 226 nodeAdminTuple = user.tags[certAlias] 227 cert = directory.findCertForNodeAdminTuple(nodeAdminTuple) 228 user.connectToDeliverFunction(context, composeService, certAlias, nodeAdminTuple=nodeAdminTuple) 229 230 @when(u'user "{userName}" sends deliver a seek request on orderer "{composeService}" with properties') 231 def step_impl(context, userName, composeService): 232 directory = bootstrap_util.getDirectory(context) 233 user = directory.getUser(userName=userName) 234 row = context.table.rows[0] 235 chainID = row['ChainId'] 236 start, end, = orderer_util.convertSeek(row['Start']), orderer_util.convertSeek(row['End']) 237 print("Start and end = {0}/{1}".format(start, end)) 238 print("") 239 streamHelper = user.getDelivererStreamHelper(context, composeService) 240 streamHelper.seekToRange(chainID=chainID, start = start, end = end) 241 242 @then(u'user "{userName}" should get a delivery "{deliveryName}" from "{composeService}" of "{expectedBlocks}" blocks with "{numMsgsToBroadcast}" messages within "{batchTimeout}" seconds') 243 def step_impl(context, userName, deliveryName, composeService, expectedBlocks, numMsgsToBroadcast, batchTimeout): 244 directory = bootstrap_util.getDirectory(context) 245 user = directory.getUser(userName=userName) 246 streamHelper = user.getDelivererStreamHelper(context, composeService) 247 248 blocks = streamHelper.getBlocks() 249 250 # Verify block count 251 assert len(blocks) == int(expectedBlocks), "Expected {0} blocks, received {1}".format(expectedBlocks, len(blocks)) 252 user.setTagValue(deliveryName, blocks) 253 254 @when(u'user "{userName}" using cert alias "{certAlias}" requests to join channel using genesis block "{genisisBlockName}" on peers with result "{joinChannelResult}"') 255 def step_impl(context, userName, certAlias, genisisBlockName, joinChannelResult): 256 timeout = 10 257 directory = bootstrap_util.getDirectory(context) 258 user = directory.getUser(userName) 259 nodeAdminTuple = user.tags[certAlias] 260 # Find the cert using the cert tuple information saved for the user under certAlias 261 signersCert = directory.findCertForNodeAdminTuple(nodeAdminTuple) 262 263 # Retrieve the genesis block from the returned value of deliver (Will be list with first block as genesis block) 264 genesisBlock = user.tags[genisisBlockName][0] 265 ccSpec = endorser_util.getChaincodeSpec("GOLANG", "", "cscc", ["JoinChain", genesisBlock.SerializeToString()]) 266 proposal = endorser_util.createInvokeProposalForBDD(context, ccSpec=ccSpec, chainID="",signersCert=signersCert, Mspid=user.tags[certAlias].organization, type="CONFIG") 267 signedProposal = endorser_util.signProposal(proposal=proposal, entity=user, signersCert=signersCert) 268 269 # Send proposal to each specified endorser, waiting 'timeout' seconds for response/error 270 endorsers = [row['Peer'] for row in context.table.rows] 271 proposalResponseFutures = [endorserStub.ProcessProposal.future(signedProposal, int(timeout)) for endorserStub in endorser_util.getEndorserStubs(context,composeServices=endorsers, directory=directory, nodeAdminTuple=nodeAdminTuple)] 272 resultsDict = dict(zip(endorsers, [respFuture.result() for respFuture in proposalResponseFutures])) 273 user.setTagValue(joinChannelResult, resultsDict) 274 275 276 @then(u'user "{userName}" expects result code for "{proposalResponseName}" of "{proposalResponseResultCode}" from peers') 277 def step_impl(context, userName, proposalResponseName, proposalResponseResultCode): 278 directory = bootstrap_util.getDirectory(context) 279 user = directory.getUser(userName=userName) 280 peerToProposalResponseDict = user.tags[proposalResponseName] 281 unexpectedResponses = [(composeService,proposalResponse) for composeService, proposalResponse in peerToProposalResponseDict.items() if proposalResponse.response.payload != proposalResponseResultCode] 282 print("ProposalResponse: \n{0}\n".format(proposalResponse)) 283 print("") 284 285 @given(u'the user "{userName}" creates an peer anchor set "{anchorSetName}" for channel "{channelName}" for orgs') 286 def step_impl(context, userName, anchorSetName, channelName): 287 directory = bootstrap_util.getDirectory(context) 288 user = directory.getUser(userName=userName) 289 nodeAdminTuples = [directory.findNodeAdminTuple(row['User'], row['Peer'], row['Organization']) for row in context.table.rows] 290 user.setTagValue(anchorSetName, bootstrap_util.getAnchorPeersConfigGroup(context=context, nodeAdminTuples=nodeAdminTuples)) 291 292 @given(u'we compose "{composeYamlFile}"') 293 def step_impl(context, composeYamlFile): 294 # time.sleep(10) # Should be replaced with a definitive interlock guaranteeing that all peers/membersrvc are ready 295 composition = compose.Composition(context, composeYamlFile) 296 context.compose_containers = composition.containerDataList 297 context.composition = composition 298 299 @given(u'I wait "{seconds}" seconds') 300 def step_impl(context, seconds): 301 time.sleep(float(seconds)) 302 303 @when(u'I wait "{seconds}" seconds') 304 def step_impl(context, seconds): 305 time.sleep(float(seconds)) 306 307 @then(u'I wait "{seconds}" seconds') 308 def step_impl(context, seconds): 309 time.sleep(float(seconds)) 310 311 @given(u'user "{userNameSource}" gives "{objectAlias}" to user "{userNameTarget}"') 312 def step_impl(context, userNameSource, objectAlias, userNameTarget): 313 directory = bootstrap_util.getDirectory(context) 314 userSource = directory.getUser(userName=userNameSource) 315 userTarget = directory.getUser(userName=userNameTarget) 316 userTarget.setTagValue(objectAlias, userSource.tags[objectAlias]) 317 318 @given(u'the ordererBootstrapAdmin creates a cert alias "{certAlias}" for orderer network bootstrap purposes for organizations') 319 def step_impl(context, certAlias): 320 assert "table" in context, "Expected table of Organizations" 321 directory = bootstrap_util.getDirectory(context) 322 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 323 assert len(context.table.rows) == 1, "Only support single orderer orgnaization at moment" 324 for row in context.table.rows: 325 nodeAdminNamedTuple = directory.registerOrdererAdminTuple(ordererBootstrapAdmin.name, "ordererBootstrapAdmin", row['Organization']) 326 ordererBootstrapAdmin.setTagValue(certAlias, nodeAdminNamedTuple)