diff --git a/catalog/hyperledger/common.bom b/catalog/hyperledger/common.bom index a17814c..dff3b25 100644 --- a/catalog/hyperledger/common.bom +++ b/catalog/hyperledger/common.bom @@ -1,70 +1,200 @@ brooklyn.catalog: - version: 0.18.0-SNAPSHOT # BROOKLYN_HYPERLEDGER_VERSION + version: 0.19.0-SNAPSHOT # BROOKLYN_HYPERLEDGER_VERSION publish: description: | - Entities for running the Hyperledger Fabric project in Apache Brooklyn. - license_code: Apache-2.0 + Entities for Hyperledger Fabric. + license_code: APACHE-2.0 icon_url: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png items: - - id: hyperledger-docker-engine - description: "The engine for running Docker containers" - itemType: entity - item: - - name: "Docker Engine (host)" - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - - install.command: | - sudo yum -y update - sudo tee /etc/yum.repos.d/docker.repo <<-'EOF' - [dockerrepo] - name=Docker Repository - baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ - enabled=1 - gpgcheck=1 - gpgkey=https://yum.dockerproject.org/gpg - EOF - sudo yum -y install docker-engine - - post.install.command: | - # Configure Docker - sudo mkdir -p /etc/systemd/system/docker.service.d - echo "[Service]" | sudo tee --append /etc/systemd/system/docker.service.d/docker.conf > /dev/null - echo "ExecStart=" | sudo tee --append /etc/systemd/system/docker.service.d/docker.conf > /dev/null - echo 'ExecStart=/usr/bin/docker daemon -D --api-cors-header="*" --storage-driver=devicemapper -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock' | sudo tee --append /etc/systemd/system/docker.service.d/docker.conf > /dev/null - - sudo systemctl enable docker.service - sudo systemctl daemon-reload - - launch.command: | - sudo service docker start - - stop.command: | - sudo service docker stop - - checkRunning.command: | - sudo service docker status - - provisioning.properties: - osFamily: centos - minRam: 4gb - installDevUrandom: true - required.ports: - - 22 - - 4243 - - 7050 - - 7051 - - 7052 - - 7053 - - 7054 - - 7055 - - 7056 - - 7057 - - 7058 - - 7059 - - 8080 - - 9999 - - childStartMode: foreground_late + - id: hyperledger-docker-engine + description: | + The Docker engine for running containers. + itemType: entity + item: + name: "hyperledger-docker-engine" + type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess + + brooklyn.parameters: + - name: docker.package + description: "Docker Package Name" + type: string + default: "docker-ce" + - name: docker.port + description: "Docker Package Number" + type: integer + default: 2376 + + brooklyn.config: + shell.env: + DOCKER_PACKAGE: $brooklyn:config("docker.package") + HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") + DOCKER_PORT: $brooklyn:config("docker.port") + + install.command: | + sudo yum -y update + sudo yum install -y yum-utils device-mapper-persistent-data lvm2 + sudo yum-config-manager --add-repo \ + https://download.docker.com/linux/centos/docker-ce.repo + sudo yum-config-manager --enable extras + sudo yum-config-manager --enable epel-testing + sudo yum install -y ${DOCKER_PACKAGE} + + post.install.command: | + echo "[HLF] docker installed" + + customize.command: | + sudo tee /etc/docker/daemon.json < compose-rest-server.out 2>&1& + + brooklyn.enrichers: + - type: org.apache.brooklyn.enricher.stock.Transformer + brooklyn.config: + uniqueTag: rest-server-address-generator + enricher.sourceSensor: $brooklyn:sensor("host.address") + enricher.targetSensor: $brooklyn:sensor("hyperledger.compose.url") + enricher.targetValue: + $brooklyn:formatString: + - "%s:%d%s" + - $brooklyn:attributeWhenReady("host.address") + - 3000 + - "/explorer" diff --git a/catalog/hyperledger/multi-cluster.bom b/catalog/hyperledger/multi-cluster.bom index f48b71d..4b5ca8c 100644 --- a/catalog/hyperledger/multi-cluster.bom +++ b/catalog/hyperledger/multi-cluster.bom @@ -1,477 +1,448 @@ brooklyn.catalog: - version: 0.18.0-SNAPSHOT # BROOKLYN_HYPERLEDGER_VERSION + version: 0.19.0-SNAPSHOT # BROOKLYN_HYPERLEDGER_VERSION publish: description: | - Entities for running the Hyperledger Fabric project in Apache Brooklyn. - license_code: Apache-2.0 + Entities for a multi location Hyperledger Fabric cluster. + license_code: APACHE-2.0 icon_url: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png items: - - id: hyperledger-fabric-multi-cluster-application - description: | - A Hyperledger Fabric cluster of a membership services node, a CLI node, a root - validating peer node, and cluster(s) of validating peer nodes running in multiple - locations. - publish: - license_code: Apache-2.0 - overview: README.md - name: "Hyperledger Fabric Multi-cluster" - iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png - itemType: entity - item: - type: org.apache.brooklyn.entity.stock.BasicApplication - - brooklyn.parameters: - - name: hyperledger.peers.per.location - description: | - The number of Hyperledger Fabric validating peer nodes to create in each - location. - type: integer - default: 3 - constraints: - - required - - name: hyperledger.pbft.request.timeout - description: | - The number of seconds the PBFT plugin should wait when making requests. - type: integer - default: 120 - constraints: - - required - - name: hyperledger.app.timeout - description: | - The number of seconds the demo app should wait between deploy, invoke, and query - steps. - type: integer - default: 180 - constraints: - - required - - brooklyn.config: - hyperledger.peers.per.location: 3 - hyperledger.pbft.request.timeout: 120 - hyperledger.app.timeout: 180 - - brooklyn.children: - - type: hyperledger-fabric-multi-cluster - name: "Hyperledger Fabric Multi-cluster" - - - id: hyperledger-fabric-multi-cluster - item: + - id: hyperledger-fabric-multi-cluster-application + description: | + A Hyperledger Fabric cluster of a membership services node, a CLI node, a root + validating peer node, and cluster(s) of validating peer nodes running in multiple + locations. + publish: + license_code: APACHE-2.0 + overview: README.md name: "Hyperledger Fabric Multi-cluster" - type: org.apache.brooklyn.entity.group.DynamicRegionsFabric - id: my-hyperledger-fabric-cluster - - memberSpec: - $brooklyn:entitySpec: - type: hyperledger-vp-cluster-multi - name: "Validating Peer Cluster" + iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png + itemType: entity + item: + type: org.apache.brooklyn.entity.stock.BasicApplication + + brooklyn.parameters: + - name: hyperledger.peers.per.location + description: | + The number of Hyperledger Fabric validating peer nodes to create in each + location. + type: integer + default: 3 + constraints: + - required + - name: hyperledger.pbft.request.timeout + description: | + The number of seconds the PBFT plugin should wait when making requests. + type: integer + default: 120 + constraints: + - required + - name: hyperledger.app.timeout + description: | + The number of seconds the demo app should wait between deploy, invoke, and query + steps. + type: integer + default: 180 + constraints: + - required - brooklyn.children: - - type: hyperledger-services-host-multi - name: "Membership Services and Sequence Node Host" - - - type: hyperledger-validating-peer-host-multi - id: my-hyperledger-root-node-multi - name: "Root Validating Peer Host" brooklyn.config: - is.root.node: true - launch.latch: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("service.isUp") - - - id: hyperledger-services-host-multi - description: | - A Docker host running a Hyperledger Fabric Membership Services node and a sequence node. - itemType: entity - item: - - name: "Membership Services and Sequence Node Host" - type: hyperledger-docker-engine - - brooklyn.children: - - type: hyperledger-membersrvc-node-multi - id: my-hyperledger-membersrvc-node-multi - - - type: hyperledger-sequence-node - id: my-hyperledger-sequence-node-multi - - - id: hyperledger-membersrvc-node-multi - description: "A Hyperledger Fabric membership services node" - itemType: entity - item: - - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - name: Membership Services Node - - brooklyn.config: - launch.latch: $brooklyn:component("my-hyperledger-sequence-node-multi").attributeWhenReady("service.isUp") - - install.command: | - sudo docker pull hyperledger/fabric-membersrvc:x86_64-0.6.1-preview + hyperledger.peers.per.location: 3 + hyperledger.pbft.request.timeout: 120 + hyperledger.app.timeout: 180 - post.install.command: | - echo "Overriding parent post.install.command with no-op" + brooklyn.children: + - type: hyperledger-fabric-multi-cluster + name: "hyperledger-fabric-multi-cluster" - launch.command: | - nohup sudo docker run --name=membersrvc \ - --restart=always \ - -i \ - -p 7054:7054 \ - -e CORE_LOGGING_LEVEL=info \ - hyperledger/fabric-membersrvc:x86_64-0.6.1-preview membersrvc >> ~/membersrvc.log 2>&1& - - checkRunning.command: | - STATUS=$(sudo docker inspect -f {{.State.Running}} membersrvc) - sudo service docker status && [ "${STATUS}" = "true" ] + - id: hyperledger-fabric-multi-cluster + item: + name: "Hyperledger Fabric Multi-cluster" + type: org.apache.brooklyn.entity.group.DynamicRegionsFabric + id: my-hyperledger-fabric-cluster - brooklyn.initializers: - - type: org.apache.brooklyn.core.sensor.StaticSensor brooklyn.config: - name: secret.keys - targetType: java.lang.String - static.value: "MwYpmSRjupbT;5wgHK9qqYaPy;vQelbRvja7cJ;9LKqKH5peurL;Pqh90CEW5juZ;FfdvDkAdY81P;QiXJgHyV4t7A;twoKZouEyLyB;BxP7QNh778gI;wu3F1EwJWHvQ" + memberSpec: + $brooklyn:entitySpec: + type: hyperledger-vp-cluster-multi + name: "hyperledger-vp-cluster" + + brooklyn.children: + - type: hyperledger-services-host-multi + name: "hyperledger-services-host" + - type: hyperledger-validating-peer-host-multi + id: my-hyperledger-root-node-multi + name: "hyperledger-validating-peer-host" + brooklyn.config: + is.root.node: true + latch.launch: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("service.isUp") + + - id: hyperledger-services-host-multi + description: | + A Docker host running a Hyperledger Fabric Membership Services node + and a sequence node. + itemType: entity + item: + type: hyperledger-docker-engine + name: "hyperledger-services-host" + + brooklyn.children: + - type: hyperledger-membersrvc-node-multi + id: my-hyperledger-membersrvc-node-multi + - type: hyperledger-sequence-node + id: my-hyperledger-sequence-node-multi + + - id: hyperledger-membersrvc-node-multi + description: | + A Hyperledger Fabric membership services node + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-membersrvc-node" - - id: hyperledger-cli-host-multi - description: | - A Docker host running a Hyperledger Fabric Membership Services CLI node. - itemType: entity - item: - - name: "CLI Node Host" - type: hyperledger-docker-engine - - brooklyn.children: - - type: hyperledger-cli-node-multi - id: my-hyperledger-cli-node-multi - - - id: hyperledger-cli-node-multi - description: "A Hyperledger Fabric CLI node" - itemType: entity - item: - - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - name: "CLI Node" - - shell.env: - HYPERLEDGER_ROOT_NODE_ADDRESS: $brooklyn:component("my-hyperledger-root-node-multi").attributeWhenReady("host.address") - HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("host.address") - HYPERLEDGER_APP_TIMEOUT: $brooklyn:config("hyperledger.app.timeout") - HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") - - install.command: | - sudo docker pull hyperledger/fabric-peer:x86_64-0.6.1-preview - sudo docker tag hyperledger/fabric-peer:x86_64-0.6.1-preview hyperledger/fabric-baseimage:latest - - post.install.command: | - echo "Overriding parent post.install.command with no-op" - - launch.command: | - nohup sudo docker run --name=cli \ - --restart=always \ - -i \ - -p 7051:7051 \ - -p 7052:7052 \ - -p 8080:8080 \ - -e CORE_VM_ENDPOINT=http://$HOST_ADDRESS:4243 \ - -e CORE_PEER_ADDRESS=$HOST_ADDRESS:7051 \ - -e CORE_PEER_ADDRESSAUTODETECT=false \ - -e CORE_SECURITY_ENABLED=true \ - -e CORE_SECURITY_PRIVACY=true \ - -e HYPERLEDGER_ROOT_NODE_ADDRESS=$HYPERLEDGER_ROOT_NODE_ADDRESS \ - -e HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS \ - -e APP_HOME=/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/asset_management/app \ - hyperledger/fabric-peer:x86_64-0.6.1-preview /bin/bash -c \ - "cd /opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/asset_management/app; \ - cp /opt/gopath/src/github.com/hyperledger/fabric/peer/core.yaml .; \ - sed -i \"s/0.0.0.0/$HYPERLEDGER_ROOT_NODE_ADDRESS/g\" core.yaml; \ - sed -i \"s/localhost/$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS/g\" core.yaml; \ - sed -i \"s/30/$HYPERLEDGER_APP_TIMEOUT/g\" app.go; \ - curl -k -so infiniteloop.sh https://raw.githubusercontent.com/hyperledger/fabric/v0.6.1-preview/scripts/infiniteloop.sh; \ - chmod +x infiniteloop.sh; \ - ./infiniteloop.sh" >> ~/cli.log 2>&1& - - checkRunning.command: | - STATUS=$(sudo docker inspect -f {{.State.Running}} cli) - sudo service docker status && [ "${STATUS}" = "true" ] - - brooklyn.initializers: - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector brooklyn.config: - name: "Run Demo Application" - description: "Runs the asset management demo application." - - command: | - sudo docker exec -i cli bash '-c' 'cd $APP_HOME && go build && ./app' 2>&1 - - - id: hyperledger-sequence-node - description: "A lightweight HTTP server that issues sequential integer values" - itemType: entity - item: - - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - name: "Sequence Node" - id: hyperledger-sequence - - install.command: | - sudo yum -y install python net-tools - - post.install.command: | - echo "Overriding parent post.install.command with no-op" - - launch.command: | - cat > sequence.py <<"END" - from BaseHTTPServer import HTTPServer - from BaseHTTPServer import BaseHTTPRequestHandler - - sequence = 0 - - class MyRequestHandler (BaseHTTPRequestHandler) : - - def do_GET(self) : - global sequence - - self.send_response(200) - self.send_header("Content-type:", "text/plain") - self.wfile.write("\n") + latch.start: $brooklyn:component("my-hyperledger-sequence-node-multi").attributeWhenReady("service.isUp") + + install.command: | + sudo docker pull hyperledger/fabric-membersrvc:${HYPERLEDGER_VERSION} + + launch.command: | + nohup sudo docker run --name=membersrvc \ + --restart=always \ + -i \ + -p 7054:7054 \ + -e CORE_LOGGING_LEVEL=info \ + hyperledger/fabric-membersrvc:${HYPERLEDGER_VERSION} membersrvc >> ~/membersrvc.log 2>&1& + + checkRunning.command: | + STATUS=$(sudo docker inspect -f {{.State.Running}} membersrvc) + sudo service docker status && [ "${STATUS}" = "true" ] + + brooklyn.initializers: + - type: org.apache.brooklyn.core.sensor.StaticSensor + brooklyn.config: + name: secret.keys + targetType: java.lang.String + static.value: "MwYpmSRjupbT;5wgHK9qqYaPy;vQelbRvja7cJ;9LKqKH5peurL;Pqh90CEW5juZ;FfdvDkAdY81P;QiXJgHyV4t7A;twoKZouEyLyB;BxP7QNh778gI;wu3F1EwJWHvQ" + + - id: hyperledger-cli-host-multi + description: | + A Docker host running a Hyperledger Fabric Membership Services CLI node. + itemType: entity + item: + type: hyperledger-docker-engine + name: "hyperledger-cli-host" + + brooklyn.children: + - type: hyperledger-cli-node-multi + id: my-hyperledger-cli-node-multi + + - id: hyperledger-cli-node-multi + description: | + A Hyperledger Fabric CLI node. + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-cli-node" - self.wfile.write(sequence) - sequence += 1 - - server = HTTPServer(("", 9999), MyRequestHandler) - - server.serve_forever() - END - - python sequence.py > sequence.out 2>&1 $PID_FILE - - checkRunning.command: | - sudo netstat -nl | grep 9999 - - stop.command: | - sudo kill -9 $(cat $PID_FILE) - - - id: hyperledger-vp-cluster-multi - description: "A cluster of Hyperledger Fabric validating peer nodes and a CLI node" - name: "Hyperledger Fabric VP Cluster" - itemType: entity - item: - type: org.apache.brooklyn.entity.stock.BasicApplication - - brooklyn.children: - - type: hyperledger-vp-nodes-multi - name: "Validating Peer Nodes Cluster" - - - type: hyperledger-cli-host-multi - name: "CLI Host" - - - id: hyperledger-vp-nodes-multi - description: "A cluster of Hyperledger Fabric validating peer nodes" - name: "Hyperledger Fabric VP Cluster" - item: - type: org.apache.brooklyn.entity.group.DynamicCluster - - brooklyn.config: - initialSize: $brooklyn:config("hyperledger.peers.per.location") - - memberSpec: - $brooklyn:entitySpec: - type: hyperledger-validating-peer-host-multi - name: "Validating Peer Docker Host" - - brooklyn.config: - is.root.node: false - launch.latch: $brooklyn:component("my-hyperledger-root-node-multi").attributeWhenReady("service.isUp") - - brooklyn.enrichers: - - type: org.apache.brooklyn.enricher.stock.Aggregator brooklyn.config: - uniqueTag: node-address-aggregator - enricher.aggregator.excludeBlank: true - enricher.aggregating.fromMembers: true - enricher.sourceSensor: $brooklyn:sensor("host.address") - enricher.targetSensor: $brooklyn:sensor("node.host.address.list") - - - id: hyperledger-validating-peer-host-multi - description: | - A Docker host running a Hyperledger Fabric validating peer node in a container - itemType: entity - item: - - name: "Validating Peer Docker Host" - type: hyperledger-docker-engine - - brooklyn.children: - - type: hyperledger-validating-peer-node-multi - id: my-hyperledger-validating-peer-node-multi - - - id: hyperledger-validating-peer-node-multi - description: "A Hyperledger Fabric validating peer node" - itemType: entity - item: - - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - name: "Validating Peer Node" - - shell.env: - IS_ROOT_NODE: $brooklyn:config("is.root.node") - - FABRIC_GROUP_MEMBERS_COUNT: $brooklyn:component("my-hyperledger-fabric-cluster").attributeWhenReady("group.members.count") - - HYPERLEDGER_ROOT_NODE_ADDRESS: $brooklyn:component("my-hyperledger-root-node-multi").attributeWhenReady("host.address") - HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("host.address") - HYPERLEDGER_PBFT_REQUEST_TIMEOUT: $brooklyn:config("hyperledger.pbft.request.timeout") - HYPERLEDGER_PEERS_PER_LOCATION: $brooklyn:config("hyperledger.peers.per.location") - - SECRET_KEYS: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("secret.keys") - - HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") - SEQ_HOST_ADDRESS: $brooklyn:component("my-hyperledger-sequence-node-multi").attributeWhenReady("host.address") - - files.install: - "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/login-template.json": "login-template.json" - "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/query-template.json": "query-template.json" - "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/query-template-security.json": "query-template-security.json" - - install.command: | - sudo docker pull hyperledger/fabric-peer:x86_64-0.6.1-preview - sudo docker tag hyperledger/fabric-peer:x86_64-0.6.1-preview hyperledger/fabric-baseimage:latest - - post.install.command: | - echo "Overriding parent post.install.command with no-op" - - launch.command: | - echo $HOST_ADDRESS > host-address - - CLUSTER_INDEX=$(curl http://$SEQ_HOST_ADDRESS:9999/) - HYPERLEDGER_PEER_ID=vp$CLUSTER_INDEX - echo $HYPERLEDGER_PEER_ID > hyperledger.peer.id - - IFS=';' read -ra SECRET_KEYS_ARRAY <<< "$SECRET_KEYS" - SECRET=${SECRET_KEYS_ARRAY[$CLUSTER_INDEX]} - - HYPERLEDGER_CLUSTER_TOTAL_SIZE=$((1 + ($FABRIC_GROUP_MEMBERS_COUNT - 2) * $HYPERLEDGER_PEERS_PER_LOCATION)) - - # Additional arguments for peer nodes - if [ $IS_ROOT_NODE == "false" ]; then - PEER_NODE_ARG="-e CORE_PEER_DISCOVERY_ROOTNODE=$HYPERLEDGER_ROOT_NODE_ADDRESS:7051" - fi - - nohup sudo docker run --name=$HYPERLEDGER_PEER_ID \ - --restart=always \ - -i \ - -p 7050:7050 \ - -p 7051:7051 \ - -p 7052:7052 \ - -p 7053:7053 \ - -e CORE_VM_ENDPOINT=http://$HOST_ADDRESS:4243 \ - -e CORE_PEER_ID=$HYPERLEDGER_PEER_ID \ - $PEER_NODE_ARG \ - -e CORE_PEER_ADDRESS=$HOST_ADDRESS:7051 \ - -e CORE_PEER_ADDRESSAUTODETECT=false \ - -e CORE_PEER_NETWORKID=dev \ - -e CORE_LOGGING_LEVEL=info \ - -e CORE_SECURITY_ENABLED=true \ - -e CORE_SECURITY_PRIVACY=true \ - -e CORE_SECURITY_ENROLLID=test_$HYPERLEDGER_PEER_ID \ - -e CORE_SECURITY_ENROLLSECRET=$SECRET \ - -e CORE_PEER_PKI_ECA_PADDR=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS:7054 \ - -e CORE_PEER_PKI_TCA_PADDR=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS:7054 \ - -e CORE_PEER_PKI_TLSCA_PADDR=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS:7054 \ - -e CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft \ - -e CORE_PBFT_GENERAL_MODE=batch \ - -e CORE_PBFT_GENERAL_N=$HYPERLEDGER_CLUSTER_TOTAL_SIZE \ - -e CORE_PBFT_GENERAL_TIMEOUT_REQUEST=${HYPERLEDGER_PBFT_REQUEST_TIMEOUT}s \ - hyperledger/fabric-peer:x86_64-0.6.1-preview peer node start >> ~/$HYPERLEDGER_PEER_ID.log 2>&1& - - checkRunning.command: | - STATUS=$(sudo docker inspect -f {{.State.Running}} $(cat hyperledger.peer.id)) - sudo service docker status && [ "${STATUS}" = "true" ] - - brooklyn.initializers: - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector - brooklyn.config: - name: "Login User" - description: "Logs in a registered user" - shell.env: - INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir") - - command: | - timestamp=$(date +%s) - rest_endpoint=http://$(cat host-address):7050/registrar - - cp ${INSTALL_DIR}/login-template.json login-${timestamp}.json - sed -i "s/ENROLL_ID/${enrollId}/g" login-${timestamp}.json - sed -i "s/ENROLL_SECRET/${enrollSecret}/g" login-${timestamp}.json - - curl -H "Content-Type: application/json" -X POST -d @login-${timestamp}.json ${rest_endpoint} + HYPERLEDGER_ROOT_NODE_ADDRESS: $brooklyn:component("my-hyperledger-root-node-multi").attributeWhenReady("host.address") + HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("host.address") + HYPERLEDGER_APP_TIMEOUT: $brooklyn:config("hyperledger.app.timeout") + HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") + + install.command: | + sudo docker pull hyperledger/fabric-peer:${HYPERLEDGER_VERSION} + sudo docker tag hyperledger/fabric-peer:${HYPERLEDGER_VERSION} hyperledger/fabric-baseimage:latest + + launch.command: | + nohup sudo docker run --name=cli \ + --restart=always \ + -i \ + -p 7051:7051 \ + -p 7052:7052 \ + -p 8080:8080 \ + -e CORE_VM_ENDPOINT=http://${HOST_ADDRESS}:${DOCKER_PORT} \ + -e CORE_PEER_ADDRESS=${HOST_ADDRESS}:7051 \ + -e CORE_PEER_ADDRESSAUTODETECT=false \ + -e CORE_SECURITY_ENABLED=true \ + -e CORE_SECURITY_PRIVACY=true \ + -e HYPERLEDGER_ROOT_NODE_ADDRESS=${HYPERLEDGER_ROOT_NODE_ADDRESS} \ + -e HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS=${HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS} \ + -e APP_HOME=/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/asset_management/app \ + hyperledger/fabric-peer:${HYPERLEDGER_VERSION} /bin/bash -c \ + "cd /opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/asset_management/app; \ + cp /opt/gopath/src/github.com/hyperledger/fabric/peer/core.yaml .; \ + sed -i \"s/0.0.0.0/${HYPERLEDGER_ROOT_NODE_ADDRESS}/g\" core.yaml; \ + sed -i \"s/localhost/${HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS}/g\" core.yaml; \ + sed -i \"s/30/${HYPERLEDGER_APP_TIMEOUT}/g\" app.go; \ + curl -k -so infiniteloop.sh https://raw.githubusercontent.com/hyperledger/fabric/v0.6.1-preview/scripts/infiniteloop.sh; \ + chmod +x infiniteloop.sh; \ + ./infiniteloop.sh" >> ~/cli.log 2>&1& + + checkRunning.command: | + STATUS=$(sudo docker inspect -f {{.State.Running}} cli) + sudo service docker status && [ "${STATUS}" = "true" ] + + brooklyn.initializers: + - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector + brooklyn.config: + name: "Run Demo Application" + description: "Runs the asset management demo application." + + command: | + sudo docker exec -i cli bash '-c' 'cd ${APP_HOME} && go build && ./app' 2>&1 + + - id: hyperledger-sequence-node + description: | + A lightweight HTTP server that issues sequential integer values. + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-sequence-node" + id: hyperledger-sequence - parameters: - enrollId: - description: "The username" + brooklyn.config: + install.command: | + sudo yum -y install python net-tools - enrollSecret: - description: "The password" + launch.command: | + cat > sequence.py <<"END" + from BaseHTTPServer import HTTPServer + from BaseHTTPServer import BaseHTTPRequestHandler - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector - brooklyn.config: - name: "Check Login" - description: "Checks if a user is logged in" + sequence = 0 - command: | - rest_endpoint=http://$(cat host-address):7050/registrar/${enrollId} - curl ${rest_endpoint} + class MyRequestHandler (BaseHTTPRequestHandler) : - parameters: - enrollId: - description: "The username" + def do_GET(self) : + global sequence - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector - brooklyn.config: - name: "Query Chaincode" - description: "Queries an example chaincode" + self.send_response(200) + self.send_header("Content-type:", "text/plain") + self.wfile.write("\n") - shell.env: - INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir") + self.wfile.write(sequence) + sequence += 1 - command: | - timestamp=$(date +%s) - rest_endpoint=http://$(cat host-address):7050/chaincode + server = HTTPServer(("", 9999), MyRequestHandler) - cp ${INSTALL_DIR}/query-template-security.json query-${timestamp}-security.json - sed -i "s/METHOD/query/g" query-${timestamp}-security.json - sed -i "s/NAME/${name}/g" query-${timestamp}-security.json - sed -i "s/FUNCTION/${function}/g" query-${timestamp}-security.json - sed -i "s/ARGUMENTS/${args}/g" query-${timestamp}-security.json - sed -i "s/METADATA/${metadata}/g" query-${timestamp}-security.json - sed -i "s/SECURE_CONTEXT/${secureContext}/g" query-${timestamp}-security.json - sed -i "s/TRANSACTION_ID/${timestamp}/g" query-${timestamp}-security.json + server.serve_forever() + END - curl -H "Content-Type: application/json" -X POST -d @query-${timestamp}-security.json ${rest_endpoint} + python sequence.py > sequence.out 2>&1 ${PID_FILE} - parameters: - name: - description: "The chaincode container name (hash)" + checkRunning.command: | + sudo netstat -nl | grep 9999 - function: - description: "The function to run" - defaultValue: "query" + stop.command: | + sudo kill -9 $(<${PID_FILE}) - args: - description: "Arguments for the function" - defaultValue: "[]" + - id: hyperledger-vp-cluster-multi + description: | + A cluster of Hyperledger Fabric validating peer nodes and a CLI node. + name: "Hyperledger Fabric VP Cluster" + itemType: entity + item: + type: org.apache.brooklyn.entity.stock.BasicApplication - metadata: - description: "Metadata for the query call" + brooklyn.children: + - type: hyperledger-vp-nodes-multi + name: "hyperledger-vp-nodes" + - type: hyperledger-cli-host-multi + name: "hyperledger-cli-host" - secureContext: - description: "The registered user" + - id: hyperledger-vp-nodes-multi + description: | + A cluster of Hyperledger Fabric validating peer nodes. + name: "Hyperledger Fabric VP Cluster" + item: + type: org.apache.brooklyn.entity.group.DynamicCluster - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector brooklyn.config: - name: "List Peers" - description: "Retrieve information about the network of peer nodes comprising the blockchain network" + initialSize: $brooklyn:config("hyperledger.peers.per.location") + + memberSpec: + $brooklyn:entitySpec: + type: hyperledger-validating-peer-host-multi + name: "hyperledger-validating-peer-host" + + brooklyn.config: + is.root.node: false + latch.launch: $brooklyn:component("my-hyperledger-root-node-multi").attributeWhenReady("service.isUp") + + brooklyn.enrichers: + - type: org.apache.brooklyn.enricher.stock.Aggregator + brooklyn.config: + uniqueTag: node-address-aggregator + enricher.aggregator.excludeBlank: true + enricher.aggregating.fromMembers: true + enricher.sourceSensor: $brooklyn:sensor("host.address") + enricher.targetSensor: $brooklyn:sensor("node.host.address.list") + + - id: hyperledger-validating-peer-host-multi + description: | + A Docker host running a Hyperledger Fabric validating peer node in a container + itemType: entity + item: + type: hyperledger-docker-engine + name: "hyperledger-validating-peer-host" + + brooklyn.children: + - type: hyperledger-validating-peer-node-multi + id: my-hyperledger-validating-peer-node-multi + + - id: hyperledger-validating-peer-node-multi + description: | + A Hyperledger Fabric validating peer node. + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-validating-peer-node" - command: | - rest_endpoint=http://$(cat host-address):7050/network/peers - curl ${rest_endpoint} + brooklyn.config: + shell.env: + IS_ROOT_NODE: $brooklyn:config("is.root.node") + FABRIC_GROUP_MEMBERS_COUNT: $brooklyn:component("my-hyperledger-fabric-cluster").attributeWhenReady("group.members.count") + HYPERLEDGER_ROOT_NODE_ADDRESS: $brooklyn:component("my-hyperledger-root-node-multi").attributeWhenReady("host.address") + HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("host.address") + HYPERLEDGER_PBFT_REQUEST_TIMEOUT: $brooklyn:config("hyperledger.pbft.request.timeout") + HYPERLEDGER_PEERS_PER_LOCATION: $brooklyn:config("hyperledger.peers.per.location") + SECRET_KEYS: $brooklyn:component("my-hyperledger-membersrvc-node-multi").attributeWhenReady("secret.keys") + HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") + SEQ_HOST_ADDRESS: $brooklyn:component("my-hyperledger-sequence-node-multi").attributeWhenReady("host.address") + + files.install: + "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/login-template.json": "login-template.json" + "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/query-template.json": "query-template.json" + "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/query-template-security.json": "query-template-security.json" + + install.command: | + sudo docker pull hyperledger/fabric-peer:${HYPERLEDGER_VERSION} + sudo docker tag hyperledger/fabric-peer:${HYPERLEDGER_VERSION} hyperledger/fabric-baseimage:latest + + launch.command: | + echo ${HOST_ADDRESS} > host-address + + CLUSTER_INDEX=$(curl http://${SEQ_HOST_ADDRESS}:9999/) + HYPERLEDGER_PEER_ID=vp${CLUSTER_INDEX} + echo ${HYPERLEDGER_PEER_ID} > hyperledger.peer.id + + IFS=';' read -ra SECRET_KEYS_ARRAY <<< "${SECRET_KEYS}" + SECRET=${SECRET_KEYS_ARRAY[${CLUSTER_INDEX}]} + + HYPERLEDGER_CLUSTER_TOTAL_SIZE=$((1 + (${FABRIC_GROUP_MEMBERS_COUNT} - 2) * ${HYPERLEDGER_PEERS_PER_LOCATION})) + + # Additional arguments for peer nodes + if [ ${IS_ROOT_NODE} == "false" ]; then + PEER_NODE_ARG="-e CORE_PEER_DISCOVERY_ROOTNODE=${HYPERLEDGER_ROOT_NODE_ADDRESS}:7051" + fi + + nohup sudo docker run --name=${HYPERLEDGER_PEER_ID} \ + --restart=always \ + -i \ + -p 7050:7050 \ + -p 7051:7051 \ + -p 7052:7052 \ + -p 7053:7053 \ + -e CORE_VM_ENDPOINT=http://${HOST_ADDRESS}:${DOCKER_PORT} \ + -e CORE_PEER_ID=${HYPERLEDGER_PEER_ID} \ + ${PEER_NODE_ARG} \ + -e CORE_PEER_ADDRESS=${HOST_ADDRESS}:7051 \ + -e CORE_PEER_ADDRESSAUTODETECT=false \ + -e CORE_PEER_NETWORKID=dev \ + -e CORE_LOGGING_LEVEL=info \ + -e CORE_SECURITY_ENABLED=true \ + -e CORE_SECURITY_PRIVACY=true \ + -e CORE_SECURITY_ENROLLID=test_${HYPERLEDGER_PEER_ID} \ + -e CORE_SECURITY_ENROLLSECRET=${SECRET} \ + -e CORE_PEER_PKI_ECA_PADDR=${HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS}:7054 \ + -e CORE_PEER_PKI_TCA_PADDR=${HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS}:7054 \ + -e CORE_PEER_PKI_TLSCA_PADDR=${HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS}:7054 \ + -e CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft \ + -e CORE_PBFT_GENERAL_MODE=batch \ + -e CORE_PBFT_GENERAL_N=${HYPERLEDGER_CLUSTER_TOTAL_SIZE} \ + -e CORE_PBFT_GENERAL_TIMEOUT_REQUEST=${HYPERLEDGER_PBFT_REQUEST_TIMEOUT}s \ + hyperledger/fabric-peer:${HYPERLEDGER_VERSION} peer node start >> ~/${HYPERLEDGER_PEER_ID}.log 2>&1& + + checkRunning.command: | + STATUS=$(sudo docker inspect -f {{.State.Running}} $(cat hyperledger.peer.id)) + sudo service docker status && [ "${STATUS}" = "true" ] + + brooklyn.initializers: + - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector + brooklyn.config: + name: "Login User" + description: "Logs in a registered user" + shell.env: + INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir") + command: | + timestamp=$(date +%s) + rest_endpoint=http://$(cat host-address):7050/registrar + + cp ${INSTALL_DIR}/login-template.json login-${timestamp}.json + sed -i "s/ENROLL_ID/${enrollId}/g" login-${timestamp}.json + sed -i "s/ENROLL_SECRET/${enrollSecret}/g" login-${timestamp}.json + + curl -H "Content-Type: application/json" -X POST -d @login-${timestamp}.json ${rest_endpoint} + parameters: + enrollId: + description: "The username" + enrollSecret: + description: "The password" + + - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector + brooklyn.config: + name: "Check Login" + description: "Checks if a user is logged in" + command: | + rest_endpoint=http://$(cat host-address):7050/registrar/${enrollId} + curl ${rest_endpoint} + parameters: + enrollId: + description: "The username" + + - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector + brooklyn.config: + name: "Query Chaincode" + description: "Queries an example chaincode" + shell.env: + INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir") + command: | + timestamp=$(date +%s) + rest_endpoint=http://$(cat host-address):7050/chaincode + + cp ${INSTALL_DIR}/query-template-security.json query-${timestamp}-security.json + sed -i "s/METHOD/query/g" query-${timestamp}-security.json + sed -i "s/NAME/${name}/g" query-${timestamp}-security.json + sed -i "s/FUNCTION/${function}/g" query-${timestamp}-security.json + sed -i "s/ARGUMENTS/${args}/g" query-${timestamp}-security.json + sed -i "s/METADATA/${metadata}/g" query-${timestamp}-security.json + sed -i "s/SECURE_CONTEXT/${secureContext}/g" query-${timestamp}-security.json + sed -i "s/TRANSACTION_ID/${timestamp}/g" query-${timestamp}-security.json + + curl -H "Content-Type: application/json" -X POST -d @query-${timestamp}-security.json ${rest_endpoint} + parameters: + name: + description: "The chaincode container name (hash)" + function: + description: "The function to run" + defaultValue: "query" + args: + description: "Arguments for the function" + defaultValue: "[]" + metadata: + description: "Metadata for the query call" + secureContext: + description: "The registered user" + + - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector + brooklyn.config: + name: "List Peers" + description: "Retrieve information about the network of peer nodes comprising the blockchain network" + command: | + rest_endpoint=http://$(cat host-address):7050/network/peers + curl ${rest_endpoint} diff --git a/catalog/hyperledger/single-cluster.bom b/catalog/hyperledger/single-cluster.bom index af5b810..20fcff0 100644 --- a/catalog/hyperledger/single-cluster.bom +++ b/catalog/hyperledger/single-cluster.bom @@ -1,415 +1,292 @@ brooklyn.catalog: - version: 0.18.0-SNAPSHOT # BROOKLYN_HYPERLEDGER_VERSION + version: 0.19.0-SNAPSHOT # BROOKLYN_HYPERLEDGER_VERSION publish: description: | - Entities for running the Hyperledger Fabric project in Apache Brooklyn. - license_code: Apache-2.0 + Entities for a Hyperledger Fabric cluster. + license_code: APACHE-2.0 icon_url: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png items: - - id: hyperledger-fabric-single-cluster-template - description: | - A Hyperledger Fabric cluster of a membership services node, a CLI node, a root - validating peer node, and a single cluster of validating peer nodes running in a - single location. - name: "Hyperledger Fabric Cluster" - iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png - itemType: template - item: - services: - - type: hyperledger-fabric-single-cluster-application - name: "Hyperledger Fabric Cluster" - - - id: hyperledger-fabric-single-cluster-application - description: | - A Hyperledger Fabric cluster of a membership services node, a CLI node, a root - validating peer node, and cluster(s) of validating peer nodes running in a single - location. - publish: - license_code: Apache-2.0 - overview: README.md - name: "Hyperledger Fabric Cluster" - iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png - itemType: entity - item: - type: org.apache.brooklyn.entity.stock.BasicApplication - - brooklyn.parameters: - - name: hyperledger.peers.per.location - description: | - The number of Hyperledger Fabric validating peer nodes to create in the single - location. - type: integer - default: 4 - constraints: - - required - - name: hyperledger.pbft.request.timeout - description: | - The number of seconds the PBFT plugin should wait when making requests. - type: integer - default: 120 - constraints: - - required - - name: hyperledger.app.timeout - description: | - The number of seconds the demo app should wait between deploy, invoke, and query - steps. - type: integer - default: 60 - constraints: - - required - - brooklyn.config: - hyperledger.peers.per.location: 4 - hyperledger.pbft.request.timeout: 120 - hyperledger.app.timeout: 60 - - brooklyn.children: - - type: hyperledger-fabric-single-cluster - name: "Hyperledger Fabric Cluster" - - - id: hyperledger-fabric-single-cluster - item: - name: "Hyperledger Fabric Cluster" - type: org.apache.brooklyn.entity.stock.BasicApplication - - brooklyn.children: - - type: hyperledger-vp-cluster - name: "Hyperledger Validating Peer Cluster" - id: my-hyperledger-fabric-vp-cluster - - - type: hyperledger-services-host - name: "Membership Services and CLI Host" - - - id: hyperledger-services-host - description: | - A Docker host running a Hyperledger Fabric Membership Services node, a CLI node, a - sequence node, and the root validating peer node in separate containers. - itemType: entity - item: - - name: "Membership Services and CLI Docker Host" - type: hyperledger-docker-engine - - brooklyn.children: - - type: hyperledger-membersrvc-node - id: my-hyperledger-membersrvc-node - - - type: hyperledger-cli-node - id: my-hyperledger-cli-node - - - id: hyperledger-membersrvc-node - description: "A Hyperledger Fabric membership services node" - itemType: entity - item: - - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - name: Membership Services Node - - install.command: | - sudo docker pull hyperledger/fabric-membersrvc:x86_64-0.6.1-preview + - id: hyperledger-fabric-single-cluster-application + name: "hyperledger-fabric-cluster" + iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png + itemType: entity + item: + type: org.apache.brooklyn.entity.stock.BasicApplication + + brooklyn.parameters: + - name: hyperledger.num.peers + description: "Peers" + type: integer + default: 2 + constraints: + - required + + brooklyn.children: + - type: hyperledger-ca-host + name: "hyperledger-ca-host" + id: my-hyperledger-ca-host + - type: hyperledger-orderer-host + name: "hyperledger-orderer-host" + id: my-hyperledger-orderer-host + - type: hyperledger-peer-cluster + name: "hyperledger-peer-cluster" + id: my-hyperledger-peer-cluster + - type: hyperledger-cli-host + name: "hyperledger-cli-host" + id: my-hyperledger-cli-host + + - id: hyperledger-fabric-development-cluster-application + name: "hyperledger-fabric-development-cluster" + description: | + Hyperledger Fabric development cluster. Deploys all components on + one VM running Docker, and the CA service on another. + iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png + itemType: entity + item: + type: org.apache.brooklyn.entity.stock.BasicApplication + + brooklyn.parameters: + - name: hyperledger.num.peers + description: "Peers" + type: integer + default: 2 + constraints: + - required + + brooklyn.children: + - type: hyperledger-ca-host + name: "hyperledger-ca-host" + id: my-hyperledger-ca-host + brooklyn.children: + - type: hyperledger-fabric-composer-node + name: "hyperledger-fabric-composer-node" + id: hyperledger-fabric-composer-node + - type: hyperledger-docker-engine + name: "hyperledger-docker-engine" + brooklyn.children: + - type: hyperledger-orderer-node + name: "hyperledger-orderer-node" + id: my-hyperledger-orderer-node + - type: hyperledger-peer-cluster + name: "hyperledger-peer-cluster" + id: my-hyperledger-peer-cluster + brooklyn.config: + firstMemberSpec: + $brooklyn:entitySpec: + type: hyperledger-peer-node + name: "hyperledger-leader-node" + id: my-hyperledger-leader-node + memberSpec: + $brooklyn:entitySpec: + type: hyperledger-peer-node + name: "hyperledger-peer-node" + brooklyn.config: + is.leader.node: false + latch.launch: $brooklyn:component("my-hyperledger-leader-node").attributeWhenReady("service.isUp") + - type: hyperledger-cli-node + name: "hyperledger-cli-node" + id: my-hyperledger-cli-node + + - id: hyperledger-ca-host + itemType: entity + item: + type: hyperledger-docker-engine + name: "hyperledger-ca-host" + + brooklyn.children: + - type: hyperledger-ca-node + id: my-hyperledger-ca-node + + - id: hyperledger-ca-node + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-ca-node" - post.install.command: | - echo "Overriding parent post.install.command with no-op" - - launch.command: | - nohup sudo docker run --name=membersrvc \ - --restart=always \ - -i \ - -p 7054:7054 \ - -e CORE_LOGGING_LEVEL=info \ - hyperledger/fabric-membersrvc:x86_64-0.6.1-preview membersrvc >> ~/membersrvc.log 2>&1& - - checkRunning.command: | - STATUS=$(sudo docker inspect -f {{.State.Running}} membersrvc) - sudo service docker status && [ "${STATUS}" = "true" ] - - brooklyn.initializers: - - type: org.apache.brooklyn.core.sensor.StaticSensor - brooklyn.config: - name: secret.keys - targetType: java.lang.String - static.value: "MwYpmSRjupbT;5wgHK9qqYaPy;vQelbRvja7cJ;9LKqKH5peurL;Pqh90CEW5juZ;FfdvDkAdY81P;QiXJgHyV4t7A;twoKZouEyLyB;BxP7QNh778gI;wu3F1EwJWHvQ" - - - id: hyperledger-cli-node - description: "A Hyperledger Fabric CLI node" - itemType: entity - item: - - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - name: "CLI Node" - - shell.env: - HYPERLEDGER_ROOT_NODE_ADDRESS: $brooklyn:component("my-hyperledger-root-node").attributeWhenReady("host.address") - HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS: $brooklyn:component("my-hyperledger-membersrvc-node").attributeWhenReady("host.address") - HYPERLEDGER_APP_TIMEOUT: $brooklyn:config("hyperledger.app.timeout") - HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") - - install.command: | - sudo docker pull hyperledger/fabric-peer:x86_64-0.6.1-preview - sudo docker tag hyperledger/fabric-peer:x86_64-0.6.1-preview hyperledger/fabric-baseimage:latest - - post.install.command: | - echo "Overriding parent post.install.command with no-op" - - launch.command: | - nohup sudo docker run --name=cli \ - --restart=always \ - -i \ - -p 7051:7051 \ - -p 7052:7052 \ - -p 8080:8080 \ - -e CORE_VM_ENDPOINT=http://$HOST_ADDRESS:4243 \ - -e CORE_PEER_ADDRESS=$HOST_ADDRESS:7051 \ - -e CORE_PEER_ADDRESSAUTODETECT=false \ - -e CORE_SECURITY_ENABLED=true \ - -e CORE_SECURITY_PRIVACY=true \ - -e HYPERLEDGER_ROOT_NODE_ADDRESS=$HYPERLEDGER_ROOT_NODE_ADDRESS \ - -e HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS \ - -e APP_HOME=/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/asset_management/app \ - hyperledger/fabric-peer:x86_64-0.6.1-preview /bin/bash -c \ - "cd /opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/asset_management/app; \ - cp /opt/gopath/src/github.com/hyperledger/fabric/peer/core.yaml .; \ - sed -i \"s/0.0.0.0/$HYPERLEDGER_ROOT_NODE_ADDRESS/g\" core.yaml; \ - sed -i \"s/localhost/$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS/g\" core.yaml; \ - sed -i \"s/30/$HYPERLEDGER_APP_TIMEOUT/g\" app.go; \ - curl -k -so infiniteloop.sh https://raw.githubusercontent.com/hyperledger/fabric/v0.6.1-preview/scripts/infiniteloop.sh; \ - chmod +x infiniteloop.sh; \ - ./infiniteloop.sh" >> ~/cli.log 2>&1& - - checkRunning.command: | - STATUS=$(sudo docker inspect -f {{.State.Running}} cli) - sudo service docker status && [ "${STATUS}" = "true" ] - - brooklyn.initializers: - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector brooklyn.config: - name: "Run Demo Application" - description: "Runs the asset management demo application." - - command: | - sudo docker exec -i cli bash '-c' 'cd $APP_HOME && go build && ./app' 2>&1 - - - id: hyperledger-vp-cluster - description: "A cluster of Hyperledger Fabric validating peer nodes" - name: "Hyperledger Fabric Cluster" - iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png - item: - type: org.apache.brooklyn.entity.group.DynamicCluster - - brooklyn.config: - initialSize: $brooklyn:config("hyperledger.peers.per.location") - - firstMemberSpec: - $brooklyn:entitySpec: - type: hyperledger-validating-peer-host - name: "Root Validating Peer Docker Host" - id: my-hyperledger-root-node - - brooklyn.config: - is.root.node: true - launch.latch: $brooklyn:component("my-hyperledger-membersrvc-node").attributeWhenReady("service.isUp") - - memberSpec: - $brooklyn:entitySpec: - type: hyperledger-validating-peer-host - name: "Validating Peer Docker Host" - - brooklyn.config: - is.root.node: false - launch.latch: $brooklyn:component("my-hyperledger-root-node").attributeWhenReady("service.isUp") - - brooklyn.enrichers: - - type: org.apache.brooklyn.enricher.stock.Aggregator - brooklyn.config: - uniqueTag: node-address-aggregator - enricher.aggregator.excludeBlank: true - enricher.aggregating.fromMembers: true - enricher.sourceSensor: $brooklyn:sensor("host.address") - enricher.targetSensor: $brooklyn:sensor("node.host.address.list") + container.name: "fabric-ca" + + launch.command: | + sudo docker run \ + --name=${CONTAINER_NAME} \ + --restart=always \ + -d \ + -p 8888:8888 \ + hyperledger/fabric-ca:${HYPERLEDGER_VERSION} fabric-ca-server start -b admin:adminpw + + - id: hyperledger-orderer-host + itemType: entity + item: + type: hyperledger-docker-engine + name: "hyperledger-orderer-host" + + brooklyn.children: + - type: hyperledger-orderer-node + id: my-hyperledger-orderer-node + + - id: hyperledger-orderer-node + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-orderer-node" - - id: hyperledger-validating-peer-host - description: | - A Docker host running a Hyperledger Fabric validating peer node in a container - itemType: entity - item: - - name: "Validating Peer Docker Host" - type: hyperledger-docker-engine - - brooklyn.children: - - type: hyperledger-validating-peer-node - id: my-hyperledger-validating-peer-node - - - id: hyperledger-validating-peer-node - description: "A Hyperledger Fabric validating peer node" - itemType: entity - item: - - type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess - name: "Validating Peer Node" - - brooklyn.config: - hyperledger.peer.id: - $brooklyn:formatString: - - "vp%d" - - $brooklyn:config("cluster.member.id") - - shell.env: - IS_ROOT_NODE: $brooklyn:config("is.root.node") - - HYPERLEDGER_ROOT_NODE_ADDRESS: $brooklyn:component("my-hyperledger-root-node").attributeWhenReady("host.address") - HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS: $brooklyn:component("my-hyperledger-membersrvc-node").attributeWhenReady("host.address") - HYPERLEDGER_CLUSTER_TOTAL_SIZE: $brooklyn:component("my-hyperledger-fabric-vp-cluster").attributeWhenReady("group.members.count") - HYPERLEDGER_PBFT_REQUEST_TIMEOUT: $brooklyn:config("hyperledger.pbft.request.timeout") - HYPERLEDGER_CLUSTER_INDEX: $brooklyn:config("cluster.member.id") - HYPERLEDGER_PEER_ID: $brooklyn:config("hyperledger.peer.id") - - SECRET_KEYS: $brooklyn:component("my-hyperledger-membersrvc-node").attributeWhenReady("secret.keys") - - HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") - - files.install: - "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/login-template.json": "login-template.json" - "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/query-template.json": "query-template.json" - "classpath://io.brooklyn.hyperledger:hyperledger/chaincode-request-templates/query-template-security.json": "query-template-security.json" - - install.command: | - sudo docker pull hyperledger/fabric-peer:x86_64-0.6.1-preview - sudo docker tag hyperledger/fabric-peer:x86_64-0.6.1-preview hyperledger/fabric-baseimage:latest - - post.install.command: | - echo "Overriding parent post.install.command with no-op" - - launch.command: | - echo $HOST_ADDRESS > host-address - echo $HYPERLEDGER_PEER_ID > hyperledger.peer.id - - IFS=';' read -ra SECRET_KEYS_ARRAY <<< "$SECRET_KEYS" - SECRET=${SECRET_KEYS_ARRAY[$HYPERLEDGER_CLUSTER_INDEX]} - - # Additional arguments for peer nodes - if [ $IS_ROOT_NODE == "false" ]; then - PEER_NODE_ARG="-e CORE_PEER_DISCOVERY_ROOTNODE=$HYPERLEDGER_ROOT_NODE_ADDRESS:7051" - fi - - nohup sudo docker run --name=$HYPERLEDGER_PEER_ID \ - --restart=always \ - -i \ - -p 7050:7050 \ - -p 7051:7051 \ - -p 7052:7052 \ - -p 7053:7053 \ - -e CORE_VM_ENDPOINT=http://$HOST_ADDRESS:4243 \ - -e CORE_PEER_ID=$HYPERLEDGER_PEER_ID \ - $PEER_NODE_ARG \ - -e CORE_PEER_ADDRESS=$HOST_ADDRESS:7051 \ - -e CORE_PEER_ADDRESSAUTODETECT=false \ - -e CORE_PEER_NETWORKID=dev \ - -e CORE_LOGGING_LEVEL=info \ - -e CORE_SECURITY_ENABLED=true \ - -e CORE_SECURITY_PRIVACY=true \ - -e CORE_SECURITY_ENROLLID=test_$HYPERLEDGER_PEER_ID \ - -e CORE_SECURITY_ENROLLSECRET=$SECRET \ - -e CORE_PEER_PKI_ECA_PADDR=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS:7054 \ - -e CORE_PEER_PKI_TCA_PADDR=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS:7054 \ - -e CORE_PEER_PKI_TLSCA_PADDR=$HYPERLEDGER_MEMBERSRVC_NODE_ADDRESS:7054 \ - -e CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft \ - -e CORE_PBFT_GENERAL_MODE=batch \ - -e CORE_PBFT_GENERAL_N=$HYPERLEDGER_CLUSTER_TOTAL_SIZE \ - -e CORE_PBFT_GENERAL_TIMEOUT_REQUEST=${HYPERLEDGER_PBFT_REQUEST_TIMEOUT}s \ - hyperledger/fabric-peer:x86_64-0.6.1-preview peer node start >> ~/$HYPERLEDGER_PEER_ID.log 2>&1& - - checkRunning.command: | - STATUS=$(sudo docker inspect -f {{.State.Running}} $(cat hyperledger.peer.id)) - sudo service docker status && [ "${STATUS}" = "true" ] - - brooklyn.initializers: - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector brooklyn.config: - name: "Login User" - description: "Logs in a registered user" - - shell.env: - INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir") + container.name: "fabric-orderer" + + launch.command: | + sudo docker run \ + --name=${CONTAINER_NAME} \ + --restart=always \ + -d \ + -e ORDERER_GENERAL_LEDGERTYPE=ram \ + -e ORDERER_GENERAL_BATCHTIMEOUT=10s \ + -e ORDERER_GENERAL_MAXMESSAGECOUNT=10 \ + -e ORDERER_GENERAL_MAXWINDOWSIZE=1000 \ + -e ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 \ + -e ORDERER_GENERAL_LISTENPORT=7050 \ + -e ORDERER_RAMLEDGER_HISTORY_SIZE=100 \ + -e CONFIGTX_ORDERER_ORDERERTYPE=solo \ + -p 29050:7050 \ + hyperledger/fabric-orderer:${HYPERLEDGER_VERSION} orderer + + - id: hyperledger-peer-cluster + name: "hyperledger-peer-cluster" + iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png + item: + type: org.apache.brooklyn.entity.group.DynamicCluster - command: | - timestamp=$(date +%s) - rest_endpoint=http://$(cat host-address):7050/registrar - - cp ${INSTALL_DIR}/login-template.json login-${timestamp}.json - sed -i "s/ENROLL_ID/${enrollId}/g" login-${timestamp}.json - sed -i "s/ENROLL_SECRET/${enrollSecret}/g" login-${timestamp}.json - - curl -H "Content-Type: application/json" -X POST -d @login-${timestamp}.json ${rest_endpoint} - - parameters: - enrollId: - description: "The username" - - enrollSecret: - description: "The password" - - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector brooklyn.config: - name: "Check Login" - description: "Checks if a user is logged in" - - command: | - rest_endpoint=http://$(cat host-address):7050/registrar/${enrollId} - curl ${rest_endpoint} + initialSize: $brooklyn:config("hyperledger.num.peers") + + firstMemberSpec: + $brooklyn:entitySpec: + type: hyperledger-peer-host + name: "hyperledger-leader-host" + id: my-hyperledger-leader-host + + brooklyn.config: + is.leader.node: true + latch.launch: $brooklyn:component("my-hyperledger-orderer-node").attributeWhenReady("service.isUp") + post.launch.command: | + sudo docker pull hyperledger/fabric-ccenv:${HYPERLEDGER_VERSION} + + memberSpec: + $brooklyn:entitySpec: + type: hyperledger-peer-host + name: "hyperledger-peer-host" + + brooklyn.config: + is.leader.node: false + latch.launch: $brooklyn:component("my-hyperledger-leader-node").attributeWhenReady("service.isUp") + + - id: hyperledger-peer-host + itemType: entity + item: + type: hyperledger-docker-engine + name: "hyperledger-peer-host" + + brooklyn.children: + - type: hyperledger-peer-node + id: my-hyperledger-peer-node + + - id: hyperledger-peer-node + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-peer-node" - parameters: - enrollId: - description: "The username" - - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector brooklyn.config: - name: "Query Chaincode" - description: "Queries an example chaincode" + container.name: "fabric-peer" shell.env: - INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir") - - command: | - timestamp=$(date +%s) - rest_endpoint=http://$(cat host-address):7050/chaincode + IS_LEADER_NODE: $brooklyn:config("is.leader.node") + HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") + ORDERER_ADDRESS: $brooklyn:component("my-hyperledger-orderer-node").attributeWhenReady("host.address") + PEER_ADDRESS: $brooklyn:component("my-hyperledger-peer-cluster").attributeWhenReady("cluster.first.entity").attributeWhenReady("host.address") + ID: $brooklyn:config("cluster.member.id") + CONTAINER_NAME: + $brooklyn:formatString: + - "%s%d" + - $brooklyn:config("container.name") + - $brooklyn:config("cluster.member.id") + + launch.command: | + MIN_PORT="2$((${ID} + 70))50" + PEER_PORT="2$((${ID} + 70))51" + MAX_PORT="2$((${ID} + 70))59" + sudo docker run \ + --name=${CONTAINER_NAME} \ + --restart=always \ + -d \ + -e CORE_VM_ENDPOINT=http://${HOST_ADDRESS}:${DOCKER_PORT} \ + -e CORE_PEER_ADDRESSAUTODETECT=false \ + -e CORE_LOGGING_LEVEL=DEBUG \ + -e CORE_NEXT=true \ + -e CORE_PEER_ENDORSER_ENABLED=true \ + -e CORE_PEER_COMMITTER_ENABLED=true \ + -e CORE_PEER_PROFILE_ENABLED=false \ + -e CORE_PEER_GOSSIP_ORGLEADER=${IS_LEADER_NODE} \ + -e CORE_PEER_GOSSIP_USELEADERELECTION=false \ + -e CORE_PEER_GOSSIP_IGNORESECURITY=true \ + -e CORE_PEER_GOSSIP_SKIPHANDSHAKE=true \ + -e CORE_PEER_ID=peer${ID} \ + -e CORE_PEER_ADDRESS=${HOST_ADDRESS}:${PEER_PORT} \ + -e CORE_PEER_COMMITTER_LEDGER_ORDERER=${ORDERER_ADDRESS}:29050 \ + -e CORE_PEER_GOSSIP_BOOTSTRAP=${PEER_ADDRESS}:27051 \ + -e CORE_PEER_GOSSIP_EXTERNALENDPOINT=${HOST_ADDRESS}:${PEER_PORT} \ + -e CORE_PEER_GOSSIP_USELEADERELECTION=false \ + -p ${MIN_PORT}-${MAX_PORT}:7050-7059 \ + hyperledger/fabric-peer:${HYPERLEDGER_VERSION} peer node start -o ${ORDERER_ADDRESS}:29050 + + - id: hyperledger-cli-host + itemType: entity + item: + type: hyperledger-docker-engine + name: "hyperledger-cli-host" + + brooklyn.children: + - type: hyperledger-cli-node + id: my-hyperledger-cli-node + + - id: hyperledger-cli-node + itemType: entity + item: + type: hyperledger-docker-container + name: "hyperledger-cli-node" - cp ${INSTALL_DIR}/query-template-security.json query-${timestamp}-security.json - sed -i "s/METHOD/query/g" query-${timestamp}-security.json - sed -i "s/NAME/${name}/g" query-${timestamp}-security.json - sed -i "s/FUNCTION/${function}/g" query-${timestamp}-security.json - sed -i "s/ARGUMENTS/${args}/g" query-${timestamp}-security.json - sed -i "s/METADATA/${metadata}/g" query-${timestamp}-security.json - sed -i "s/SECURE_CONTEXT/${secureContext}/g" query-${timestamp}-security.json - sed -i "s/TRANSACTION_ID/${timestamp}/g" query-${timestamp}-security.json - - curl -H "Content-Type: application/json" -X POST -d @query-${timestamp}-security.json ${rest_endpoint} - - parameters: - name: - description: "The chaincode container name (hash)" - - function: - description: "The function to run" - defaultValue: "query" - - args: - description: "Arguments for the function" - defaultValue: "[]" - - metadata: - description: "Metadata for the query call" - - secureContext: - description: "The registered user" - - - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector brooklyn.config: - name: "List Peers" - description: "Retrieve information about the network of peer nodes comprising the blockchain network" + latch.start: $brooklyn:component("my-hyperledger-peer-cluster").attributeWhenReady("service.isUp") - command: | - rest_endpoint=http://$(cat host-address):7050/network/peers - curl ${rest_endpoint} + shell.env: + HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address") + PEER_ADDRESS: $brooklyn:component("my-hyperledger-peer-cluster").attributeWhenReady("cluster.first.entity").attributeWhenReady("host.address") + + container.name: "fabric-cli" + + launch.command: | + sudo docker run \ + --name=${CONTAINER_NAME} \ + --restart=always \ + -d \ + -e CORE_VM_ENDPOINT=http://${HOST_ADDRESS}:${DOCKER_PORT} \ + -e CORE_PEER_ADDRESSAUTODETECT=false \ + -e CORE_LOGGING_LEVEL=DEBUG \ + -e CORE_NEXT=true \ + -e CORE_PEER_ENDORSER_ENABLED=true \ + -e CORE_PEER_COMMITTER_ENABLED=true \ + -e CORE_PEER_PROFILE_ENABLED=false \ + -e CORE_PEER_GOSSIP_ORGLEADER=false \ + -e CORE_PEER_GOSSIP_USELEADERELECTION=false \ + -e CORE_PEER_GOSSIP_IGNORESECURITY=true \ + -e CORE_PEER_GOSSIP_SKIPHANDSHAKE=true \ + -e CORE_PEER_ID=cli \ + -e CORE_PEER_ADDRESS=${PEER_ADDRESS}:27051 \ + -e GOPATH=/opt/golang \ + -p 28050-28059:7050-7059 \ + hyperledger/fabric-peer:${HYPERLEDGER_VERSION} bash -c 'while true; do sleep 20170504; done' + + post.launch.command: | + sudo docker exec fabric-cli bash -c \ + 'apt-get -y update && apt-get -y install golang git && mkdir /opt/golang' diff --git a/examples/hyperledger-development-cluster.yaml b/examples/hyperledger-development-cluster.yaml new file mode 100644 index 0000000..f268b6a --- /dev/null +++ b/examples/hyperledger-development-cluster.yaml @@ -0,0 +1,7 @@ +location: +services: + - type: 'hyperledger-fabric-development-cluster-application' + brooklyn.config: + hyperledger.peers.per.location: 2 + hyperledger.pbft.request.timeout: 120 + hyperledger.app.timeout: 60 diff --git a/hyperledger.bom b/hyperledger.bom index 0fc813e..dcefb79 100644 --- a/hyperledger.bom +++ b/hyperledger.bom @@ -1,3 +1,27 @@ brooklyn.catalog: items: - classpath://io.brooklyn.hyperledger:hyperledger/catalog.bom + + - id: hyperledger-fabric-single-cluster-template + name: "hyperledger-fabric-cluster" + iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png + itemType: template + publish: + license_code: APACHE-2.0 + overview: README.md + item: + services: + - type: hyperledger-fabric-single-cluster-application + name: "hyperledger-fabric-cluster" + + - id: hyperledger-fabric-development-cluster-template + name: "hyperledger-fabric-development" + iconUrl: classpath://io.brooklyn.hyperledger:icon/hyperledger-fabric.png + itemType: template + publish: + license_code: APACHE-2.0 + overview: README.md + item: + services: + - type: hyperledger-fabric-development-cluster-application + name: "hyperledger-fabric-development" diff --git a/pom.xml b/pom.xml index a67f422..12349c5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.brooklyn.hyperledger hyperledger bundle - 0.18.0-SNAPSHOT + 0.19.0-SNAPSHOT Brooklyn :: Hyperledger Apache Brooklyn blueprint to deploy and manage Hyperledger Fabric diff --git a/resources/hyperledger/fabric-composer-templates/connection-template.json b/resources/hyperledger/fabric-composer-templates/connection-template.json new file mode 100644 index 0000000..2c75c67 --- /dev/null +++ b/resources/hyperledger/fabric-composer-templates/connection-template.json @@ -0,0 +1,9 @@ +{ + "type": "hlf", + "membershipServicesURL": "grpc://${config['hyperledger.membersrvc']}:7054", + "peerURL": "grpc://${config['hyperledger.rootnode']}:7051", + "eventHubURL": "grpc://${config['hyperledger.rootnode']}:7053", + "keyValStore": "${config['onbox.base.dir']}.composer-credentials", + "deployWaitTime": "300", + "invokeWaitTime": "100" +}