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)