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))