github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/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 bdd_grpc_util 18 import endorser_util 19 import bdd_test_util 20 import bootstrap_util 21 import orderer_util 22 import time 23 24 class ChannelCreationInfo: 25 'Used to store the information needed to construct Config TX for orderer broadcast to create a new channel' 26 def __init__(self, channelId, channelCreationPolicyName, signedConfigEnvelope): 27 self.channelId = channelId 28 self.channelCreationPolicyName = channelCreationPolicyName 29 self.config_update_envelope = signedConfigEnvelope 30 31 def __repr__(self): 32 return "channelId = {0}\nchannelCreationPolicyName={1}\nconfigUpdateEnvelope={2}\n".format(self.channelId, 33 self.channelCreationPolicyName, 34 str( 35 self.config_update_envelope)) 36 37 38 39 @given(u'the orderer network has organizations') 40 def step_impl(context): 41 assert 'table' in context, "Expected table of orderer organizations" 42 directory = bootstrap_util.getDirectory(context) 43 for row in context.table.rows: 44 org = directory.getOrganization(row['Organization'], shouldCreate = True) 45 org.addToNetwork(bootstrap_util.Network.Orderer) 46 47 48 @given(u'user requests role of orderer admin by creating a key and csr for orderer and acquires signed certificate from organization') 49 def step_impl(context): 50 assert 'table' in context, "Expected table with triplet of User/Orderer/Organization" 51 directory = bootstrap_util.getDirectory(context) 52 for row in context.table.rows: 53 directory.registerOrdererAdminTuple(row['User'], row['Orderer'], row['Organization']) 54 55 @given(u'user requests role for peer by creating a key and csr for peer and acquires signed certificate from organization') 56 def step_impl(context): 57 assert 'table' in context, "Expected table with triplet of User/Peer/Organization" 58 directory = bootstrap_util.getDirectory(context) 59 for row in context.table.rows: 60 directory.registerOrdererAdminTuple(row['User'], row['Peer'], row['Organization']) 61 62 @given(u'the peer network has organizations') 63 def step_impl(context): 64 assert 'table' in context, "Expected table of peer network organizations" 65 directory = bootstrap_util.getDirectory(context) 66 for row in context.table.rows: 67 org = directory.getOrganization(row['Organization'], shouldCreate = True) 68 org.addToNetwork(bootstrap_util.Network.Peer) 69 70 @given(u'a ordererBootstrapAdmin is identified and given access to all public certificates and orderer node info') 71 def step_impl(context): 72 directory = bootstrap_util.getDirectory(context) 73 assert len(directory.ordererAdminTuples) > 0, "No orderer admin tuples defined!!!" 74 # Simply create the user 75 bootstrap_util.getOrdererBootstrapAdmin(context, shouldCreate=True) 76 77 @given(u'the ordererBootstrapAdmin creates the genesis block "{ordererGenesisBlockName}" for chain "{ordererSystemChainIdName}" for network config policy "{networkConfigPolicy}" and consensus "{consensusType}" using chain creators policies') 78 def step_impl(context, ordererGenesisBlockName, ordererSystemChainIdName, networkConfigPolicy, consensusType): 79 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 80 ordererSystemChainIdGUUID = ordererBootstrapAdmin.tags[ordererSystemChainIdName] 81 # Now collect the named signed config items 82 configGroups =[] 83 for row in context.table.rows: 84 configGroupName = row['ConfigGroup Names'] 85 configGroups += ordererBootstrapAdmin.tags[configGroupName] 86 # Concatenate signedConfigItems 87 88 # Construct block 89 (genesisBlock,envelope) = bootstrap_util.createGenesisBlock(context, ordererSystemChainIdGUUID, consensusType, signedConfigItems=configGroups) 90 ordererBootstrapAdmin.setTagValue(ordererGenesisBlockName, genesisBlock) 91 bootstrap_util.OrdererGensisBlockCompositionCallback(context, genesisBlock) 92 bootstrap_util.PeerCompositionCallback(context) 93 94 @given(u'the orderer admins inspect and approve the genesis block for chain "{chainId}"') 95 def step_impl(context, chainId): 96 pass 97 98 @given(u'the orderer admins use the genesis block for chain "{chainId}" to configure orderers') 99 def step_impl(context, chainId): 100 pass 101 #raise NotImplementedError(u'STEP: Given the orderer admins use the genesis block for chain "testchainid" to configure orderers') 102 103 @given(u'the ordererBootstrapAdmin generates a GUUID to identify the orderer system chain and refer to it by name as "{ordererSystemChainId}"') 104 def step_impl(context, ordererSystemChainId): 105 directory = bootstrap_util.getDirectory(context) 106 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 107 ordererBootstrapAdmin.setTagValue(ordererSystemChainId, bootstrap_util.GetUUID()) 108 109 110 @given(u'the ordererBootstrapAdmin creates a chain creators policy "{chainCreatePolicyName}" (network name) for peer orgs who wish to form a network using orderer system chain "{ordererSystemChainId}"') 111 def step_impl(context, chainCreatePolicyName, ordererSystemChainId): 112 directory = bootstrap_util.getDirectory(context) 113 114 115 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 116 ordererSystemChainIdGuuid = ordererBootstrapAdmin.tags[ordererSystemChainId] 117 118 # Collect the orgs from the table 119 orgNames = [row['Organization'] for row in context.table.rows] 120 bootstrap_util.addOrdererBootstrapAdminOrgReferences(context, chainCreatePolicyName, orgNames) 121 122 chainCreatorsOrgsPolicySignedConfigItem = \ 123 bootstrap_util.createChainCreatorsPolicy(context=context, chainCreatePolicyName=chainCreatePolicyName, chaindId=ordererSystemChainIdGuuid, orgNames=orgNames) 124 125 ordererBootstrapAdmin.setTagValue(chainCreatePolicyName, [chainCreatorsOrgsPolicySignedConfigItem]) 126 127 128 @given(u'the ordererBootstrapAdmin runs the channel template tool to create the orderer configuration template "{templateName}" for application developers using orderer "{ordererComposeService}"') 129 def step_impl(context, templateName, ordererComposeService): 130 pass 131 132 133 @given(u'the ordererBootstrapAdmin distributes orderer configuration template "template1" and chain creation policy name "chainCreatePolicy1"') 134 def step_impl(context): 135 pass 136 137 138 @given(u'the user "{userName}" creates a peer template "{templateName}" with chaincode deployment policy using chain creation policy name "{chainCreatePolicyName}" and peer organizations') 139 def step_impl(context, userName, templateName, chainCreatePolicyName): 140 ' At the moment, only really defining MSP Config Items (NOT SIGNED)' 141 directory = bootstrap_util.getDirectory(context) 142 user = directory.getUser(userName) 143 user.setTagValue(templateName, [directory.getOrganization(row['Organization']) for row in context.table.rows]) 144 145 146 @given(u'the user "{userName}" creates a ConfigUpdateEnvelope "{createChannelSignedConfigEnvelope}"') 147 def step_impl(context, userName, createChannelSignedConfigEnvelope): 148 directory = bootstrap_util.getDirectory(context) 149 user = directory.getUser(userName) 150 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 151 152 153 channelID = context.table.rows[0]["ChannelID"] 154 chainCreationPolicyName = context.table.rows[0]["Chain Creation Policy Name"] 155 templateName = context.table.rows[0]["Template"] 156 # Loop through templates referenced orgs 157 mspOrgNames = [org.name for org in user.tags[templateName]] 158 signedMspConfigItems = bootstrap_util.getSignedMSPConfigItems(context=context, orgNames=mspOrgNames) 159 160 # Add the anchors signed config Items 161 anchorSignedConfigItemsName = context.table.rows[0]["Anchors"] 162 signedAnchorsConfigItems = user.tags[anchorSignedConfigItemsName] 163 164 # Intermediate step until template tool is ready 165 signedConfigItems = bootstrap_util.createSignedConfigItems(configGroups=signedMspConfigItems + signedAnchorsConfigItems) 166 167 168 169 #NOTE: Conidered passing signing key for appDeveloper, but decided that the peer org signatures they need to collect subsequently should be proper way 170 config_update_envelope = bootstrap_util.createConfigUpdateEnvelope(channelConfigGroup=signedConfigItems, chainId=channelID, chainCreationPolicyName=chainCreationPolicyName) 171 172 user.setTagValue(createChannelSignedConfigEnvelope, ChannelCreationInfo(channelID, chainCreationPolicyName, config_update_envelope)) 173 174 # Construct TX Config Envelope, broadcast, expect success, and then connect to deliver to revtrieve block. 175 # Make sure the blockdata exactly the TxConfigEnvelope I submitted. 176 # txConfigEnvelope = bootstrap_util.createConfigTxEnvelope(chainId=channelID, signedConfigEnvelope=signedConfigEnvelope) 177 178 179 @given(u'the following application developers are defined for peer organizations and each saves their cert as alias') 180 def step_impl(context): 181 assert 'table' in context, "Expected table with triplet of Developer/ChainCreationPolicyName/Organization" 182 directory = bootstrap_util.getDirectory(context) 183 for row in context.table.rows: 184 userName = row['Developer'] 185 nodeAdminNamedTuple = directory.registerOrdererAdminTuple(userName, row['ChainCreationPolicyName'], row['Organization']) 186 user = directory.getUser(userName) 187 user.setTagValue(row['AliasSavedUnder'], nodeAdminNamedTuple) 188 189 @given(u'the user "{userName}" collects signatures for ConfigUpdateEnvelope "{createChannelSignedConfigEnvelopeName}" from peer orgs') 190 def step_impl(context, userName, createChannelSignedConfigEnvelopeName): 191 assert 'table' in context, "Expected table of peer organizations" 192 directory = bootstrap_util.getDirectory(context) 193 user = directory.getUser(userName=userName) 194 # Get the ChannelCreationInfo object that holds the signedConfigEnvelope 195 channelCreationInfo = user.tags[createChannelSignedConfigEnvelopeName] 196 config_update_envelope = channelCreationInfo.config_update_envelope 197 for row in context.table.rows: 198 org = directory.getOrganization(row['Organization']) 199 assert bootstrap_util.Network.Peer in org.networks, "Organization '{0}' not in Peer network".format(org.name) 200 bootstrap_util.BootstrapHelper.addSignatureToSignedConfigItem(config_update_envelope, (org, org.getSelfSignedCert())) 201 # print("Signatures for signedConfigEnvelope:\n {0}\n".format(signedConfigEnvelope.Items[0])) 202 203 @given(u'the user "{userName}" creates a ConfigUpdate Tx "{configUpdateTxName}" using signed ConfigUpdateEnvelope "{createChannelSignedConfigEnvelopeName}"') 204 def step_impl(context, userName, configUpdateTxName, createChannelSignedConfigEnvelopeName): 205 directory = bootstrap_util.getDirectory(context) 206 user = directory.getUser(userName=userName) 207 channelCreationInfo = user.tags[createChannelSignedConfigEnvelopeName] 208 #TODO: this is temporary until partial update is supported. Normally you would just return 209 # this message and send directly to broadcast. 210 envelope_for_config_update = bootstrap_util.createConfigUpdateTxEnvelope(channelCreationInfo.channelId, channelCreationInfo.config_update_envelope) 211 user.setTagValue(configUpdateTxName, envelope_for_config_update) 212 213 @given(u'the user "{userName}" broadcasts ConfigUpdate Tx "{configTxName}" to orderer "{orderer}" to create channel "{channelId}"') 214 def step_impl(context, userName, configTxName, orderer, channelId): 215 directory = bootstrap_util.getDirectory(context) 216 user = directory.getUser(userName=userName) 217 configTxEnvelope = user.tags[configTxName] 218 bootstrap_util.broadcastCreateChannelConfigTx(context=context, composeService=orderer, chainId=channelId, user=user, configTxEnvelope=configTxEnvelope) 219 220 @when(u'user "{userName}" connects to deliver function on orderer "{composeService}"') 221 def step_impl(context, userName, composeService): 222 directory = bootstrap_util.getDirectory(context) 223 user = directory.getUser(userName=userName) 224 user.connectToDeliverFunction(context, composeService) 225 226 @when(u'user "{userName}" sends deliver a seek request on orderer "{composeService}" with properties') 227 def step_impl(context, userName, composeService): 228 directory = bootstrap_util.getDirectory(context) 229 user = directory.getUser(userName=userName) 230 row = context.table.rows[0] 231 chainID = row['ChainId'] 232 start, end, = orderer_util.convertSeek(row['Start']), orderer_util.convertSeek(row['End']) 233 234 streamHelper = user.getDelivererStreamHelper(context, composeService) 235 streamHelper.seekToRange(chainID=chainID, start = start, end = end) 236 237 @then(u'user "{userName}" should get a delivery "{deliveryName}" from "{composeService}" of "{expectedBlocks}" blocks with "{numMsgsToBroadcast}" messages within "{batchTimeout}" seconds') 238 def step_impl(context, userName, deliveryName, composeService, expectedBlocks, numMsgsToBroadcast, batchTimeout): 239 directory = bootstrap_util.getDirectory(context) 240 user = directory.getUser(userName=userName) 241 streamHelper = user.getDelivererStreamHelper(context, composeService) 242 243 blocks = streamHelper.getBlocks() 244 245 # Verify block count 246 assert len(blocks) == int(expectedBlocks), "Expected {0} blocks, received {1}".format(expectedBlocks, len(blocks)) 247 user.setTagValue(deliveryName, blocks) 248 249 @when(u'user "{userName}" using cert alias "{certAlias}" requests to join channel using genesis block "{genisisBlockName}" on peers with result "{joinChannelResult}"') 250 def step_impl(context, userName, certAlias, genisisBlockName, joinChannelResult): 251 timeout = 10 252 directory = bootstrap_util.getDirectory(context) 253 user = directory.getUser(userName) 254 # Find the cert using the cert tuple information saved for the user under certAlias 255 signersCert = directory.findCertForNodeAdminTuple(user.tags[certAlias]) 256 257 # Retrieve the genesis block from the returned value of deliver (Will be list with first block as genesis block) 258 genesisBlock = user.tags[genisisBlockName][0] 259 ccSpec = endorser_util.getChaincodeSpec("GOLANG", "", "cscc", ["JoinChain", genesisBlock.SerializeToString()]) 260 proposal = endorser_util.createInvokeProposalForBDD(context, ccSpec=ccSpec, chainID="",signersCert=signersCert, Mspid="DEFAULT", type="CONFIG") 261 signedProposal = endorser_util.signProposal(proposal=proposal, entity=user, signersCert=signersCert) 262 263 # Send proposal to each specified endorser, waiting 'timeout' seconds for response/error 264 endorsers = [row['Peer'] for row in context.table.rows] 265 proposalResponseFutures = [endorserStub.ProcessProposal.future(signedProposal, int(timeout)) for endorserStub in endorser_util.getEndorserStubs(context, endorsers)] 266 resultsDict = dict(zip(endorsers, [respFuture.result() for respFuture in proposalResponseFutures])) 267 user.setTagValue(joinChannelResult, resultsDict) 268 269 270 271 @given(u'the ordererBoostrapAdmin creates MSP configuration "{mspConfigItemsName}" for orderer system chain "{ordererSystemChainIdName}" for every MSP referenced by the policies') 272 def step_impl(context, ordererSystemChainIdName, mspConfigItemsName): 273 assert 'table' in context, "Expected table of policy names" 274 directory = bootstrap_util.getDirectory(context) 275 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 276 ordererSystemChainIdGUUID = ordererBootstrapAdmin.tags[ordererSystemChainIdName] 277 mspSignedConfigItems = bootstrap_util.getMspConfigItemsForPolicyNames(context, policyNames=[row['PolicyName'] for row in context.table.rows]) 278 ordererBootstrapAdmin.setTagValue(mspConfigItemsName, mspSignedConfigItems) 279 280 @given(u'the ordererBoostrapAdmin creates the chain creation policy names "{chainCreationPolicyNames}" for orderer system chain "{ordererSystemChainIdName}" with policies') 281 def step_impl(context, chainCreationPolicyNames, ordererSystemChainIdName): 282 ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) 283 ordererSystemChainIdGUUID = ordererBootstrapAdmin.tags[ordererSystemChainIdName] 284 policyNames = [row['PolicyName'] for row in context.table.rows] 285 chainCreationPolicyNamesConfigItem = bootstrap_util.createChainCreationPolicyNames(context, chainCreationPolicyNames=policyNames, chaindId=ordererSystemChainIdGUUID) 286 ordererBootstrapAdmin.setTagValue(chainCreationPolicyNames, [chainCreationPolicyNamesConfigItem]) 287 288 @then(u'user "{userName}" expects result code for "{proposalResponseName}" of "{proposalResponseResultCode}" from peers') 289 def step_impl(context, userName, proposalResponseName, proposalResponseResultCode): 290 directory = bootstrap_util.getDirectory(context) 291 user = directory.getUser(userName=userName) 292 peerToProposalResponseDict = user.tags[proposalResponseName] 293 unexpectedResponses = [(composeService,proposalResponse) for composeService, proposalResponse in peerToProposalResponseDict.items() if proposalResponse.response.payload != proposalResponseResultCode] 294 print("ProposalResponse: \n{0}\n".format(proposalResponse)) 295 print("") 296 297 @given(u'the user "{userName}" creates an peer anchor set "{anchorSetName}" for channel "{channelName}" for orgs') 298 def step_impl(context, userName, anchorSetName, channelName): 299 directory = bootstrap_util.getDirectory(context) 300 user = directory.getUser(userName=userName) 301 nodeAdminTuples = [directory.findNodeAdminTuple(row['User'], row['Peer'], row['Organization']) for row in context.table.rows] 302 user.setTagValue(anchorSetName, bootstrap_util.getAnchorPeersConfigGroup(context=context, nodeAdminTuples=nodeAdminTuples))