Skip to content

Commit

Permalink
[FAB-1141] Add kafka and couchDB to bootstrap
Browse files Browse the repository at this point in the history
Checking this in to allow Kostas to debug issue on
3 kafka node composition.  Solo and 1 kafka node
are and couchdb configs are currently succeeding.

Added couchdb example.  Feel free to choose from
any of the examples to configure the environment
you want. Commented out for now to not fail CI.

Now parameterized orderer references to allow usage
of both solo and kafka consensus types to leverage
the same scenario.  Solo simply reuses orderer0 for all
orderer references.

Removed comments from couchdb config.

Change-Id: Id835abd0112df3a56284ef436c69e0b468c3d2bf
Signed-off-by: jeffgarratt <garratt.jeff@gmail.com>
  • Loading branch information
jeffgarratt committed Mar 21, 2017
1 parent 5b59e06 commit 94f6f4a
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 34 deletions.
51 changes: 51 additions & 0 deletions bddtests/docker-compose-next-4-couchdb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version: '2'

services:

couchdb0:
image: hyperledger/fabric-couchdb
ports:
- "5984:5984"

peer0:
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
depends_on:
- couchdb0

couchdb1:
image: hyperledger/fabric-couchdb
ports:
- "6984:5984"

peer1:
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984
depends_on:
- couchdb1

couchdb2:
image: hyperledger/fabric-couchdb
ports:
- "7984:5984"

peer2:
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb2:5984
depends_on:
- couchdb2

couchdb3:
image: hyperledger/fabric-couchdb
ports:
- "8984:5984"

peer3:
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb3:5984
depends_on:
- couchdb3
48 changes: 29 additions & 19 deletions bddtests/features/bootstrap.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
#
# Tags that can be used and will affect test internals:
# @doNotDecompose will NOT decompose the named compose_yaml after scenario ends. Useful for setting up environment and reviewing after scenario.
# @chaincodeImagesUpToDate use this if all scenarios chaincode images are up to date, and do NOT require building. BE SURE!!!
#
# @generateDocs will generate documentation for the scenario that can be used for both verification and comprehension.
#

#@chaincodeImagesUpToDate
@bootstrap
Feature: Bootstrap
As a blockchain entrepreneur
I want to bootstrap a new blockchain network

@doNotDecompose
#@doNotDecompose
@generateDocs
Scenario Outline: Bootstrap a development network with 4 peers (2 orgs) and 1 orderer (1 org), each having a single independent root of trust (No fabric-ca, just openssl)
#creates 1 self-signed key/cert pair per orderer organization
Expand All @@ -22,6 +23,8 @@ Feature: Bootstrap
And user requests role of orderer admin by creating a key and csr for orderer and acquires signed certificate from organization:
| User | Orderer | Organization |
| orderer0Signer | orderer0 | ordererOrg0 |
| orderer1Signer | orderer1 | ordererOrg0 |
| orderer2Signer | orderer2 | ordererOrg0 |


# Rolenames : MspPrincipal.proto
Expand Down Expand Up @@ -81,8 +84,11 @@ Feature: Bootstrap

And we compose "<ComposeFile>"

# Sleep as to allow system up time
And I wait "<SystemUpWaitTime>" seconds

# This implicitly incorporates the orderer genesis block info
And the ordererBootstrapAdmin runs the channel template tool to create the orderer configuration template "template1" for application developers using orderer "orderer0"
And the ordererBootstrapAdmin runs the channel template tool to create the orderer configuration template "template1" for application developers using orderer "<orderer0>"
And the ordererBootstrapAdmin distributes orderer configuration template "template1" and chain creation policy name "chainCreatePolicy1"

And the following application developers are defined for peer organizations and each saves their cert as alias
Expand Down Expand Up @@ -118,17 +124,17 @@ Feature: Bootstrap

And the user "dev0Org0" creates a ConfigUpdate Tx "configUpdateTx1" using cert alias "dev0Org0App1" using signed ConfigUpdateEnvelope "createChannelConfigUpdate1"

And the user "dev0Org0" using cert alias "dev0Org0App1" broadcasts ConfigUpdate Tx "configUpdateTx1" to orderer "orderer0" to create channel "com.acme.blockchain.jdoe.Channel1"
And the user "dev0Org0" using cert alias "dev0Org0App1" broadcasts ConfigUpdate Tx "configUpdateTx1" to orderer "<orderer0>" to create channel "com.acme.blockchain.jdoe.Channel1"

# Sleep as the deliver takes a bit to have the first block ready
And I wait "2" seconds
And I wait "<BroadcastWaitTime>" seconds

When user "dev0Org0" using cert alias "dev0Org0App1" connects to deliver function on orderer "orderer0"
And user "dev0Org0" sends deliver a seek request on orderer "orderer0" with properties:
When user "dev0Org0" using cert alias "dev0Org0App1" connects to deliver function on orderer "<orderer0>"
And user "dev0Org0" sends deliver a seek request on orderer "<orderer0>" with properties:
| ChainId | Start | End |
| com.acme.blockchain.jdoe.Channel1 | 0 | 0 |

Then user "dev0Org0" should get a delivery "genesisBlockForMyNewChannel" from "orderer0" of "1" blocks with "1" messages within "1" seconds
Then user "dev0Org0" should get a delivery "genesisBlockForMyNewChannel" from "<orderer0>" of "1" blocks with "1" messages within "1" seconds
Given user "dev0Org0" gives "genesisBlockForMyNewChannel" to user "dev0Org1"

# This is entry point for joining an existing channel
Expand Down Expand Up @@ -161,7 +167,7 @@ Feature: Bootstrap
# Under the covers, create a deployment spec, etc.
And user "dev0Org0" using cert alias "dev0Org0App1" creates a install proposal "installProposal1" for channel "com.acme.blockchain.jdoe.Channel1" using chaincode spec "cc_spec"

And user "dev0Org0" using cert alias "dev0Org0App1" sends proposal "installProposal1" to endorsers with timeout of "30" seconds with proposal responses "installProposalResponses":
And user "dev0Org0" using cert alias "dev0Org0App1" sends proposal "installProposal1" to endorsers with timeout of "90" seconds with proposal responses "installProposalResponses":
| Endorser |
| peer0 |
| peer2 |
Expand All @@ -174,7 +180,7 @@ Feature: Bootstrap
# Under the covers, create a deployment spec, etc.
When user "dev0Org0" using cert alias "dev0Org0App1" creates a instantiate proposal "instantiateProposal1" for channel "com.acme.blockchain.jdoe.Channel1" using chaincode spec "cc_spec"

And user "dev0Org0" using cert alias "dev0Org0App1" sends proposal "instantiateProposal1" to endorsers with timeout of "30" seconds with proposal responses "instantiateProposalResponses":
And user "dev0Org0" using cert alias "dev0Org0App1" sends proposal "instantiateProposal1" to endorsers with timeout of "90" seconds with proposal responses "instantiateProposalResponses":
| Endorser |
| peer0 |
| peer2 |
Expand All @@ -192,16 +198,16 @@ Feature: Bootstrap

When the user "dev0Org0" creates transaction "instantiateTx1" from proposal "instantiateProposal1" and proposal responses "instantiateProposalResponses" for channel "com.acme.blockchain.jdoe.Channel1"

And the user "dev0Org0" broadcasts transaction "instantiateTx1" to orderer "orderer0" on channel "com.acme.blockchain.jdoe.Channel1"
And the user "dev0Org0" broadcasts transaction "instantiateTx1" to orderer "<orderer1>" on channel "com.acme.blockchain.jdoe.Channel1"

# Sleep as the deliver takes a bit to have the first block ready
And I wait "2" seconds

And user "dev0Org0" sends deliver a seek request on orderer "orderer0" with properties:
And user "dev0Org0" sends deliver a seek request on orderer "<orderer0>" with properties:
| ChainId | Start | End |
| com.acme.blockchain.jdoe.Channel1 | 1 | 1 |

Then user "dev0Org0" should get a delivery "deliveredInstantiateTx1Block" from "orderer0" of "1" blocks with "1" messages within "1" seconds
Then user "dev0Org0" should get a delivery "deliveredInstantiateTx1Block" from "<orderer0>" of "1" blocks with "1" messages within "1" seconds

# Sleep as the deliver takes a bit to have the first block ready
And I wait "1" seconds
Expand Down Expand Up @@ -256,20 +262,24 @@ Feature: Bootstrap

When the user "dev0Org0" creates transaction "invokeTx1" from proposal "invokeProposal1" and proposal responses "invokeProposal1Responses" for channel "com.acme.blockchain.jdoe.Channel1"

And the user "dev0Org0" broadcasts transaction "invokeTx1" to orderer "orderer0" on channel "com.acme.blockchain.jdoe.Channel1"
And the user "dev0Org0" broadcasts transaction "invokeTx1" to orderer "<orderer2>" on channel "com.acme.blockchain.jdoe.Channel1"

# Sleep as the deliver takes a bit to have the first block ready
And I wait "2" seconds

And user "dev0Org0" sends deliver a seek request on orderer "orderer0" with properties:
And user "dev0Org0" sends deliver a seek request on orderer "<orderer0>" with properties:
| ChainId | Start | End |
| com.acme.blockchain.jdoe.Channel1 | 2 | 2 |

Then user "dev0Org0" should get a delivery "deliveredInvokeTx1Block" from "orderer0" of "1" blocks with "1" messages within "1" seconds
Then user "dev0Org0" should get a delivery "deliveredInvokeTx1Block" from "<orderer0>" of "1" blocks with "1" messages within "1" seconds


# TODO: Once events are working, consider listen event listener as well.

Examples: Orderer Options
| ComposeFile | Waittime | PolicyType | ConsensusType |
| docker-compose-next-4.yml | 60 | unanimous | solo |
| ComposeFile | SystemUpWaitTime | ConsensusType | BroadcastWaitTime | orderer0 | orderer1 | orderer2 |Orderer Specific Info|
| docker-compose-next-4.yml | 0 | solo | 2 | orderer0 | orderer0 | orderer0 | |
| docker-compose-next-4.yml ./environments/orderer-1-kafka-1/docker-compose.yml orderer-3-kafka-1.yml | 5 | kafka | 5 | orderer0 | orderer1 | orderer2 | |
| docker-compose-next-4.yml docker-compose-next-4-couchdb.yml | 5 | solo | 2 | orderer0 | orderer0 | orderer0 | |
# | docker-compose-next-4.yml docker-compose-next-4-couchdb.yml ./environments/orderer-1-kafka-1/docker-compose.yml orderer-3-kafka-1.yml | 8 | kafka | 5 | orderer0 | orderer1 | orderer2 | |
# | docker-compose-next-4.yml ./environments/orderer-1-kafka-3/docker-compose.yml | 5 | kafka | 5 | orderer0 | orderer1 | orderer2 | |
2 changes: 0 additions & 2 deletions bddtests/features/endorser.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
#
# Tags that can be used and will affect test internals:
# @doNotDecompose will NOT decompose the named compose_yaml after scenario ends. Useful for setting up environment and reviewing after scenario.
# @chaincodeImagesUpToDate use this if all scenarios chaincode images are up to date, and do NOT require building. BE SURE!!!

#@chaincodeImagesUpToDate
@endorser
Feature: Endorser
As a application developer
Expand Down
29 changes: 29 additions & 0 deletions bddtests/orderer-3-kafka-1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: '2'
services:
orderer1:
extends:
service: orderer0
image: hyperledger/fabric-testenv-orderer
environment:
- ORDERER_GENERAL_LOCALMSPDIR=${ORDERER1_ORDERER_GENERAL_LOCALMSPDIR}
- ORDERER_GENERAL_LOCALMSPID=${ORDERER1_ORDERER_GENERAL_LOCALMSPID}
- ORDERER_GENERAL_TLS_PRIVATEKEY=${ORDERER1_ORDERER_GENERAL_TLS_PRIVATEKEY}
- ORDERER_GENERAL_TLS_CERTIFICATE=${ORDERER1_ORDERER_GENERAL_TLS_CERTIFICATE}
- ORDERER_GENERAL_TLS_ROOTCAS=${ORDERER1_ORDERER_GENERAL_TLS_ROOTCAS}
depends_on:
- orderer0
- kafka0

orderer2:
extends:
service: orderer0
image: hyperledger/fabric-testenv-orderer
environment:
- ORDERER_GENERAL_LOCALMSPDIR=${ORDERER2_ORDERER_GENERAL_LOCALMSPDIR}
- ORDERER_GENERAL_LOCALMSPID=${ORDERER2_ORDERER_GENERAL_LOCALMSPID}
- ORDERER_GENERAL_TLS_PRIVATEKEY=${ORDERER2_ORDERER_GENERAL_TLS_PRIVATEKEY}
- ORDERER_GENERAL_TLS_CERTIFICATE=${ORDERER2_ORDERER_GENERAL_TLS_CERTIFICATE}
- ORDERER_GENERAL_TLS_ROOTCAS=${ORDERER2_ORDERER_GENERAL_TLS_ROOTCAS}
depends_on:
- orderer0
- kafka0
6 changes: 5 additions & 1 deletion bddtests/steps/bootstrap_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def step_impl(context, certAlias, ordererGenesisBlockName, ordererSystemChainIdN
nodeAdminTuple=nodeAdminTuple,
signedConfigItems=configGroups)
ordererBootstrapAdmin.setTagValue(ordererGenesisBlockName, genesisBlock)
ordererBootstrapAdmin.setTagValue("ConsensusType", consensusType)
bootstrap_util.OrdererGensisBlockCompositionCallback(context, genesisBlock)
bootstrap_util.PeerCompositionCallback(context)

Expand Down Expand Up @@ -151,7 +152,10 @@ def step_impl(context, userName, createChannelSignedConfigEnvelope):
signedAnchorsConfigItems = user.tags[anchorSignedConfigItemsName]

# Intermediate step until template tool is ready
channel_config_groups = bootstrap_util.createSignedConfigItems(directory, configGroups=signedMspConfigItems + signedAnchorsConfigItems)
consensus_type = ordererBootstrapAdmin.tags["ConsensusType"]
channel_config_groups = bootstrap_util.createSignedConfigItems(directory=directory,
consensus_type=consensus_type,
configGroups=signedMspConfigItems + signedAnchorsConfigItems)

# bootstrap_util.setMetaPolicy(channelId=channelID, channgel_config_groups=channgel_config_groups)

Expand Down
23 changes: 13 additions & 10 deletions bddtests/steps/bootstrap_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ def SignedBy(cls, index):

class BootstrapHelper:
KEY_CONSENSUS_TYPE = "ConsensusType"
KEY_ORDERER_KAFKA_BROKERS = "KafkaBrokers"
KEY_CHAIN_CREATION_POLICY_NAMES = "ChainCreationPolicyNames"
KEY_ACCEPT_ALL_POLICY = "AcceptAllPolicy"
KEY_HASHING_ALGORITHM = "HashingAlgorithm"
Expand Down Expand Up @@ -517,13 +518,6 @@ def encodeBatchTimeout(self):
value=orderer_dot_configuration_pb2.BatchTimeout(timeout=self.batchTimeout).SerializeToString())
return self.signConfigItem(configItem)

def encodeConsensusType(self):
configItem = self.getConfigItem(
commonConfigType=common_dot_configtx_pb2.ConfigItem.ConfigType.Value("ORDERER"),
key=BootstrapHelper.KEY_CONSENSUS_TYPE,
value=orderer_dot_configuration_pb2.ConsensusType(type=self.consensusType).SerializeToString())
return self.signConfigItem(configItem)

def encodeChainCreators(self, ciValue=orderer_dot_configuration_pb2.ChainCreationPolicyNames(
names=DEFAULT_CHAIN_CREATORS).SerializeToString()):
configItem = self.getConfigItem(
Expand Down Expand Up @@ -655,9 +649,11 @@ def getMspConfigItemsForPolicyNames(context, policyNames):
return getSignedMSPConfigItems(context=context, orgNames=orgNamesReferenced)


def createSignedConfigItems(directory, configGroups=[]):
def createSignedConfigItems(directory, consensus_type, configGroups=[]):

channelConfig = createChannelConfigGroup(directory)
channelConfig = createChannelConfigGroup(directory=directory, consensusType=consensus_type)
#TODO: Once jyellicks latest updates come through, will NOT need base orderer config
# channelConfig = common_dot_configtx_pb2.ConfigGroup()
for configGroup in configGroups:
mergeConfigGroups(channelConfig, configGroup)
return channelConfig
Expand Down Expand Up @@ -727,6 +723,13 @@ def createChannelConfigGroup(directory, hashingAlgoName="SHA256", consensusType=
channel.groups[OrdererGroup].groups[ordererOrg.name].values[BootstrapHelper.KEY_MSP_INFO].value = toValue(
ordererOrg.getMSPConfig())

# #Kafka specific
# matchingNATs = [nat for nat in directory.getNamedCtxTuples() if (("orderer" in nat.user) and ("Signer" in nat.user) and ((compose_service in nat.nodeName)))]
# for broker in [org for org in directory.getOrganizations().values() if Network.Orderer in org.networks]:
# channel.groups[OrdererGroup].groups[ordererOrg.name].values[BootstrapHelper.KEY_MSP_INFO].value = toValue(
# ordererOrg.getMSPConfig())
channel.groups[OrdererGroup].values[BootstrapHelper.KEY_ORDERER_KAFKA_BROKERS].value = toValue(orderer_dot_configuration_pb2.KafkaBrokers(brokers=["kafka0:9092"]))



# Now set policies for each org group (Both peer and orderer)
Expand Down Expand Up @@ -820,7 +823,7 @@ def createGenesisBlock(context, chainId, consensusType, nodeAdminTuple, signedCo
directory = getDirectory(context)
assert len(directory.ordererAdminTuples) > 0, "No orderer admin tuples defined!!!"

channelConfig = createChannelConfigGroup(directory)
channelConfig = createChannelConfigGroup(directory=directory, consensusType=consensusType)
for configGroup in signedConfigItems:
mergeConfigGroups(channelConfig, configGroup)

Expand Down
2 changes: 1 addition & 1 deletion bddtests/steps/docgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def compositionCallCLIAdvice(self, joinpoint):
return result

def _getNetworkGroup(self, serviceName):
groups = {"peer" : 1, "orderer" : 2}
groups = {"peer" : 1, "orderer" : 2, "kafka" : 7, "zookeeper" : 8, "couchdb" : 9}
groupId = 0
for group, id in groups.iteritems():
if serviceName.lower().startswith(group):
Expand Down
2 changes: 1 addition & 1 deletion bddtests/templates/html/graph.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

</style>
<div>
<svg width="860" height="600"></svg>
<svg width="860" height="700"></svg>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
Expand Down

0 comments on commit 94f6f4a

Please sign in to comment.