├── .gitignore ├── README.md ├── chaincode ├── .dockerignore ├── .gitignore ├── Dockerfile ├── assetTransfer.go ├── go.mod └── go.sum ├── deploy ├── .gitignore ├── Vagrantfile ├── dev │ ├── .gitignore │ ├── chaincode │ │ └── basic │ │ │ ├── .dockerignore │ │ │ ├── .gitignore │ │ │ ├── Dockerfile │ │ │ ├── assetTransfer.go │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ └── packaging │ │ │ ├── basic-org1.tgz │ │ │ ├── basic-org2.tgz │ │ │ ├── basic-org3.tgz │ │ │ ├── connection.json │ │ │ └── metadata.json │ ├── configtx │ │ └── configtx.yaml │ ├── connection-profile │ │ ├── ccp-template.json │ │ └── ccp-template.yaml │ ├── create-artifact.sh │ ├── create-certs.sh │ ├── docker-compose-api.yaml │ ├── docker-compose-ca.yaml │ ├── docker-compose-explorer.yaml │ ├── docker-compose-test-net.yaml │ ├── explorer │ │ ├── config.json │ │ └── network.json │ ├── external-builder │ │ ├── build │ │ ├── core.yaml │ │ ├── detect │ │ └── release │ ├── init-cc.sh │ ├── init-ccp.sh │ ├── init-channel.sh │ ├── install.sh │ ├── organizations │ │ └── fabric-ca │ │ │ └── org1 │ │ │ └── fabric-ca-server-config.yaml │ ├── scripts │ │ ├── ccp.sh │ │ ├── createAppChannel.sh │ │ ├── createChannel.sh │ │ ├── createGenesis.sh │ │ ├── org1-certs.sh │ │ └── updateAnchorPeer.sh │ └── uninstall.sh ├── k8s │ ├── api │ │ ├── api-svc.yaml │ │ └── api.yaml │ ├── ca │ │ ├── ca-orderer-svc.yaml │ │ ├── ca-orderer.yaml │ │ ├── ca-org1-svc.yaml │ │ ├── ca-org1.yaml │ │ ├── ca-org2-svc.yaml │ │ ├── ca-org2.yaml │ │ ├── ca-org3-svc.yaml │ │ └── ca-org3.yaml │ ├── cc │ │ ├── org1-chaincode-deployment.yaml │ │ ├── org1-chaincode-service.yaml │ │ ├── org2-chaincode-deployment.yaml │ │ ├── org2-chaincode-service.yaml │ │ ├── org3-chaincode-deployment.yaml │ │ └── org3-chaincode-service.yaml │ ├── explorer │ │ ├── configmap.yaml │ │ ├── explorer-db-svc.yaml │ │ ├── explorer-db.yaml │ │ ├── explorer-svc.yaml │ │ └── explorer.yaml │ ├── fabricfiles │ │ ├── chaincode │ │ │ └── basic │ │ │ │ ├── .dockerignore │ │ │ │ ├── .gitignore │ │ │ │ ├── Dockerfile │ │ │ │ ├── assetTransfer.go │ │ │ │ ├── go.mod │ │ │ │ ├── go.sum │ │ │ │ └── packaging │ │ │ │ ├── basic-org1.tgz │ │ │ │ ├── basic-org2.tgz │ │ │ │ ├── basic-org3.tgz │ │ │ │ ├── connection.json │ │ │ │ └── metadata.json │ │ ├── configtx │ │ │ └── configtx.yaml │ │ ├── connection-profile │ │ │ ├── ccp-template.json │ │ │ └── ccp-template.yaml │ │ ├── organizations │ │ │ └── fabric-ca │ │ │ │ ├── ordererOrg │ │ │ │ └── fabric-ca-server-config.yaml │ │ │ │ ├── org1 │ │ │ │ └── fabric-ca-server-config.yaml │ │ │ │ ├── org2 │ │ │ │ └── fabric-ca-server-config.yaml │ │ │ │ └── org3 │ │ │ │ └── fabric-ca-server-config.yaml │ │ └── scripts │ │ │ ├── ccp.sh │ │ │ ├── createAppChannel.sh │ │ │ ├── createChannel.sh │ │ │ ├── createGenesis.sh │ │ │ ├── orderer-certs.sh │ │ │ ├── org1-certs.sh │ │ │ ├── org2-certs.sh │ │ │ ├── org3-certs.sh │ │ │ ├── packageChaincode.sh │ │ │ └── updateAnchorPeer.sh │ ├── ingress │ │ ├── ingress.yaml │ │ └── issuer.yaml │ ├── install.sh │ ├── job │ │ ├── approve-chaincode.yaml │ │ ├── check-commit-readiness.yaml │ │ ├── commit-chaincode.yaml │ │ ├── create-app-channel.yaml │ │ ├── create-artifacts.yaml │ │ ├── create-certs.yaml │ │ ├── create-connection-profile.yaml │ │ ├── init-ledger-data.yaml │ │ ├── install-chaincode.yaml │ │ ├── join-app-channel.yaml │ │ ├── package-chaincode.yaml │ │ └── update-anchor-peer.yaml │ ├── kafka │ │ ├── kafka-svc.yaml │ │ ├── kafka.yaml │ │ ├── zookeeper-svc.yaml │ │ └── zookeeper.yaml │ ├── monitoring │ │ ├── grafana-config.yaml │ │ ├── grafana-svc.yaml │ │ ├── grafana.yaml │ │ ├── prometheus-config.yaml │ │ ├── prometheus-svc.yaml │ │ └── prometheus.yaml │ ├── orderer │ │ ├── order-svc.yaml │ │ ├── order2-svc.yaml │ │ ├── order3-svc.yaml │ │ ├── order4-svc.yaml │ │ ├── order5-svc.yaml │ │ ├── orderer.yaml │ │ ├── orderer2.yaml │ │ ├── orderer3.yaml │ │ ├── orderer4.yaml │ │ └── orderer5.yaml │ ├── peer │ │ ├── builder-config.yaml │ │ ├── org1 │ │ │ ├── peer0Org1-cli.yaml │ │ │ ├── peer0Org1-couchdb-svc.yaml │ │ │ ├── peer0Org1-couchdb.yaml │ │ │ ├── peer0Org1-svc.yaml │ │ │ └── peer0Org1.yaml │ │ ├── org2 │ │ │ ├── peer0Org2-cli.yaml │ │ │ ├── peer0Org2-couchdb-svc.yaml │ │ │ ├── peer0Org2-couchdb.yaml │ │ │ ├── peer0Org2-svc.yaml │ │ │ └── peer0Org2.yaml │ │ └── org3 │ │ │ ├── peer0Org3-cli.yaml │ │ │ ├── peer0Org3-couchdb-svc.yaml │ │ │ ├── peer0Org3-couchdb.yaml │ │ │ ├── peer0Org3-svc.yaml │ │ │ └── peer0Org3.yaml │ ├── pv │ │ ├── fabricfiles-pv.yaml │ │ ├── kafka-pv.yaml │ │ └── zookeeper-pv.yaml │ ├── pvc │ │ ├── fabricfiles-pvc.yaml │ │ ├── kafka-pvc.yaml │ │ └── zookeeper-pvc.yaml │ ├── ui │ │ ├── frontend-svc.yaml │ │ └── frontend.yaml │ └── uninstall.sh └── setup │ ├── haproxy-setup │ └── install_haproxy.sh │ ├── kubernetes-setup │ ├── install-prereqs.sh │ ├── install_cert_manager.sh │ ├── install_istio.sh │ ├── install_jenkins.sh │ ├── install_k8s_dashboard.sh │ ├── install_k8s_prereqs.sh │ ├── install_kubespray.sh │ ├── install_nfs_provisioner.sh │ ├── install_rancher.sh │ └── install_sonarqube.sh │ └── nfs-server-setup │ ├── copy_fabricfiles.sh │ ├── create_fabric_dir.sh │ └── install_nfs.sh ├── frontend ├── .dockerignore ├── .editorconfig ├── .gitignore ├── Dockerfile ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app-routing.module.ts │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── asset-dialog │ │ │ ├── asset-dialog.component.css │ │ │ ├── asset-dialog.component.html │ │ │ ├── asset-dialog.component.spec.ts │ │ │ └── asset-dialog.component.ts │ │ ├── asset-list │ │ │ ├── asset-list.component.css │ │ │ ├── asset-list.component.html │ │ │ ├── asset-list.component.spec.ts │ │ │ └── asset-list.component.ts │ │ ├── asset.model.ts │ │ ├── history-dialog │ │ │ ├── history-dialog.component.css │ │ │ ├── history-dialog.component.html │ │ │ ├── history-dialog.component.spec.ts │ │ │ └── history-dialog.component.ts │ │ └── services │ │ │ ├── http.service.spec.ts │ │ │ └── http.service.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── hlf-api ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── susimsek │ │ │ └── springboothlfexample │ │ │ ├── SpringBootHlfExampleApplication.java │ │ │ ├── config │ │ │ ├── ApiDocConfig.java │ │ │ ├── ApiDocProperties.java │ │ │ ├── CorsConfig.java │ │ │ └── CorsProperties.java │ │ │ ├── controller │ │ │ ├── AssetController.java │ │ │ └── CAUserController.java │ │ │ ├── exception │ │ │ ├── ExceptionTranslator.java │ │ │ ├── RecordAlreadyExistsException.java │ │ │ └── RecordNotFoundException.java │ │ │ ├── model │ │ │ ├── request │ │ │ │ ├── AssetRegistrationRequestDTO.java │ │ │ │ ├── AssetUpdateRequestDTO.java │ │ │ │ └── CAUserRegistrationDTO.java │ │ │ └── response │ │ │ │ ├── AssetDTO.java │ │ │ │ ├── AssetHistoryDTO.java │ │ │ │ ├── AssetItemDTO.java │ │ │ │ └── CAUserDTO.java │ │ │ ├── service │ │ │ ├── AssetService.java │ │ │ ├── CAUserService.java │ │ │ ├── impl │ │ │ │ ├── AssetServiceImpl.java │ │ │ │ └── CAUserServiceImpl.java │ │ │ └── mapper │ │ │ │ ├── AssetMapper.java │ │ │ │ └── CAUserMapper.java │ │ │ └── util │ │ │ ├── CAUserUtil.java │ │ │ ├── HlfExceptionMessageUtil.java │ │ │ ├── JsonUtil.java │ │ │ └── TransactionUtil.java │ └── resources │ │ ├── application.properties │ │ └── cp │ │ └── connection-org1.json │ └── test │ └── java │ └── io │ └── susimsek │ └── springboothlfexample │ └── SpringBootHlfExampleApplicationTests.java └── images ├── backend1.png ├── backend2.png ├── backend3.png ├── backend4.png ├── backend5.png ├── explorer1.png ├── explorer2.png ├── explorer3.png ├── explorer4.png ├── explorer5.png ├── frontend1.png ├── frontend2.png ├── frontend3.png ├── frontend4.png ├── grafana1.png ├── grafana2.png ├── grafana3.png ├── spring-boot-hlf-k8s-fullstack-blockchain-app.png ├── used-technologies.png └── vagrant-k8s-installation.png /.gitignore: -------------------------------------------------------------------------------- 1 | ###################### 2 | # Project Specific 3 | ###################### 4 | /src/main/webapp/content/css/main.css 5 | /target/classes/static/** 6 | /src/test/javascript/coverage/ 7 | 8 | ###################### 9 | # Node 10 | ###################### 11 | /node/ 12 | node_tmp/ 13 | node_modules/ 14 | npm-debug.log.* 15 | /.awcache/* 16 | /.cache-loader/* 17 | 18 | ###################### 19 | # SASS 20 | ###################### 21 | .sass-cache/ 22 | 23 | ###################### 24 | # Eclipse 25 | ###################### 26 | *.pydevproject 27 | .project 28 | .metadata 29 | tmp/ 30 | tmp/**/* 31 | *.tmp 32 | *.bak 33 | *.swp 34 | *~.nib 35 | local.properties 36 | .classpath 37 | .settings/ 38 | .loadpath 39 | .factorypath 40 | /src/main/resources/rebel.xml 41 | 42 | # External tool builders 43 | .externalToolBuilders/** 44 | 45 | # Locally stored "Eclipse launch configurations" 46 | *.launch 47 | 48 | # CDT-specific 49 | .cproject 50 | 51 | # PDT-specific 52 | .buildpath 53 | 54 | # STS-specific 55 | /.sts4-cache/* 56 | 57 | ###################### 58 | # IntelliJ 59 | ###################### 60 | .idea/ 61 | *.iml 62 | *.iws 63 | *.ipr 64 | *.ids 65 | *.orig 66 | classes/ 67 | out/ 68 | 69 | ###################### 70 | # Visual Studio Code 71 | ###################### 72 | .vscode/* 73 | !.vscode/settings.json 74 | !.vscode/tasks.json 75 | !.vscode/launch.json 76 | !.vscode/extensions.json 77 | *.code-workspace 78 | 79 | ###################### 80 | # Maven 81 | ###################### 82 | /log/ 83 | /target/ 84 | 85 | ###################### 86 | # Gradle 87 | ###################### 88 | .gradle/ 89 | /build/ 90 | 91 | ###################### 92 | # Package Files 93 | ###################### 94 | *.jar 95 | *.war 96 | *.ear 97 | *.db 98 | 99 | ###################### 100 | # Windows 101 | ###################### 102 | # Windows image file caches 103 | Thumbs.db 104 | 105 | # Folder config file 106 | Desktop.ini 107 | 108 | ###################### 109 | # Mac OSX 110 | ###################### 111 | .DS_Store 112 | .svn 113 | 114 | # Thumbnails 115 | ._* 116 | 117 | # Files that might appear on external disk 118 | .Spotlight-V100 119 | .Trashes 120 | 121 | ###################### 122 | # Directories 123 | ###################### 124 | /bin/ 125 | ###################### 126 | # Logs 127 | ###################### 128 | *.log* 129 | 130 | ###################### 131 | # Others 132 | ###################### 133 | *.class 134 | *.*~ 135 | *~ 136 | .merge_file* 137 | 138 | ###################### 139 | # Gradle Wrapper 140 | ###################### 141 | !gradle/wrapper/gradle-wrapper.jar 142 | 143 | ###################### 144 | # Maven Wrapper 145 | ###################### 146 | !.mvn/wrapper/maven-wrapper.jar 147 | 148 | ###################### 149 | # ESLint 150 | ###################### 151 | .eslintcache 152 | 153 | ###################### 154 | # Code coverage 155 | ###################### 156 | /coverage/ 157 | /.nyc_output/ 158 | 159 | # Vagrant 160 | .vagrant/ -------------------------------------------------------------------------------- /chaincode/.dockerignore: -------------------------------------------------------------------------------- 1 | chaincode.env* 2 | *.json 3 | *.md 4 | *.tar.gz 5 | *.tgz 6 | 7 | Dockerfile* 8 | docker-compose* 9 | .dockerignore 10 | .git 11 | .gitignore 12 | README.md 13 | LICENSE 14 | 15 | # IDEs and editors 16 | /.idea 17 | .project 18 | .classpath 19 | .c9/ 20 | *.launch 21 | .settings/ 22 | *.sublime-workspace 23 | 24 | # IDE - VSCode 25 | .vscode/* 26 | !.vscode/settings.json 27 | !.vscode/tasks.json 28 | !.vscode/launch.json 29 | !.vscode/extensions.json 30 | .history/* 31 | 32 | # misc 33 | /.sass-cache 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | npm-debug.log 38 | yarn-error.log 39 | testem.log 40 | /typings 41 | 42 | # System Files 43 | .DS_Store 44 | Thumbs.db -------------------------------------------------------------------------------- /chaincode/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Go template 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | vendor/ 11 | tmp/ 12 | data/ 13 | 14 | # Test binary, built with `go test -c` 15 | *.test 16 | 17 | # Output of the go coverage tool, specifically when used with LiteIDE 18 | *.o 19 | *.a 20 | *.so 21 | *.prof 22 | *.out 23 | 24 | # Editors 25 | .idea/* 26 | *.iml 27 | *.iws 28 | *.ipr 29 | *.ids 30 | *.orig 31 | 32 | **/sponge_log.log 33 | 34 | testing/kokoro/test-env.sh 35 | 36 | # Vagrant 37 | .vagrant/ 38 | 39 | # General files for the project 40 | pkg/* 41 | *.pyc 42 | bin/* 43 | .project 44 | /.bin 45 | /_test/secrets/*.json 46 | 47 | # OSX leaves these everywhere on SMB shares 48 | ._* 49 | 50 | # OSX trash 51 | .DS_Store 52 | 53 | # Chart dependencies 54 | **/charts/*.tgz 55 | 56 | .history 57 | -------------------------------------------------------------------------------- /chaincode/Dockerfile: -------------------------------------------------------------------------------- 1 | # This image is a microservice in golang for the Degree chaincode 2 | FROM golang:1.14.6-alpine AS build 3 | 4 | COPY . /go/src/github.com/susimsek 5 | WORKDIR /go/src/github.com/susimsek 6 | 7 | # Build application 8 | RUN go build -o chaincode -v . 9 | 10 | # Production ready image 11 | # Pass the binary to the prod image 12 | FROM alpine:3.11 as prod 13 | 14 | COPY --from=build /go/src/github.com/susimsek/chaincode /app/chaincode 15 | 16 | USER 1000 17 | 18 | WORKDIR /app 19 | CMD ./chaincode -------------------------------------------------------------------------------- /chaincode/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/susimsek 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/golang/protobuf v1.3.3 7 | github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 8 | github.com/hyperledger/fabric-contract-api-go v1.1.1 9 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect 10 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect 11 | google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /deploy/.gitignore: -------------------------------------------------------------------------------- 1 | ###################### 2 | # Project Specific 3 | ###################### 4 | /src/main/webapp/content/css/main.css 5 | /target/classes/static/** 6 | /src/test/javascript/coverage/ 7 | 8 | ###################### 9 | # Node 10 | ###################### 11 | /node/ 12 | node_tmp/ 13 | node_modules/ 14 | npm-debug.log.* 15 | /.awcache/* 16 | /.cache-loader/* 17 | 18 | ###################### 19 | # SASS 20 | ###################### 21 | .sass-cache/ 22 | 23 | ###################### 24 | # Eclipse 25 | ###################### 26 | *.pydevproject 27 | .project 28 | .metadata 29 | tmp/ 30 | tmp/**/* 31 | *.tmp 32 | *.bak 33 | *.swp 34 | *~.nib 35 | local.properties 36 | .classpath 37 | .settings/ 38 | .loadpath 39 | .factorypath 40 | /src/main/resources/rebel.xml 41 | 42 | # External tool builders 43 | .externalToolBuilders/** 44 | 45 | # Locally stored "Eclipse launch configurations" 46 | *.launch 47 | 48 | # CDT-specific 49 | .cproject 50 | 51 | # PDT-specific 52 | .buildpath 53 | 54 | # STS-specific 55 | /.sts4-cache/* 56 | 57 | ###################### 58 | # IntelliJ 59 | ###################### 60 | .idea/ 61 | *.iml 62 | *.iws 63 | *.ipr 64 | *.ids 65 | *.orig 66 | classes/ 67 | out/ 68 | 69 | ###################### 70 | # Visual Studio Code 71 | ###################### 72 | .vscode/* 73 | !.vscode/settings.json 74 | !.vscode/tasks.json 75 | !.vscode/launch.json 76 | !.vscode/extensions.json 77 | *.code-workspace 78 | 79 | ###################### 80 | # Maven 81 | ###################### 82 | /log/ 83 | /target/ 84 | 85 | ###################### 86 | # Gradle 87 | ###################### 88 | .gradle/ 89 | /build/ 90 | 91 | ###################### 92 | # Package Files 93 | ###################### 94 | *.jar 95 | *.war 96 | *.ear 97 | *.db 98 | 99 | ###################### 100 | # Windows 101 | ###################### 102 | # Windows image file caches 103 | Thumbs.db 104 | 105 | # Folder config file 106 | Desktop.ini 107 | 108 | ###################### 109 | # Mac OSX 110 | ###################### 111 | .DS_Store 112 | .svn 113 | 114 | # Thumbnails 115 | ._* 116 | 117 | # Files that might appear on external disk 118 | .Spotlight-V100 119 | .Trashes 120 | 121 | ###################### 122 | # Directories 123 | ###################### 124 | /bin/ 125 | ###################### 126 | # Logs 127 | ###################### 128 | *.log* 129 | 130 | ###################### 131 | # Others 132 | ###################### 133 | *.class 134 | *.*~ 135 | *~ 136 | .merge_file* 137 | 138 | ###################### 139 | # Gradle Wrapper 140 | ###################### 141 | !gradle/wrapper/gradle-wrapper.jar 142 | 143 | ###################### 144 | # Maven Wrapper 145 | ###################### 146 | !.mvn/wrapper/maven-wrapper.jar 147 | 148 | ###################### 149 | # ESLint 150 | ###################### 151 | .eslintcache 152 | 153 | ###################### 154 | # Code coverage 155 | ###################### 156 | /coverage/ 157 | /.nyc_output/ 158 | 159 | # Vagrant 160 | .vagrant/ 161 | -------------------------------------------------------------------------------- /deploy/dev/.gitignore: -------------------------------------------------------------------------------- 1 | ###################### 2 | # Project Specific 3 | ###################### 4 | wallet/ 5 | channel-artifacts/ 6 | system-genesis-block/ 7 | organizations/* 8 | connection-profile/* 9 | !organizations/**/fabric-ca-server-config.yaml 10 | !connection-profile/ccp-template* -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/.dockerignore: -------------------------------------------------------------------------------- 1 | chaincode.env* 2 | *.json 3 | *.md 4 | *.tar.gz 5 | *.tgz 6 | -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Go template 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | vendor/ 11 | tmp/ 12 | data/ 13 | 14 | # Test binary, built with `go test -c` 15 | *.test 16 | 17 | # Output of the go coverage tool, specifically when used with LiteIDE 18 | *.o 19 | *.a 20 | *.so 21 | *.prof 22 | *.out 23 | 24 | # Editors 25 | .idea/* 26 | *.iml 27 | *.iws 28 | *.ipr 29 | *.ids 30 | *.orig 31 | 32 | **/sponge_log.log 33 | 34 | testing/kokoro/test-env.sh 35 | 36 | # Vagrant 37 | .vagrant/ -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/Dockerfile: -------------------------------------------------------------------------------- 1 | # This image is a microservice in golang for the Degree chaincode 2 | FROM golang:1.14.6-alpine AS build 3 | 4 | COPY ./ /go/src/github.com/marbles 5 | WORKDIR /go/src/github.com/marbles 6 | 7 | # Build application 8 | RUN go build -o chaincode -v . 9 | 10 | # Production ready image 11 | # Pass the binary to the prod image 12 | FROM alpine:3.11 as prod 13 | 14 | COPY --from=build /go/src/github.com/marbles/chaincode /app/chaincode 15 | 16 | USER 1000 17 | 18 | WORKDIR /app 19 | CMD ./chaincode -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/susimsek 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/golang/protobuf v1.3.3 7 | github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 8 | github.com/hyperledger/fabric-contract-api-go v1.1.1 9 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect 10 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect 11 | google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/packaging/basic-org1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/deploy/dev/chaincode/basic/packaging/basic-org1.tgz -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/packaging/basic-org2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/deploy/dev/chaincode/basic/packaging/basic-org2.tgz -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/packaging/basic-org3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/deploy/dev/chaincode/basic/packaging/basic-org3.tgz -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/packaging/connection.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "basic-org3:7052", 3 | "dial_timeout": "10s", 4 | "tls_required": false, 5 | "client_auth_required": false, 6 | "client_key": "-----BEGIN EC PRIVATE KEY----- ... -----END EC PRIVATE KEY-----", 7 | "client_cert": "-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----", 8 | "root_cert": "-----BEGIN CERTIFICATE---- ... -----END CERTIFICATE-----" 9 | } 10 | -------------------------------------------------------------------------------- /deploy/dev/chaincode/basic/packaging/metadata.json: -------------------------------------------------------------------------------- 1 | {"path":"","type":"external","label":"basic"} 2 | -------------------------------------------------------------------------------- /deploy/dev/connection-profile/ccp-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-network-org${ORG}", 3 | "version": "1.0.0", 4 | "client": { 5 | "organization": "Org${ORG}", 6 | "connection": { 7 | "timeout": { 8 | "peer": { 9 | "endorser": "300" 10 | } 11 | } 12 | } 13 | }, 14 | "organizations": { 15 | "Org${ORG}": { 16 | "mspid": "Org${ORG}MSP", 17 | "peers": [ 18 | "peer0-org${ORG}" 19 | ], 20 | "certificateAuthorities": [ 21 | "ca-org${ORG}" 22 | ] 23 | } 24 | }, 25 | "peers": { 26 | "peer0-org${ORG}": { 27 | "url": "grpcs://peer0-org${ORG}:${P0PORT}", 28 | "tlsCACerts": { 29 | "pem": "${PEERPEM}" 30 | }, 31 | "grpcOptions": { 32 | "ssl-target-name-override": "peer0-org${ORG}", 33 | "hostnameOverride": "peer0-org${ORG}" 34 | } 35 | } 36 | }, 37 | "certificateAuthorities": { 38 | "ca-org${ORG}": { 39 | "url": "https://ca-org${ORG}:${CAPORT}", 40 | "caName": "ca-org${ORG}", 41 | "tlsCACerts": { 42 | "pem": ["${CAPEM}"] 43 | }, 44 | "httpOptions": { 45 | "verify": false 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /deploy/dev/connection-profile/ccp-template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: test-network-org${ORG} 3 | version: 1.0.0 4 | client: 5 | organization: Org${ORG} 6 | connection: 7 | timeout: 8 | peer: 9 | endorser: '300' 10 | organizations: 11 | Org${ORG}: 12 | mspid: Org${ORG}MSP 13 | peers: 14 | - peer0-org${ORG} 15 | certificateAuthorities: 16 | - ca-org${ORG} 17 | peers: 18 | peer0-org${ORG}: 19 | url: grpcs://peer0-org${ORG}:${P0PORT} 20 | tlsCACerts: 21 | pem: "${PEERPEM}" 22 | grpcOptions: 23 | ssl-target-name-override: peer0-org${ORG} 24 | hostnameOverride: peer0-org${ORG} 25 | certificateAuthorities: 26 | ca-org${ORG}: 27 | url: https://ca-org${ORG}:${CAPORT} 28 | caName: ca-org${ORG} 29 | tlsCACerts: 30 | pem: 31 | - "${CAPEM}" 32 | httpOptions: 33 | verify: false 34 | -------------------------------------------------------------------------------- /deploy/dev/create-artifact.sh: -------------------------------------------------------------------------------- 1 | docker run --rm --network fabric_test -w "/" -v "$(pwd)/scripts:/scripts" -v "$(pwd)/organizations:/organizations" -v "$(pwd)/configtx:/configtx" -v "$(pwd)/system-genesis-block:/system-genesis-block" -v "$(pwd)/channel-artifacts:/channel-artifacts" hyperledger/fabric-tools:2.3 /bin/bash -c "./scripts/createGenesis.sh && ./scripts/createChannel.sh" -------------------------------------------------------------------------------- /deploy/dev/create-certs.sh: -------------------------------------------------------------------------------- 1 | docker run --rm --network fabric_test -v "$(pwd)/scripts:/scripts" -v "$(pwd)/organizations:/organizations" hyperledger/fabric-ca-tools:1.2.1 /bin/sh -c "./scripts/org1-certs.sh" -------------------------------------------------------------------------------- /deploy/dev/docker-compose-api.yaml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | api: 5 | image: suayb/hlf-api:1.0.0 6 | container_name: api 7 | networks: 8 | - test 9 | labels: 10 | service: hyperledger-fabric 11 | environment: 12 | - SERVER_PORT=9090 13 | - HYPERLEDGER-FABRIC_NETWORK-CONFIG=file:/usr/src/app/connection-profile/connection-org1.json 14 | - HYPERLEDGER-FABRIC_WALLET-PATH=/usr/src/app/wallet 15 | - HYPERLEDGER-FABRIC_CA-CLIENT_CA-NAME=ca-org1 16 | - HYPERLEDGER-FABRIC_GATEWAY_CHANNEL-NAME=mychannel 17 | - HYPERLEDGER-FABRIC_GATEWAY_CHAINCODE-NAME=basic 18 | - HYPERLEDGER-FABRIC_CA-CLIENT_ADMIN-USER-ID=admin 19 | - HYPERLEDGER-FABRIC_CA-CLIENT_ADMIN-PASSWORD=adminpw 20 | - HYPERLEDGER-FABRIC_GATEWAY_CA-USER_REGISTRATION-ENABLED=true 21 | - HYPERLEDGER-FABRIC_GATEWAY_CA-USER_USER-ID=tom 22 | - HYPERLEDGER-FABRIC_GATEWAY_CA-USER_ORG-MSP=Org1MSP 23 | - HYPERLEDGER-FABRIC_GATEWAY_CA-USER_AFFILIATION=org1.department1 24 | volumes: 25 | - ./connection-profile:/usr/src/app/connection-profile 26 | - ./organizations:/organizations 27 | - ./wallet:/usr/src/app/wallet 28 | ports: 29 | - 9090:9090 30 | 31 | networks: 32 | test: 33 | name: fabric_test -------------------------------------------------------------------------------- /deploy/dev/docker-compose-ca.yaml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | ca-org1: 5 | image: hyperledger/fabric-ca:1.4.9 6 | container_name: ca-org1 7 | networks: 8 | - test 9 | labels: 10 | service: hyperledger-fabric 11 | command: sh -c 'fabric-ca-server start -b admin:adminpw -d' 12 | environment: 13 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server 14 | - FABRIC_CA_SERVER_CA_NAME=ca-org1 15 | - FABRIC_CA_SERVER_TLS_ENABLED=true 16 | - FABRIC_CA_SERVER_PORT=7054 17 | - FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS=0.0.0.0:17054 18 | ports: 19 | - "7054:7054" 20 | - "17054:17054" 21 | volumes: 22 | - ./organizations/fabric-ca/org1:/etc/hyperledger/fabric-ca-server 23 | 24 | networks: 25 | test: 26 | name: fabric_test -------------------------------------------------------------------------------- /deploy/dev/docker-compose-explorer.yaml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | explorer: 5 | image: hyperledger/explorer:1.1.8 6 | container_name: explorer 7 | depends_on: 8 | - explorer-db 9 | networks: 10 | - test 11 | labels: 12 | service: hyperledger-fabric 13 | environment: 14 | - DATABASE_HOST=explorer-db 15 | - DATABASE_DATABASE=fabricexplorer 16 | - DATABASE_USERNAME=hppoc 17 | - DATABASE_PASSWD=password 18 | - LOG_LEVEL_APP=debug 19 | - LOG_LEVEL_DB=debug 20 | - LOG_LEVEL_CONSOLE=info 21 | - LOG_CONSOLE_STDOUT=true 22 | - DISCOVERY_AS_LOCALHOST=false 23 | volumes: 24 | - ./organizations:/organizations 25 | - ./explorer/config.json:/opt/explorer/app/platform/fabric/config.json 26 | - ./explorer/network.json:/opt/explorer/app/platform/fabric/first-network.json 27 | ports: 28 | - 8080:8080 29 | 30 | explorer-db: 31 | image: hyperledger/explorer-db:1.1.8 32 | container_name: explorer-db 33 | networks: 34 | - test 35 | labels: 36 | service: hyperledger-fabric 37 | environment: 38 | - DATABASE_DATABASE=fabricexplorer 39 | - DATABASE_USERNAME=hppoc 40 | - DATABASE_PASSWORD=password 41 | volumes: 42 | - explorer:/var/lib/postgresql/data 43 | ports: 44 | - 5432:5432 45 | 46 | volumes: 47 | explorer: 48 | name: explorer 49 | 50 | networks: 51 | test: 52 | name: fabric_test -------------------------------------------------------------------------------- /deploy/dev/explorer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "network-configs": { 3 | "first-network": { 4 | "name": "first-network", 5 | "profile": "./first-network.json" 6 | } 7 | }, 8 | "license": "Apache-2.0" 9 | } -------------------------------------------------------------------------------- /deploy/dev/explorer/network.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-network", 3 | "version": "1.0.0", 4 | "client": { 5 | "tlsEnable": true, 6 | "adminCredential": { 7 | "id": "admin", 8 | "password": "adminpw" 9 | }, 10 | "enableAuthentication": true, 11 | "organization": "Org1MSP", 12 | "connection": { 13 | "timeout": { 14 | "peer": { 15 | "endorser": "300" 16 | }, 17 | "orderer": "300" 18 | } 19 | } 20 | }, 21 | "channels": { 22 | "mychannel": { 23 | "peers": { 24 | "peer0-org1": {} 25 | }, 26 | "connection": { 27 | "timeout": { 28 | "peer": { 29 | "endorser": "6000", 30 | "eventHub": "6000", 31 | "eventReg": "6000" 32 | } 33 | } 34 | } 35 | } 36 | }, 37 | "organizations": { 38 | "Org1MSP": { 39 | "mspid": "Org1MSP", 40 | "adminPrivateKey": { 41 | "path": "/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk" 42 | }, 43 | "peers": [ 44 | "peer0-org1" 45 | ], 46 | "signedCert": { 47 | "path": "/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/cert.pem" 48 | } 49 | } 50 | }, 51 | "peers": { 52 | "peer0-org1": { 53 | "tlsCACerts": { 54 | "path": "/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" 55 | }, 56 | "url": "grpcs://peer0-org1:7051" 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /deploy/dev/external-builder/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # The bin/build script is responsible for building, compiling, or transforming the contents 4 | # of a chaincode package into artifacts that can be used by release and run. 5 | # 6 | # The peer invokes build with three arguments: 7 | # bin/build CHAINCODE_SOURCE_DIR CHAINCODE_METADATA_DIR BUILD_OUTPUT_DIR 8 | # 9 | # When build is invoked, CHAINCODE_SOURCE_DIR contains the chaincode source and 10 | # CHAINCODE_METADATA_DIR contains the metadata.json file from the chaincode package installed to the peer. 11 | # BUILD_OUTPUT_DIR is the directory where build must place artifacts needed by release and run. 12 | # The build script should treat the input directories CHAINCODE_SOURCE_DIR and 13 | # CHAINCODE_METADATA_DIR as read only, but the BUILD_OUTPUT_DIR is writeable. 14 | 15 | CHAINCODE_SOURCE_DIR="$1" 16 | CHAINCODE_METADATA_DIR="$2" 17 | BUILD_OUTPUT_DIR="$3" 18 | 19 | set -euo pipefail 20 | 21 | #external chaincodes expect connection.json file in the chaincode package 22 | if [ ! -f "$CHAINCODE_SOURCE_DIR/connection.json" ]; then 23 | >&2 echo "$CHAINCODE_SOURCE_DIR/connection.json not found" 24 | exit 1 25 | fi 26 | 27 | #simply copy the endpoint information to specified output location 28 | cp $CHAINCODE_SOURCE_DIR/connection.json $BUILD_OUTPUT_DIR/connection.json 29 | 30 | if [ -d "$CHAINCODE_SOURCE_DIR/metadata" ]; then 31 | cp -a $CHAINCODE_SOURCE_DIR/metadata $BUILD_OUTPUT_DIR/metadata 32 | fi 33 | 34 | exit 0 -------------------------------------------------------------------------------- /deploy/dev/external-builder/detect: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # The bin/detect script is responsible for determining whether or not a buildpack 4 | # should be used to build a chaincode package and launch it. 5 | # 6 | # The peer invokes detect with two arguments: 7 | # bin/detect CHAINCODE_SOURCE_DIR CHAINCODE_METADATA_DIR 8 | # 9 | # When detect is invoked, CHAINCODE_SOURCE_DIR contains the chaincode source and 10 | # CHAINCODE_METADATA_DIR contains the metadata.json file from the chaincode package installed to the peer. 11 | # The CHAINCODE_SOURCE_DIR and CHAINCODE_METADATA_DIR should be treated as read only inputs. 12 | # If the buildpack should be applied to the chaincode source package, detect must return an exit code of 0; 13 | # any other exit code will indicate that the buildpack should not be applied. 14 | 15 | CHAINCODE_METADATA_DIR="$2" 16 | 17 | set -euo pipefail 18 | 19 | # use jq to extract the chaincode type from metadata.json and exit with 20 | # success if the chaincode type is golang 21 | if [ "$(cat "$CHAINCODE_METADATA_DIR/metadata.json" | sed -e 's/[{}]/''/g' | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'type'\042/){print $(i+1)}}}' | tr -d '"')" = "external" ]; then 22 | exit 0 23 | fi 24 | 25 | exit 1 -------------------------------------------------------------------------------- /deploy/dev/external-builder/release: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # The bin/release script is responsible for providing chaincode metadata to the peer. 4 | # bin/release is optional. If it is not provided, this step is skipped. 5 | # 6 | # The peer invokes release with two arguments: 7 | # bin/release BUILD_OUTPUT_DIR RELEASE_OUTPUT_DIR 8 | # 9 | # When release is invoked, BUILD_OUTPUT_DIR contains the artifacts 10 | # populated by the build program and should be treated as read only input. 11 | # RELEASE_OUTPUT_DIR is the directory where release must place artifacts to be consumed by the peer. 12 | 13 | set -euo pipefail 14 | 15 | BUILD_OUTPUT_DIR="$1" 16 | RELEASE_OUTPUT_DIR="$2" 17 | 18 | # copy indexes from metadata/* to the output directory 19 | # if [ -d "$BUILD_OUTPUT_DIR/metadata" ] ; then 20 | # cp -a "$BUILD_OUTPUT_DIR/metadata/"* "$RELEASE_OUTPUT_DIR/" 21 | # fi 22 | 23 | #external chaincodes expect artifacts to be placed under "$RELEASE_OUTPUT_DIR"/chaincode/server 24 | if [ -f $BUILD_OUTPUT_DIR/connection.json ]; then 25 | mkdir -p "$RELEASE_OUTPUT_DIR"/chaincode/server 26 | cp $BUILD_OUTPUT_DIR/connection.json "$RELEASE_OUTPUT_DIR"/chaincode/server 27 | 28 | #if tls_required is true, copy TLS files (using above example, the fully qualified path for these fils would be "$RELEASE_OUTPUT_DIR"/chaincode/server/tls) 29 | 30 | exit 0 31 | fi 32 | 33 | exit 1 -------------------------------------------------------------------------------- /deploy/dev/init-cc.sh: -------------------------------------------------------------------------------- 1 | docker exec -it cli-peer0-org1 /bin/bash -c 'cd /opt/gopath/src/github.com/chaincode/basic/packaging && peer lifecycle chaincode install basic-org1.tgz' 2 | docker exec -it cli-peer0-org1 /bin/bash -c 'PACKAGE_ID=$(echo $(peer lifecycle chaincode queryinstalled) | sed "s/.*Package ID: //; s/,.*//") && peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name $CHAINCODE_NAME --version $CHAINCODE_VERSION --init-required --package-id $PACKAGE_ID --sequence 1 -o $ORDERER_URL --tls --cafile $ORDERER_CA' 3 | docker exec -it cli-peer0-org1 /bin/bash -c 'peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name $CHAINCODE_NAME --version $CHAINCODE_VERSION --init-required --sequence 1 -o $ORDERER_URL --tls --cafile $ORDERER_CA' 4 | docker exec -it cli-peer0-org1 /bin/bash -c 'peer lifecycle chaincode commit -o $ORDERER_URL --channelID $CHANNEL_NAME --name $CHAINCODE_NAME --version $CHAINCODE_VERSION --sequence 1 --init-required --tls true --cafile $ORDERER_CA --peerAddresses peer0-org1:7051 --tlsRootCertFiles /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt && peer lifecycle chaincode querycommitted -C $CHANNEL_NAME' 5 | docker exec -it peer0-org1 /bin/sh -c "cd /var/hyperledger/production/externalbuilder/builds/*/release/chaincode/server && rm connection.json && echo '{\"address\":\"basic-org1:7052\",\"dial_timeout\":\"10s\",\"tls_required\":false,\"client_auth_required\":false,\"client_key\":\"-----BEGIN EC PRIVATE KEY----- ... -----END EC PRIVATE KEY-----\",\"client_cert\":\"-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----\",\"root_cert\":\"-----BEGIN CERTIFICATE---- ... -----END CERTIFICATE-----\"}' >> connection.json" 6 | docker exec -it cli-peer0-org1 /bin/bash -c 'peer chaincode invoke -o $ORDERER_URL --isInit --tls true --cafile $ORDERER_CA -C $CHANNEL_NAME -n $CHAINCODE_NAME --peerAddresses peer0-org1:7051 --tlsRootCertFiles /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt -c '\''{"Args":["InitLedger"]}'\'' --waitForEvent' -------------------------------------------------------------------------------- /deploy/dev/init-ccp.sh: -------------------------------------------------------------------------------- 1 | docker exec -it cli-peer0-org1 /bin/bash -c './scripts/ccp.sh && cp ./organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/* ./organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk' -------------------------------------------------------------------------------- /deploy/dev/init-channel.sh: -------------------------------------------------------------------------------- 1 | docker exec -it cli-peer0-org1 /bin/bash -c "./scripts/createAppChannel.sh" 2 | docker exec -it cli-peer0-org1 /bin/bash -c "peer channel join -b ./channel-artifacts/mychannel.block" 3 | docker exec -it cli-peer0-org1 /bin/bash -c "peer channel list" 4 | docker exec -it cli-peer0-org1 /bin/bash -c "./scripts/updateAnchorPeer.sh Org1MSP" -------------------------------------------------------------------------------- /deploy/dev/install.sh: -------------------------------------------------------------------------------- 1 | docker-compose -f docker-compose-ca.yaml up -d 2 | sleep 10 3 | ./create-certs.sh 4 | ./create-artifact.sh 5 | docker-compose -f docker-compose-test-net.yaml up -d 6 | sleep 10 7 | ./init-channel.sh 8 | ./init-cc.sh 9 | ./init-ccp.sh 10 | sleep 10 11 | docker-compose -f docker-compose-api.yaml up -d -------------------------------------------------------------------------------- /deploy/dev/scripts/ccp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function one_line_pem { 4 | echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`" 5 | } 6 | 7 | function json_ccp { 8 | local PP=$(one_line_pem $4) 9 | local CP=$(one_line_pem $5) 10 | sed -e "s/\${ORG}/$1/" \ 11 | -e "s/\${P0PORT}/$2/" \ 12 | -e "s/\${CAPORT}/$3/" \ 13 | -e "s#\${PEERPEM}#$PP#" \ 14 | -e "s#\${CAPEM}#$CP#" \ 15 | connection-profile/ccp-template.json 16 | } 17 | 18 | function yaml_ccp { 19 | local PP=$(one_line_pem $4) 20 | local CP=$(one_line_pem $5) 21 | sed -e "s/\${ORG}/$1/" \ 22 | -e "s/\${P0PORT}/$2/" \ 23 | -e "s/\${CAPORT}/$3/" \ 24 | -e "s#\${PEERPEM}#$PP#" \ 25 | -e "s#\${CAPEM}#$CP#" \ 26 | connection-profile/ccp-template.yaml | sed -e $'s/\\\\n/\\\n /g' 27 | } 28 | 29 | ORG=1 30 | P0PORT=7051 31 | CAPORT=7054 32 | PEERPEM=organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem 33 | CAPEM=organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem 34 | 35 | echo "$(json_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org1.json 36 | echo "$(yaml_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org1.yaml -------------------------------------------------------------------------------- /deploy/dev/scripts/createAppChannel.sh: -------------------------------------------------------------------------------- 1 | peer channel create -o orderer:7050 -c mychannel -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /organizations/peerOrganizations/org1.example.com/msp/tlscacerts/ca.crt -------------------------------------------------------------------------------- /deploy/dev/scripts/createChannel.sh: -------------------------------------------------------------------------------- 1 | CHANNEL_NAME="$1" 2 | DELAY="$2" 3 | MAX_RETRY="$3" 4 | VERBOSE="$4" 5 | : ${CHANNEL_NAME:="mychannel"} 6 | : ${DELAY:="3"} 7 | : ${MAX_RETRY:="5"} 8 | : ${VERBOSE:="true"} 9 | FABRIC_CFG_PATH=${PWD}configtx 10 | 11 | 12 | createChannelTx() { 13 | 14 | set -x 15 | configtxgen -profile OneOrgChannel -outputCreateChannelTx ./channel-artifacts/${CHANNEL_NAME}.tx -channelID $CHANNEL_NAME 16 | res=$? 17 | { set +x; } 2>/dev/null 18 | if [ $res -ne 0 ]; then 19 | fatalln "Failed to generate channel configuration transaction..." 20 | fi 21 | 22 | } 23 | 24 | createAncorPeerTx() { 25 | 26 | for orgmsp in Org1MSP; do 27 | 28 | echo "Generating anchor peer update transaction for ${orgmsp}" 29 | set -x 30 | configtxgen -profile OneOrgChannel -outputAnchorPeersUpdate ./channel-artifacts/${orgmsp}anchors.tx -channelID $CHANNEL_NAME -asOrg ${orgmsp} 31 | res=$? 32 | { set +x; } 2>/dev/null 33 | if [ $res -ne 0 ]; then 34 | fatalln "Failed to generate anchor peer update transaction for ${orgmsp}..." 35 | fi 36 | done 37 | } 38 | 39 | 40 | 41 | verifyResult() { 42 | if [ $1 -ne 0 ]; then 43 | fatalln "$2" 44 | fi 45 | } 46 | 47 | 48 | 49 | ## Create channeltx 50 | echo "Generating channel create transaction '${CHANNEL_NAME}.tx'" 51 | createChannelTx 52 | 53 | ## Create anchorpeertx 54 | echo "Generating anchor peer update transactions" 55 | createAncorPeerTx 56 | 57 | 58 | 59 | exit 0 -------------------------------------------------------------------------------- /deploy/dev/scripts/createGenesis.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | export FABRIC_CFG_PATH=${PWD}configtx 4 | 5 | 6 | configtxgen -profile OneOrgOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block -------------------------------------------------------------------------------- /deploy/dev/scripts/updateAnchorPeer.sh: -------------------------------------------------------------------------------- 1 | CORE_PEER_LOCALMSPID=$1 2 | peer channel update -o orderer:7050 -c mychannel -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile $ORDERER_CA -------------------------------------------------------------------------------- /deploy/dev/uninstall.sh: -------------------------------------------------------------------------------- 1 | docker-compose -f docker-compose-api.yaml down -v --remove-orphans 2 | docker-compose -f docker-compose-test-net.yaml down -v 3 | docker-compose -f docker-compose-ca.yaml down -v 4 | rm -rf wallet 5 | rm -rf channel-artifacts 6 | rm -rf system-genesis-block 7 | find organizations \! -name 'fabric-ca-server-config.yaml' -delete 8 | find connection-profile \! -name 'ccp-template*' -delete -------------------------------------------------------------------------------- /deploy/k8s/api/api-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: api 5 | labels: 6 | app: api 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: api 11 | ports: 12 | - protocol: TCP 13 | targetPort: 8080 14 | port: 8080 -------------------------------------------------------------------------------- /deploy/k8s/api/api.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: api 5 | labels: 6 | app: api 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: api 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: api 16 | spec: 17 | containers: 18 | - name: api 19 | image: suayb/hlf-api:1.0.0 20 | imagePullPolicy: Always 21 | stdin: true 22 | tty: true 23 | resources: 24 | requests: 25 | memory: "400Mi" 26 | cpu: "300m" 27 | limits: 28 | memory: "450Mi" 29 | cpu: "400m" 30 | livenessProbe: 31 | httpGet: 32 | port: 8080 33 | path: /actuator/health/liveness 34 | initialDelaySeconds: 30 35 | periodSeconds: 30 36 | failureThreshold: 3 37 | readinessProbe: 38 | httpGet: 39 | port: 8080 40 | path: /actuator/health/readiness 41 | initialDelaySeconds: 30 42 | periodSeconds: 30 43 | failureThreshold: 3 44 | env: 45 | - name: HYPERLEDGER-FABRIC_NETWORK-CONFIG 46 | value: "file:/usr/src/app/connection-profile/connection-org1.json" 47 | - name: HYPERLEDGER-FABRIC_WALLET-PATH 48 | value: /usr/src/app/wallet 49 | - name: HYPERLEDGER-FABRIC_CA-CLIENT_CA-NAME 50 | value: ca-org1 51 | - name: HYPERLEDGER-FABRIC_GATEWAY_CHANNEL-NAME 52 | value: mychannel 53 | - name: HYPERLEDGER-FABRIC_GATEWAY_CHAINCODE-NAME 54 | value: basic 55 | - name: HYPERLEDGER-FABRIC_CA-CLIENT_ADMIN-USER-ID 56 | value: admin 57 | - name: HYPERLEDGER-FABRIC_CA-CLIENT_ADMIN-PASSWORD 58 | value: adminpw 59 | - name: HYPERLEDGER-FABRIC_GATEWAY_CA-USER_REGISTRATION-ENABLED 60 | value: "true" 61 | - name: HYPERLEDGER-FABRIC_GATEWAY_CA-USER_USER-ID 62 | value: tom 63 | - name: HYPERLEDGER-FABRIC_GATEWAY_CA-USER_ORG-MSP 64 | value: Org1MSP 65 | - name: HYPERLEDGER-FABRIC_GATEWAY_CA-USER_AFFILIATION 66 | value: org1.department1 67 | ports: 68 | - containerPort: 8080 69 | volumeMounts: 70 | - name: data 71 | mountPath: /usr/src/app/connection-profile 72 | subPath: connection-profile # blochani networke erişmek için gerekli. 73 | - name: data 74 | mountPath: /organizations 75 | subPath: organizations # sertifiakalar erişim için gerekli. 76 | - name: data 77 | mountPath: /usr/src/app/wallet 78 | subPath: wallet # identity kalıcı hale gelir,api chash verdiğinde bile. 79 | volumes: 80 | - name: data 81 | persistentVolumeClaim: 82 | claimName: fabricfiles-pvc 83 | - name: ca-client-config -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-orderer-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ca-orderer 5 | labels: 6 | app: ca-orderer 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: ca-orderer # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - protocol: TCP 13 | targetPort: 10054 # contanier portu 14 | port: 10054 # service portu 15 | -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-orderer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ca-orderer 5 | labels: 6 | app: ca-orderer 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: ca-orderer 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: ca-orderer 16 | spec: 17 | containers: 18 | - name: ca-orderer 19 | image: hyperledger/fabric-ca:1.4.9 20 | imagePullPolicy: IfNotPresent 21 | command: 22 | [ 23 | "fabric-ca-server", 24 | "start", "-b", "admin:adminpw", "--port", "10054", "-d" 25 | ] 26 | resources: 27 | requests: 28 | memory: "300Mi" 29 | cpu: "300m" 30 | limits: 31 | memory: "500Mi" 32 | cpu: "350m" 33 | ports: 34 | - containerPort: 10054 35 | env: 36 | - name: FABRIC_CA_SERVER_CA_NAME 37 | value: ca-orderer 38 | - name: FABRIC_CA_SERVER_TLS_ENABLED 39 | value: "true" 40 | volumeMounts: 41 | - name: data 42 | mountPath: /etc/hyperledger/fabric-ca-server 43 | subPath: organizations/fabric-ca/ordererOrg 44 | volumes: 45 | - name: data 46 | persistentVolumeClaim: 47 | claimName: fabricfiles-pvc 48 | -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-org1-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ca-org1 5 | labels: 6 | app: ca-org1 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: ca-org1 # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - protocol: TCP 13 | targetPort: 7054 # contanier portu 14 | port: 7054 # service portu 15 | -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-org1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ca-org1 5 | labels: 6 | app: ca-org1 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: ca-org1 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: ca-org1 16 | spec: 17 | containers: 18 | - name: ca-org1 19 | image: hyperledger/fabric-ca:1.4.9 20 | imagePullPolicy: IfNotPresent 21 | command: 22 | [ 23 | "fabric-ca-server", 24 | "start", "-b", "admin:adminpw", "--port", "7054", "-d" 25 | ] 26 | resources: 27 | requests: 28 | memory: "300Mi" 29 | cpu: "250m" 30 | limits: 31 | memory: "500Mi" 32 | cpu: "350m" 33 | ports: 34 | - containerPort: 7054 35 | env: 36 | - name: FABRIC_CA_SERVER_CA_NAME 37 | value: ca-org1 38 | - name: FABRIC_CA_SERVER_TLS_ENABLED 39 | value: "true" 40 | - name: FABRIC_CA_SERVER_CSR_CN 41 | value: "ca-org1" 42 | - name: FABRIC_CA_SERVER_CSR_HOSTS 43 | value: "ca-org1" 44 | volumeMounts: 45 | - name: data 46 | mountPath: /etc/hyperledger/fabric-ca-server 47 | subPath: organizations/fabric-ca/org1 48 | volumes: 49 | - name: data 50 | persistentVolumeClaim: 51 | claimName: fabricfiles-pvc 52 | -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-org2-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ca-org2 5 | labels: 6 | app: ca-org2 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: ca-org2 # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - protocol: TCP 13 | targetPort: 8054 # contanier portu 14 | port: 8054 # service portu 15 | -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-org2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ca-org2 5 | labels: 6 | app: ca-org2 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: ca-org2 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: ca-org2 16 | spec: 17 | containers: 18 | - name: ca-org2 19 | image: hyperledger/fabric-ca:1.4.9 20 | imagePullPolicy: IfNotPresent 21 | command: 22 | [ 23 | "fabric-ca-server", 24 | "start", "-b", "admin:adminpw", "--port", "8054", "-d" 25 | ] 26 | resources: 27 | requests: 28 | memory: "300Mi" 29 | cpu: "300m" 30 | limits: 31 | memory: "500Mi" 32 | cpu: "350m" 33 | ports: 34 | - containerPort: 8054 35 | env: 36 | - name: FABRIC_CA_SERVER_CA_NAME 37 | value: ca-org2 38 | - name: FABRIC_CA_SERVER_TLS_ENABLED 39 | value: "true" 40 | - name: FABRIC_CA_SERVER_CSR_CN 41 | value: "ca-org2" 42 | - name: FABRIC_CA_SERVER_CSR_HOSTS 43 | value: "ca-org2" 44 | volumeMounts: 45 | - name: data 46 | mountPath: /etc/hyperledger/fabric-ca-server 47 | subPath: organizations/fabric-ca/org2 48 | volumes: 49 | - name: data 50 | persistentVolumeClaim: 51 | claimName: fabricfiles-pvc 52 | -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-org3-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ca-org3 5 | labels: 6 | app: ca-org3 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: ca-org3 # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - protocol: TCP 13 | targetPort: 9054 # contanier portu 14 | port: 9054 # service portu 15 | -------------------------------------------------------------------------------- /deploy/k8s/ca/ca-org3.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ca-org3 5 | labels: 6 | app: ca-org3 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: ca-org3 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: ca-org3 16 | spec: 17 | containers: 18 | - name: ca-org3 19 | image: hyperledger/fabric-ca:1.4.9 20 | imagePullPolicy: IfNotPresent 21 | command: 22 | [ 23 | "fabric-ca-server", 24 | "start", "-b", "admin:adminpw", "--port", "9054", "-d" 25 | ] 26 | resources: 27 | requests: 28 | memory: "300Mi" 29 | cpu: "300m" 30 | limits: 31 | memory: "500Mi" 32 | cpu: "350m" 33 | ports: 34 | - containerPort: 9054 35 | env: 36 | - name: FABRIC_CA_SERVER_CA_NAME 37 | value: ca-org3 38 | - name: FABRIC_CA_SERVER_TLS_ENABLED 39 | value: "true" 40 | - name: FABRIC_CA_SERVER_CSR_CN 41 | value: "ca-org3" 42 | - name: FABRIC_CA_SERVER_CSR_HOSTS 43 | value: "ca-org3" 44 | volumeMounts: 45 | - name: data 46 | mountPath: /etc/hyperledger/fabric-ca-server 47 | subPath: organizations/fabric-ca/org3 48 | volumes: 49 | - name: data 50 | persistentVolumeClaim: 51 | claimName: fabricfiles-pvc 52 | -------------------------------------------------------------------------------- /deploy/k8s/cc/org1-chaincode-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: chaincode-basic-org1 5 | labels: 6 | app: chaincode-basic-org1 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: chaincode-basic-org1 11 | strategy: 12 | type: Recreate 13 | template: 14 | metadata: 15 | labels: 16 | app: chaincode-basic-org1 17 | spec: 18 | containers: 19 | - name: chaincode-basic-org1 20 | image: suayb/basic-cc-hlf:1.0 21 | imagePullPolicy: Always 22 | ports: 23 | - containerPort: 7052 24 | env: 25 | - name: CHAINCODE_ID # notdaki peer0-org1 ile değiştirildi.chaincode install sonrası oluşur. 26 | value: "basic:35478980dc38b87771c3dd752ef9bc263ac5ce9785d0f1843641f88a1869b730" 27 | - name: CHAINCODE_SERVER_ADDRESS 28 | value: "0.0.0.0:7052" -------------------------------------------------------------------------------- /deploy/k8s/cc/org1-chaincode-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: basic-org1 5 | labels: 6 | app: basic-org1 7 | spec: 8 | selector: 9 | app: chaincode-basic-org1 10 | ports: 11 | - name: grpc 12 | protocol: TCP 13 | targetPort: 7052 14 | port: 7052 15 | -------------------------------------------------------------------------------- /deploy/k8s/cc/org2-chaincode-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: chaincode-basic-org2 5 | labels: 6 | app: chaincode-basic-org2 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: chaincode-basic-org2 11 | strategy: 12 | type: Recreate 13 | template: 14 | metadata: 15 | labels: 16 | app: chaincode-basic-org2 17 | spec: 18 | containers: 19 | - name: chaincode-basic-org2 20 | image: suayb/basic-cc-hlf:1.0 21 | imagePullPolicy: Always 22 | ports: 23 | - containerPort: 7052 24 | env: 25 | - name: CHAINCODE_ID # notdaki peer0-org2 ile değiştirildi. 26 | value: "basic:116339123252b333d8eb05b36268d1ddb3435b655b81343ae3e19fbe32b76866" 27 | - name: CHAINCODE_SERVER_ADDRESS 28 | value: "0.0.0.0:7052" -------------------------------------------------------------------------------- /deploy/k8s/cc/org2-chaincode-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: basic-org2 5 | labels: 6 | app: basic-org2 7 | spec: 8 | selector: 9 | app: chaincode-basic-org2 10 | ports: 11 | - name: grpc 12 | protocol: TCP 13 | targetPort: 7052 14 | port: 7052 -------------------------------------------------------------------------------- /deploy/k8s/cc/org3-chaincode-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: chaincode-basic-org3 5 | labels: 6 | app: chaincode-basic-org3 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: chaincode-basic-org3 11 | strategy: 12 | type: Recreate 13 | template: 14 | metadata: 15 | labels: 16 | app: chaincode-basic-org3 17 | spec: 18 | containers: 19 | - name: chaincode-basic-org3 20 | image: suayb/basic-cc-hlf:1.0 21 | imagePullPolicy: Always 22 | ports: 23 | - containerPort: 7052 24 | env: 25 | - name: CHAINCODE_ID # notdaki peer0-org3 ile değiştirildi. 26 | value: "basic:6739161a64e55d45ec2b852e5218a7580613654fdfc8c3e7656a4c822379b5c4" 27 | - name: CHAINCODE_SERVER_ADDRESS 28 | value: "0.0.0.0:7052" -------------------------------------------------------------------------------- /deploy/k8s/cc/org3-chaincode-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: basic-org3 5 | labels: 6 | app: basic-org3 7 | spec: 8 | selector: 9 | app: chaincode-basic-org3 10 | ports: 11 | - name: grpc 12 | protocol: TCP 13 | targetPort: 7052 14 | port: 7052 -------------------------------------------------------------------------------- /deploy/k8s/explorer/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: explorer-config 5 | data: 6 | network.json: |- 7 | { 8 | "name": "first-network", 9 | "version": "1.0.0", 10 | "client": { 11 | "tlsEnable": true, 12 | "adminCredential": { 13 | "id": "admin", 14 | "password": "adminpw" 15 | }, 16 | "enableAuthentication": true, 17 | "organization": "Org1MSP", 18 | "connection": { 19 | "timeout": { 20 | "peer": { 21 | "endorser": "300" 22 | }, 23 | "orderer": "300" 24 | } 25 | } 26 | }, 27 | "channels": { 28 | "mychannel": { 29 | "peers": { 30 | "peer0-org1": {} 31 | }, 32 | "connection": { 33 | "timeout": { 34 | "peer": { 35 | "endorser": "6000", 36 | "eventHub": "6000", 37 | "eventReg": "6000" 38 | } 39 | } 40 | } 41 | } 42 | }, 43 | "organizations": { 44 | "Org1MSP": { 45 | "mspid": "Org1MSP", 46 | "adminPrivateKey": { 47 | "path": "/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk" 48 | }, 49 | "peers": [ 50 | "peer0-org1" 51 | ], 52 | "signedCert": { 53 | "path": "/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/cert.pem" 54 | } 55 | } 56 | }, 57 | "peers": { 58 | "peer0-org1": { 59 | "tlsCACerts": { 60 | "path": "/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" 61 | }, 62 | "url": "grpcs://peer0-org1:7051" 63 | } 64 | } 65 | } 66 | 67 | config.json: |- 68 | { 69 | "network-configs": { 70 | "first-network": { 71 | "name": "first-network", 72 | "profile": "./first-network.json" 73 | } 74 | }, 75 | "license": "Apache-2.0" 76 | } 77 | -------------------------------------------------------------------------------- /deploy/k8s/explorer/explorer-db-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: explorer-db 5 | labels: 6 | app: explorer-db 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: explorer-db 11 | ports: 12 | - protocol: TCP 13 | targetPort: 5432 14 | port: 5432 -------------------------------------------------------------------------------- /deploy/k8s/explorer/explorer-db.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: explorer-db 5 | labels: 6 | app: explorer-db 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: explorer-db 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: explorer-db 16 | spec: 17 | containers: 18 | - name: explorer-db 19 | image: hyperledger/explorer-db:1.1.8 20 | resources: 21 | limits: 22 | memory: "528Mi" 23 | cpu: "400m" 24 | ports: 25 | - containerPort: 5432 26 | livenessProbe: 27 | exec: 28 | command: 29 | - /bin/sh 30 | - -c 31 | - exec pg_isready -U "postgres" -h 127.0.0.1 -p 5432 32 | initialDelaySeconds: 30 33 | periodSeconds: 10 34 | successThreshold: 1 35 | timeoutSeconds: 5 36 | failureThreshold: 6 37 | readinessProbe: 38 | exec: 39 | command: 40 | - /bin/sh 41 | - -c 42 | - exec pg_isready -U "postgres" -h 127.0.0.1 -p 5432 43 | initialDelaySeconds: 5 44 | periodSeconds: 10 45 | successThreshold: 1 46 | timeoutSeconds: 5 47 | failureThreshold: 6 48 | env: 49 | - name: DATABASE_DATABASE 50 | value: fabricexplorer 51 | - name: DATABASE_USERNAME 52 | value: hppoc 53 | - name: DATABASE_PASSWORD 54 | value: password 55 | volumeMounts: 56 | - name: explorer-db 57 | mountPath: /var/lib/postgresql/data 58 | subPath: explorer/explorer-db # postgesql datası 59 | volumes: 60 | - name: explorer-db 61 | persistentVolumeClaim: 62 | claimName: fabricfiles-pvc 63 | 64 | -------------------------------------------------------------------------------- /deploy/k8s/explorer/explorer-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: explorer 5 | labels: 6 | app: explorer 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: explorer 11 | ports: 12 | - protocol: TCP 13 | targetPort: 8080 14 | port: 8080 -------------------------------------------------------------------------------- /deploy/k8s/explorer/explorer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: explorer 5 | labels: 6 | app: explorer 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: explorer 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: explorer 16 | spec: 17 | containers: 18 | - name: explorer 19 | image: hyperledger/explorer:1.1.8 20 | resources: 21 | limits: 22 | memory: "528Mi" 23 | cpu: "400m" 24 | ports: 25 | - containerPort: 8080 26 | env: 27 | - name: DATABASE_HOST 28 | value: "explorer-db" 29 | - name: DATABASE_DATABASE 30 | value: "fabricexplorer" 31 | - name: DATABASE_USERNAME 32 | value: "hppoc" 33 | - name: DATABASE_PASSWD 34 | value: "password" 35 | - name: LOG_LEVEL_APP 36 | value: "debug" 37 | - name: LOG_LEVEL_DB 38 | value: "debug" 39 | - name: LOG_LEVEL_CONSOLE 40 | value: "info" 41 | - name: LOG_CONSOLE_STDOUT 42 | value: "true" 43 | - name: DISCOVERY_AS_LOCALHOST 44 | value: "false" 45 | volumeMounts: 46 | - name: fabricfiles 47 | mountPath: /organizations 48 | subPath: organizations # sertifikalar için 49 | - name: explorer-config 50 | mountPath: /opt/explorer/app/platform/fabric/config.json 51 | subPath: config.json # fabric bağlantısı için gerekli.pathi tutar. 52 | - name: explorer-config 53 | mountPath: /opt/explorer/app/platform/fabric/first-network.json 54 | subPath: network.json # fabric bağlantısı için gerekli. 55 | volumes: 56 | - name: fabricfiles 57 | persistentVolumeClaim: 58 | claimName: fabricfiles-pvc 59 | - name: explorer-config 60 | configMap: 61 | name: explorer-config 62 | items: 63 | - key: config.json 64 | path: config.json 65 | - key: network.json 66 | path: network.json 67 | -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/.dockerignore: -------------------------------------------------------------------------------- 1 | chaincode.env* 2 | *.json 3 | *.md 4 | *.tar.gz 5 | *.tgz 6 | -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Go template 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | vendor/ 11 | tmp/ 12 | data/ 13 | 14 | # Test binary, built with `go test -c` 15 | *.test 16 | 17 | # Output of the go coverage tool, specifically when used with LiteIDE 18 | *.o 19 | *.a 20 | *.so 21 | *.prof 22 | *.out 23 | 24 | # Editors 25 | .idea/* 26 | *.iml 27 | *.iws 28 | *.ipr 29 | *.ids 30 | *.orig 31 | 32 | **/sponge_log.log 33 | 34 | testing/kokoro/test-env.sh 35 | 36 | # Vagrant 37 | .vagrant/ -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/Dockerfile: -------------------------------------------------------------------------------- 1 | # This image is a microservice in golang for the Degree chaincode 2 | FROM golang:1.14.6-alpine AS build 3 | 4 | COPY ./ /go/src/github.com/marbles 5 | WORKDIR /go/src/github.com/marbles 6 | 7 | # Build application 8 | RUN go build -o chaincode -v . 9 | 10 | # Production ready image 11 | # Pass the binary to the prod image 12 | FROM alpine:3.11 as prod 13 | 14 | COPY --from=build /go/src/github.com/marbles/chaincode /app/chaincode 15 | 16 | USER 1000 17 | 18 | WORKDIR /app 19 | CMD ./chaincode -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/susimsek 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/golang/protobuf v1.3.3 7 | github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 8 | github.com/hyperledger/fabric-contract-api-go v1.1.1 9 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect 10 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect 11 | google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/packaging/basic-org1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/deploy/k8s/fabricfiles/chaincode/basic/packaging/basic-org1.tgz -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/packaging/basic-org2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/deploy/k8s/fabricfiles/chaincode/basic/packaging/basic-org2.tgz -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/packaging/basic-org3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/deploy/k8s/fabricfiles/chaincode/basic/packaging/basic-org3.tgz -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/packaging/connection.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "basic-org3:7052", 3 | "dial_timeout": "10s", 4 | "tls_required": false, 5 | "client_auth_required": false, 6 | "client_key": "-----BEGIN EC PRIVATE KEY----- ... -----END EC PRIVATE KEY-----", 7 | "client_cert": "-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----", 8 | "root_cert": "-----BEGIN CERTIFICATE---- ... -----END CERTIFICATE-----" 9 | } 10 | -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/chaincode/basic/packaging/metadata.json: -------------------------------------------------------------------------------- 1 | {"path":"","type":"external","label":"basic"} 2 | -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/connection-profile/ccp-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-network-org${ORG}", 3 | "version": "1.0.0", 4 | "client": { 5 | "organization": "Org${ORG}", 6 | "connection": { 7 | "timeout": { 8 | "peer": { 9 | "endorser": "300" 10 | } 11 | } 12 | } 13 | }, 14 | "organizations": { 15 | "Org${ORG}": { 16 | "mspid": "Org${ORG}MSP", 17 | "peers": [ 18 | "peer0-org${ORG}" 19 | ], 20 | "certificateAuthorities": [ 21 | "ca-org${ORG}" 22 | ] 23 | } 24 | }, 25 | "peers": { 26 | "peer0-org${ORG}": { 27 | "url": "grpcs://peer0-org${ORG}:${P0PORT}", 28 | "tlsCACerts": { 29 | "pem": "${PEERPEM}" 30 | }, 31 | "grpcOptions": { 32 | "ssl-target-name-override": "peer0-org${ORG}", 33 | "hostnameOverride": "peer0-org${ORG}" 34 | } 35 | } 36 | }, 37 | "certificateAuthorities": { 38 | "ca-org${ORG}": { 39 | "url": "https://ca-org${ORG}:${CAPORT}", 40 | "caName": "ca-org${ORG}", 41 | "tlsCACerts": { 42 | "pem": ["${CAPEM}"] 43 | }, 44 | "httpOptions": { 45 | "verify": false 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/connection-profile/ccp-template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: test-network-org${ORG} 3 | version: 1.0.0 4 | client: 5 | organization: Org${ORG} 6 | connection: 7 | timeout: 8 | peer: 9 | endorser: '300' 10 | organizations: 11 | Org${ORG}: 12 | mspid: Org${ORG}MSP 13 | peers: 14 | - peer0-org${ORG} 15 | certificateAuthorities: 16 | - ca-org${ORG} 17 | peers: 18 | peer0-org${ORG}: 19 | url: grpcs://peer0-org${ORG}:${P0PORT} 20 | tlsCACerts: 21 | pem: "${PEERPEM}" 22 | grpcOptions: 23 | ssl-target-name-override: peer0-org${ORG} 24 | hostnameOverride: peer0-org${ORG} 25 | certificateAuthorities: 26 | ca-org${ORG}: 27 | url: https://ca-org${ORG}:${CAPORT} 28 | caName: ca-org${ORG} 29 | tlsCACerts: 30 | pem: 31 | - "${CAPEM}" 32 | httpOptions: 33 | verify: false 34 | -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/scripts/ccp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function one_line_pem { 4 | echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`" 5 | } 6 | 7 | function json_ccp { 8 | local PP=$(one_line_pem $4) 9 | local CP=$(one_line_pem $5) 10 | sed -e "s/\${ORG}/$1/" \ 11 | -e "s/\${P0PORT}/$2/" \ 12 | -e "s/\${CAPORT}/$3/" \ 13 | -e "s#\${PEERPEM}#$PP#" \ 14 | -e "s#\${CAPEM}#$CP#" \ 15 | connection-profile/ccp-template.json 16 | } 17 | 18 | function yaml_ccp { 19 | local PP=$(one_line_pem $4) 20 | local CP=$(one_line_pem $5) 21 | sed -e "s/\${ORG}/$1/" \ 22 | -e "s/\${P0PORT}/$2/" \ 23 | -e "s/\${CAPORT}/$3/" \ 24 | -e "s#\${PEERPEM}#$PP#" \ 25 | -e "s#\${CAPEM}#$CP#" \ 26 | connection-profile/ccp-template.yaml | sed -e $'s/\\\\n/\\\n /g' 27 | } 28 | 29 | ORG=1 30 | P0PORT=7051 31 | CAPORT=7054 32 | PEERPEM=organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem 33 | CAPEM=organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem 34 | 35 | echo "$(json_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org1.json 36 | echo "$(yaml_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org1.yaml 37 | 38 | ORG=2 39 | P0PORT=9051 40 | CAPORT=8054 41 | PEERPEM=organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem 42 | CAPEM=organizations/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem 43 | 44 | echo "$(json_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org2.json 45 | echo "$(yaml_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org2.yaml 46 | 47 | 48 | 49 | 50 | ORG=3 51 | P0PORT=11051 52 | CAPORT=9054 53 | PEERPEM=organizations/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem 54 | CAPEM=organizations/peerOrganizations/org3.example.com/ca/ca.org3.example.com-cert.pem 55 | 56 | echo "$(json_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org3.json 57 | echo "$(yaml_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > connection-profile/connection-org3.yaml -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/scripts/createAppChannel.sh: -------------------------------------------------------------------------------- 1 | peer channel create -o orderer:7050 -c mychannel -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/scripts/createChannel.sh: -------------------------------------------------------------------------------- 1 | CHANNEL_NAME="$1" 2 | DELAY="$2" 3 | MAX_RETRY="$3" 4 | VERBOSE="$4" 5 | : ${CHANNEL_NAME:="mychannel"} 6 | : ${DELAY:="3"} 7 | : ${MAX_RETRY:="5"} 8 | : ${VERBOSE:="true"} 9 | FABRIC_CFG_PATH=${PWD}configtx 10 | 11 | 12 | createChannelTx() { 13 | 14 | set -x 15 | configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/${CHANNEL_NAME}.tx -channelID $CHANNEL_NAME 16 | res=$? 17 | { set +x; } 2>/dev/null 18 | if [ $res -ne 0 ]; then 19 | fatalln "Failed to generate channel configuration transaction..." 20 | fi 21 | 22 | } 23 | 24 | createAncorPeerTx() { 25 | 26 | for orgmsp in Org1MSP Org2MSP Org3MSP; do 27 | 28 | echo "Generating anchor peer update transaction for ${orgmsp}" 29 | set -x 30 | configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/${orgmsp}anchors.tx -channelID $CHANNEL_NAME -asOrg ${orgmsp} 31 | res=$? 32 | { set +x; } 2>/dev/null 33 | if [ $res -ne 0 ]; then 34 | fatalln "Failed to generate anchor peer update transaction for ${orgmsp}..." 35 | fi 36 | done 37 | } 38 | 39 | 40 | 41 | verifyResult() { 42 | if [ $1 -ne 0 ]; then 43 | fatalln "$2" 44 | fi 45 | } 46 | 47 | 48 | 49 | ## Create channeltx 50 | echo "Generating channel create transaction '${CHANNEL_NAME}.tx'" 51 | createChannelTx 52 | 53 | ## Create anchorpeertx 54 | echo "Generating anchor peer update transactions" 55 | createAncorPeerTx 56 | 57 | 58 | 59 | exit 0 -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/scripts/createGenesis.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | export FABRIC_CFG_PATH=${PWD}configtx 4 | 5 | 6 | configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/scripts/packageChaincode.sh: -------------------------------------------------------------------------------- 1 | while [ $# -gt 0 ]; do 2 | case "$1" in 3 | --cc_name=*) 4 | CHAINCODE_NAME="${1#*=}" 5 | ;; 6 | --cc_org1=*) 7 | CC_ORG1="${1#*=}" 8 | ;; 9 | --cc_org2=*) 10 | CC_ORG2="${1#*=}" 11 | ;; 12 | --cc_org3=*) 13 | CC_ORG3="${1#*=}" 14 | ;; 15 | *) 16 | printf "***************************\n" 17 | printf "* Error: Invalid argument.*\n" 18 | printf "***************************\n" 19 | exit 1 20 | esac 21 | shift 22 | done 23 | 24 | CC_PATH=/chaincode/$CHAINCODE_NAME 25 | 26 | create_connection_json(){ 27 | mkdir -p $CC_PATH/packaging 28 | cd $CC_PATH/packaging 29 | json='{ 30 | "address": "'$CC_ORG1'", 31 | "dial_timeout": "10s", 32 | "tls_required": false, 33 | "client_auth_required": false, 34 | "client_key": "-----BEGIN EC PRIVATE KEY----- ... -----END EC PRIVATE KEY-----", 35 | "client_cert": "-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----", 36 | "root_cert": "-----BEGIN CERTIFICATE---- ... -----END CERTIFICATE-----" 37 | }' 38 | echo $json > connection.json 39 | } 40 | 41 | create_metadata_json(){ 42 | json='{ 43 | "path":"","type":"external","label":"'$CHAINCODE_NAME'" 44 | }' 45 | echo $json > metadata.json 46 | } 47 | 48 | package_chaincode(){ 49 | package basic-org1.tgz 50 | sed -i "s/$CC_ORG1/$CC_ORG2/g" connection.json 51 | package basic-org2.tgz 52 | sed -i "s/$CC_ORG2/$CC_ORG3/g" connection.json 53 | package basic-org3.tgz 54 | } 55 | 56 | package(){ 57 | tar_name="$1" 58 | tar cfz code.tar.gz connection.json 59 | tar cfz $tar_name code.tar.gz metadata.json 60 | rm code.tar.gz 61 | } 62 | 63 | # Let's go ################################################################################### 64 | create_connection_json 65 | create_metadata_json 66 | package_chaincode -------------------------------------------------------------------------------- /deploy/k8s/fabricfiles/scripts/updateAnchorPeer.sh: -------------------------------------------------------------------------------- 1 | CORE_PEER_LOCALMSPID=$1 2 | peer channel update -o orderer:7050 -c mychannel -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile $ORDERER_CA -------------------------------------------------------------------------------- /deploy/k8s/ingress/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress 5 | annotations: 6 | kubernetes.io/ingress.class: "nginx" 7 | spec: 8 | # tls: 9 | # - hosts: 10 | # - hlf-k8.tk 11 | # - api.hlf-k8.tk 12 | # - explorer.hlf-k8.tk 13 | # - grafana.hlf-k8.tk 14 | # secretName: tls-cert # sertifika bu isimde saklanır. 15 | rules: 16 | - host: hlf-k8.tk # frontend domain 17 | http: 18 | paths: 19 | - path: / 20 | pathType: Prefix 21 | backend: 22 | service: 23 | name: frontend 24 | port: 25 | number: 80 # servis port 26 | - host: api.hlf-k8.tk # api domain 27 | http: 28 | paths: 29 | - path: / 30 | pathType: Prefix 31 | backend: 32 | service: 33 | name: api 34 | port: 35 | number: 8080 # servis port 36 | - host: explorer.hlf-k8.tk # explorer domain 37 | http: 38 | paths: 39 | - path: / 40 | pathType: Prefix 41 | backend: 42 | service: 43 | name: explorer 44 | port: 45 | number: 8080 # servis port 46 | - host: grafana.hlf-k8.tk # grafana domain 47 | http: 48 | paths: 49 | - path: / 50 | pathType: Prefix 51 | backend: 52 | service: 53 | name: grafana 54 | port: 55 | number: 3000 # servis port 56 | -------------------------------------------------------------------------------- /deploy/k8s/ingress/issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1alpha2 2 | kind: ClusterIssuer 3 | metadata: 4 | name: letsencrypt-prod 5 | namespace: cert-manager 6 | spec: 7 | acme: 8 | # The ACME server URL 9 | server: https://acme-v02.api.letsencrypt.org/directory # letencrpt prod url 10 | # Email address used for ACME registration 11 | email: suaybsimsek58@gmail.com 12 | # Name of a secret used to store the ACME account private key 13 | privateKeySecretRef: 14 | name: letsencrypt-prod 15 | # Enable the HTTP-01 challenge provider 16 | solvers: 17 | - http01: 18 | ingress: 19 | class: nginx # HTTP-01 için nginx ayarlandı. -------------------------------------------------------------------------------- /deploy/k8s/job/create-app-channel.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: create-app-channel 5 | spec: 6 | backoffLimit: 2 7 | parallelism: 1 # maksiumum çalıştırılacak pod 8 | completions: 1 9 | template: 10 | spec: 11 | containers: 12 | - name: create-app-channel 13 | image: hyperledger/fabric-tools:2.3 14 | workingDir: / 15 | command: 16 | - /bin/bash 17 | - -c 18 | - | 19 | ./scripts/createAppChannel.sh 20 | env: 21 | - name: ORDERER_CA # orderer ca konfigurasyonu 22 | value: /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 23 | - name: CORE_PEER_ADDRESS # peer adresi 24 | value: peer0-org1:7051 25 | - name: CORE_PEER_ID 26 | value: cli.peer0.org1.example.com 27 | - name: CORE_PEER_LOCALMSPID 28 | value: Org1MSP 29 | - name: CORE_PEER_MSPCONFIGPATH 30 | value: /organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 31 | - name: CORE_PEER_TLS_CERT_FILE 32 | value: /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt 33 | - name: CORE_PEER_TLS_ENABLED 34 | value: "true" 35 | - name: CORE_PEER_TLS_KEY_FILE 36 | value: /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key 37 | - name: CORE_PEER_TLS_ROOTCERT_FILE 38 | value: /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 39 | - name: FABRIC_LOGGING_SPEC 40 | value: ERROR 41 | - name: GOPATH 42 | value: /opt/gopath 43 | - name: SYS_CHANNEL 44 | value: system-channel 45 | - name: CORE_CHAINCODE_BUILDER 46 | value: hyperledger/fabric-ccenv:1.4.8 47 | volumeMounts: 48 | - name: fabricfiles 49 | mountPath: /organizations 50 | subPath: organizations # sertifikalara erişmek için 51 | - name: fabricfiles 52 | mountPath: /configtx 53 | subPath: configtx # configtx.yaml dosyası için. 54 | - name: fabricfiles 55 | mountPath: /channel-artifacts 56 | subPath: channel-artifacts # channel artifact dir 57 | - name: fabricfiles 58 | mountPath: /scripts 59 | subPath: scripts 60 | - name: fabricfiles 61 | mountPath: /opt/gopath/src/github.com/chaincode 62 | subPath: chaincode # chanicode dir 63 | restartPolicy: OnFailure 64 | volumes: 65 | - name: fabricfiles 66 | persistentVolumeClaim: 67 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/job/create-artifacts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: create-artifacts 5 | spec: 6 | backoffLimit: 1 7 | template: 8 | spec: 9 | containers: 10 | - name: create-artifacts 11 | image: hyperledger/fabric-tools:2.3 12 | workingDir: / 13 | command: 14 | - /bin/bash 15 | - -c 16 | - | 17 | ./scripts/createGenesis.sh && 18 | ./scripts/createChannel.sh 19 | volumeMounts: 20 | - name: fabricfiles 21 | mountPath: /organizations 22 | subPath: organizations # sertifikalara ihtiyacımız olduğu için buraya mount ettik. 23 | - name: fabricfiles 24 | mountPath: /configtx 25 | subPath: configtx # configtx.yaml var.genesis block ve channel tranasction için gerekli. 26 | - name: fabricfiles 27 | mountPath: /system-genesis-block 28 | subPath: system-genesis-block # genesis block dosyası tutuluyor 29 | - name: fabricfiles 30 | mountPath: /channel-artifacts 31 | subPath: channel-artifacts # channel transaction tutulur. 32 | - name: fabricfiles 33 | mountPath: /scripts 34 | subPath: scripts # script çalıştırmak için gerekli. 35 | # createGenesis.sh genesis blocku oluşturur.system-genesis-block içine 36 | # createChannel channel tranasctionu oluşturur.channel-artifacts içinde 37 | # createChannel 3 org içinde anco pper oluşturur. 38 | restartPolicy: Never 39 | volumes: 40 | - name: fabricfiles 41 | persistentVolumeClaim: 42 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/job/create-certs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: create-certs 5 | spec: 6 | backoffLimit: 1 7 | parallelism: 1 # maksiumum çalıştırılacak pod 8 | completions: 1 9 | template: 10 | metadata: 11 | name: create-certs 12 | spec: 13 | containers: 14 | - name: create-certs 15 | image: hyperledger/fabric-ca-tools:1.2.1 16 | command: 17 | - /bin/sh 18 | - -c 19 | - | 20 | ./scripts/orderer-certs.sh && 21 | ./scripts/org1-certs.sh && 22 | ./scripts/org2-certs.sh && 23 | ./scripts/org3-certs.sh 24 | resources: 25 | requests: 26 | memory: "300Mi" 27 | cpu: "300m" 28 | limits: 29 | memory: "500Mi" 30 | cpu: "350m" 31 | volumeMounts: 32 | - name: fabricfiles 33 | mountPath: /organizations # root dizinde bu pathe mount eder. 34 | subPath: organizations # nfs dir pathi 35 | - name: fabricfiles 36 | mountPath: /scripts 37 | subPath: scripts # nfs dir pathi 38 | restartPolicy: Never 39 | volumes: 40 | - name: fabricfiles 41 | persistentVolumeClaim: 42 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/job/create-connection-profile.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: create-connection-profile 5 | spec: 6 | backoffLimit: 1 7 | parallelism: 1 # maksiumum çalıştırılacak pod 8 | completions: 1 9 | template: 10 | spec: 11 | containers: 12 | - name: create-connection-profile 13 | image: hyperledger/fabric-tools:2.3 14 | workingDir: / 15 | command: 16 | - /bin/bash 17 | - -c 18 | - | 19 | ./scripts/ccp.sh && 20 | cp ./organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/* ./organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk 21 | volumeMounts: 22 | - name: fabricfiles 23 | mountPath: /organizations # root dizinde bu pathe mount eder. 24 | subPath: organizations # nfs dir pathi 25 | - name: fabricfiles 26 | mountPath: /scripts 27 | subPath: scripts # nfs dir pathi 28 | - name: fabricfiles 29 | mountPath: /connection-profile 30 | subPath: connection-profile 31 | restartPolicy: Never 32 | volumes: 33 | - name: fabricfiles 34 | persistentVolumeClaim: 35 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/job/package-chaincode.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: package-chaincode 5 | spec: 6 | backoffLimit: 1 7 | template: 8 | spec: 9 | containers: 10 | - name: package-chaincode 11 | image: busybox:1.34.0 12 | command: 13 | - /bin/sh 14 | - -c 15 | - | 16 | ./scripts/packageChaincode.sh --cc_name=${CHAINCODE_NAME} --cc_org1=${CC_ORG1} --cc_org2=${CC_ORG2} --cc_org3=${CC_ORG3} 17 | env: 18 | - name: CHAINCODE_NAME 19 | value: basic 20 | - name: CC_ORG1 21 | value: basic-org1:7052 22 | - name: CC_ORG2 23 | value: basic-org2:7052 24 | - name: CC_ORG3 25 | value: basic-org3:7052 26 | volumeMounts: 27 | - name: fabricfiles 28 | mountPath: /chaincode 29 | subPath: chaincode # channel transaction tutulur. 30 | - name: fabricfiles 31 | mountPath: /scripts 32 | subPath: scripts 33 | restartPolicy: Never 34 | volumes: 35 | - name: fabricfiles 36 | persistentVolumeClaim: 37 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/kafka/kafka-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: kafka 5 | labels: 6 | app: kafka 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: kafka 11 | ports: 12 | - name: "broker" 13 | targetPort: 9092 # container metric portu 14 | port: 9092 15 | 16 | --- 17 | #---------------- Kafka Headless Service --------------- 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: broker 22 | spec: 23 | type: ClusterIP 24 | clusterIP: None 25 | selector: 26 | app: kafka 27 | ports: 28 | - name: "broker" 29 | targetPort: 9092 # container metric portu 30 | port: 9092 -------------------------------------------------------------------------------- /deploy/k8s/kafka/kafka.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: StatefulSet 3 | metadata: 4 | name: broker 5 | labels: 6 | app: kafka 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: kafka 11 | serviceName: broker 12 | replicas: 2 13 | template: 14 | metadata: 15 | labels: 16 | app: kafka 17 | spec: 18 | terminationGracePeriodSeconds: 10 19 | containers: 20 | - name: broker 21 | image: hyperledger/fabric-kafka:0.4.21 22 | ports: 23 | - name: broker 24 | containerPort: 9092 25 | livenessProbe: 26 | tcpSocket: 27 | port: 9092 28 | initialDelaySeconds: 10 29 | timeoutSeconds: 5 30 | failureThreshold: 3 31 | periodSeconds: 10 32 | successThreshold: 1 33 | readinessProbe: 34 | tcpSocket: 35 | port: 9092 36 | initialDelaySeconds: 5 37 | timeoutSeconds: 5 38 | failureThreshold: 6 39 | periodSeconds: 10 40 | successThreshold: 1 41 | env: 42 | - name: KAFKA_MESSAGE_MAX_BYTES 43 | value: "102760448" 44 | - name: KAFKA_REPLICA_FETCH_MAX_BYTES 45 | value: "102760448" 46 | - name: KAFKA_UNCLEAN_LEADER_ELECTION_ENABLE 47 | value: "false" 48 | - name: KAFKA_DEFAULT_REPLICATION_FACTOR 49 | value: "2" 50 | - name: KAFKA_MIN_INSYNC_REPLICAS 51 | value: "2" 52 | - name: KAFKA_ZOOKEEPER_CONNECT 53 | value: zoo-0.zoo:2181,zoo-1.zoo:2181 54 | - name: KAFKA_PORT 55 | value: "9092" 56 | - name: GODEBUG 57 | value: netdns=go 58 | - name: KAFKA_ZOOKEEPER_CONNECTION_TIMEOUT_MS 59 | value: "30000" 60 | - name: KAFKA_LOG_DIRS 61 | value: /opt/kafka/data 62 | volumeMounts: 63 | - name: kafka 64 | mountPath: /opt/kafka/data 65 | volumeClaimTemplates: 66 | - metadata: 67 | name: kafka -------------------------------------------------------------------------------- /deploy/k8s/kafka/zookeeper-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zookeeper 5 | labels: 6 | app: zookeeper 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: zookeeper 11 | ports: 12 | - name: client 13 | protocol: TCP 14 | targetPort: 2181 15 | port: 2181 16 | 17 | --- 18 | #---------------- Zookeper Headless Service --------------- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: zoo 23 | spec: 24 | type: ClusterIP 25 | clusterIP: None 26 | selector: 27 | app: zookeeper 28 | ports: 29 | - name: "peer" 30 | targetPort: 2888 # container metric portu 31 | port: 2888 32 | - name: "leader-election" 33 | targetPort: 3888 # container metric portu 34 | port: 3888 -------------------------------------------------------------------------------- /deploy/k8s/kafka/zookeeper.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: StatefulSet 3 | metadata: 4 | name: zoo 5 | labels: 6 | app: zookeeper 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: zookeeper 11 | serviceName: zoo 12 | replicas: 2 13 | template: 14 | metadata: 15 | labels: 16 | app: zookeeper 17 | spec: 18 | terminationGracePeriodSeconds: 10 19 | containers: 20 | - name: zookeeper 21 | image: hyperledger/fabric-zookeeper:0.4.21 22 | command: ["/bin/sh"] 23 | args: ["-c", "export ZOO_MY_ID=${HOSTNAME##*-}; /docker-entrypoint.sh zkServer.sh start-foreground"] 24 | resources: 25 | requests: 26 | memory: 256Mi 27 | cpu: 250m 28 | limits: 29 | memory: "400Mi" 30 | cpu: "350m" 31 | env: 32 | - name: ZOO_SERVERS 33 | value: server.0=zoo-0.zoo.default.svc.cluster.local:2888:3888 server.1=zoo-1.zoo.default.svc.cluster.local:2888:3888 34 | - name: ZOO_4LW_COMMANDS_WHITELIST 35 | value: srvr, mntr, ruok 36 | - name: ZOO_MAX_SESSION_TIMEOUT 37 | value: "40000" 38 | - name: ZOO_TICK_TIME 39 | value: "2000" 40 | ports: 41 | - name: client 42 | containerPort: 2181 43 | - name: peer 44 | containerPort: 2888 45 | - name: leader-election 46 | containerPort: 3888 47 | livenessProbe: 48 | exec: 49 | command: 50 | - /bin/sh 51 | - -c 52 | - zkServer.sh status 53 | initialDelaySeconds: 30 54 | periodSeconds: 10 55 | timeoutSeconds: 5 56 | failureThreshold: 6 57 | successThreshold: 1 58 | volumeMounts: 59 | - name: zookeeper 60 | mountPath: /data 61 | volumeClaimTemplates: 62 | - metadata: 63 | name: zookeeper 64 | -------------------------------------------------------------------------------- /deploy/k8s/monitoring/grafana-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: grafana 5 | labels: 6 | app: grafana 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: grafana 11 | ports: 12 | - protocol: TCP 13 | targetPort: 3000 14 | port: 3000 -------------------------------------------------------------------------------- /deploy/k8s/monitoring/grafana.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: grafana 5 | labels: 6 | app: grafana 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: grafana 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: grafana 16 | spec: 17 | containers: 18 | - name: grafana 19 | image: grafana/grafana:8.1.2 20 | imagePullPolicy: IfNotPresent 21 | resources: 22 | limits: 23 | memory: "128Mi" 24 | cpu: "500m" 25 | ports: 26 | - containerPort: 3000 27 | livenessProbe: 28 | httpGet: 29 | path: /api/health 30 | port: 3000 31 | initialDelaySeconds: 60 32 | timeoutSeconds: 30 33 | failureThreshold: 10 34 | readinessProbe: 35 | httpGet: 36 | path: /api/health 37 | port: 3000 38 | env: 39 | - name: GF_PATHS_PROVISIONING # provising pathi 40 | value: /var/lib/grafana/provisioning/ 41 | - name: GF_SECURITY_ADMIN_USER # admin user 42 | value: admin 43 | - name: GF_SECURITY_ADMIN_PASSWORD # admin password 44 | value: adminpw 45 | - name: GF_USERS_ALLOW_SIGN_UP # signup kapalı 46 | value: "false" 47 | volumeMounts: 48 | - name: grafana-config 49 | mountPath: /var/lib/grafana/provisioning/datasources/datasource.yml 50 | subPath: datasource.yml # prometheus ayarı için 51 | - name: grafana-config 52 | mountPath: /var/lib/grafana/provisioning/dashboards/hlf/dashboard.json 53 | subPath: dashboard.json # dashboard görseli çin 54 | - name: grafana-config 55 | mountPath: /var/lib/grafana/provisioning/dashboards/dashboard.yaml 56 | subPath: dashboard.yaml # dashboard için 57 | - name: grafana 58 | mountPath: /var/lib/grafana 59 | subPath: monitoring/grafana 60 | volumes: 61 | - name: grafana 62 | persistentVolumeClaim: 63 | claimName: fabricfiles-pvc 64 | - name: grafana-config 65 | configMap: 66 | name: grafana-config 67 | items: 68 | - key: datasource.yml 69 | path: datasource.yml 70 | - key: dashboard.json 71 | path: dashboard.json # dashbboard için gerekli. 72 | - key: dashboard.yaml 73 | path: dashboard.yaml # dashbaord dosyası pathi 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /deploy/k8s/monitoring/prometheus-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: monitoring-config 5 | labels: 6 | app: monitoring-config 7 | data: # prometheus.yml dosyası orderer,peer0-org1,peer0-org2,peer0-org3 den metrik çeker. 8 | prometheus.yml: | 9 | global: 10 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 11 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 12 | 13 | alerting: 14 | alertmanagers: 15 | - static_configs: 16 | - targets: 17 | # - alertmanager:9093 18 | 19 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 20 | rule_files: 21 | # - "first_rules.yml" 22 | # - "second_rules.yml" 23 | 24 | # A scrape configuration containing exactly one endpoint to scrape: 25 | # Here it's Prometheus itself. 26 | scrape_configs: 27 | # The job name is added as a label `job=` to any timeseries scraped from this config. 28 | - job_name: "prometheus" 29 | static_configs: 30 | - targets: ["localhost:9090"] 31 | - job_name: "orderer" 32 | static_configs: 33 | - targets: ["orderer-metrics:9444"] 34 | - job_name: "orderer2" 35 | static_configs: 36 | - targets: ["orderer2-metrics:9444"] 37 | - job_name: "orderer3" 38 | static_configs: 39 | - targets: ["orderer3-metrics:9444"] 40 | - job_name: "orderer4" 41 | static_configs: 42 | - targets: ["orderer4-metrics:9444"] 43 | - job_name: "orderer5" 44 | static_configs: 45 | - targets: ["orderer5-metrics:9444"] 46 | - job_name: "peer0_org1" 47 | static_configs: 48 | - targets: ["peer0-org1-metrics:9443"] 49 | - job_name: "peer0_org2" 50 | static_configs: 51 | - targets: ["peer0-org2-metrics:9443"] 52 | - job_name: "peer0_org3" 53 | static_configs: 54 | - targets: ["peer0-org3-metrics:9443"] 55 | -------------------------------------------------------------------------------- /deploy/k8s/monitoring/prometheus-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: prometheus 5 | labels: 6 | app: prometheus 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: prometheus 11 | ports: 12 | - protocol: TCP 13 | targetPort: 9090 14 | port: 9090 -------------------------------------------------------------------------------- /deploy/k8s/monitoring/prometheus.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: prometheus 5 | labels: 6 | app: prometheus 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: prometheus 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: prometheus 16 | spec: 17 | containers: 18 | - name: prometheus 19 | image: prom/prometheus:v2.29.2 20 | imagePullPolicy: IfNotPresent 21 | resources: 22 | limits: 23 | memory: "128Mi" 24 | cpu: "300m" 25 | ports: 26 | - containerPort: 9090 27 | livenessProbe: 28 | httpGet: 29 | path: /-/healthy 30 | port: 9090 31 | initialDelaySeconds: 30 32 | periodSeconds: 15 33 | timeoutSeconds: 10 34 | failureThreshold: 3 35 | successThreshold: 1 36 | readinessProbe: 37 | httpGet: 38 | path: /-/ready 39 | port: 9090 40 | initialDelaySeconds: 30 41 | periodSeconds: 5 42 | timeoutSeconds: 4 43 | failureThreshold: 3 44 | successThreshold: 1 45 | volumeMounts: 46 | - name: prometheus 47 | mountPath: /prometheus 48 | subPath: monitoring/prometheus 49 | - name: prometheus-config 50 | mountPath: /etc/prometheus/prometheus.yml 51 | subPath: prometheus.yml # prometheus dosyası pathi verildi. 52 | volumes: 53 | - name: prometheus 54 | persistentVolumeClaim: 55 | claimName: fabricfiles-pvc 56 | - name: prometheus-config 57 | configMap: 58 | name: monitoring-config 59 | items: 60 | - key: prometheus.yml 61 | path: prometheus.yml -------------------------------------------------------------------------------- /deploy/k8s/orderer/order-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: orderer 5 | labels: 6 | app: orderer 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: orderer # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7050 # contanier portu 15 | port: 7050 # service portu 16 | 17 | --- 18 | #---------------- Orderer1 Metrics Service --------------- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: orderer-metrics 23 | labels: 24 | app: orderer 25 | metrics-service: "true" 26 | spec: 27 | type: ClusterIP 28 | selector: 29 | app: orderer 30 | ports: 31 | - name: "orderer-metrics" 32 | targetPort: 9444 # container metric portu 33 | port: 9444 -------------------------------------------------------------------------------- /deploy/k8s/orderer/order2-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: orderer2 5 | labels: 6 | app: orderer2 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: orderer2 # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7050 # contanier portu 15 | port: 7050 # service portu 16 | --- 17 | #---------------- Orderer2 Metrics Service --------------- 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: orderer2-metrics 22 | labels: 23 | app: orderer2 24 | metrics-service: "true" 25 | spec: 26 | type: ClusterIP 27 | selector: 28 | app: orderer2 29 | ports: 30 | - name: "orderer2-metrics" 31 | targetPort: 9444 # container metric portu 32 | port: 9444 -------------------------------------------------------------------------------- /deploy/k8s/orderer/order3-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: orderer3 5 | labels: 6 | app: orderer3 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: orderer3 # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7050 # contanier portu 15 | port: 7050 # service portu 16 | 17 | --- 18 | #---------------- Orderer3 Metrics Service --------------- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: orderer3-metrics 23 | labels: 24 | app: orderer3 25 | metrics-service: "true" 26 | spec: 27 | type: ClusterIP 28 | selector: 29 | app: orderer3 30 | ports: 31 | - name: "orderer3-metrics" 32 | targetPort: 9444 # container metric portu 33 | port: 9444 -------------------------------------------------------------------------------- /deploy/k8s/orderer/order4-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: orderer4 5 | labels: 6 | app: orderer4 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: orderer4 # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7050 # contanier portu 15 | port: 7050 # service portu 16 | 17 | --- 18 | #---------------- Orderer4 Metrics Service --------------- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: orderer4-metrics 23 | labels: 24 | app: orderer4 25 | metrics-service: "true" 26 | spec: 27 | type: ClusterIP 28 | selector: 29 | app: orderer4 30 | ports: 31 | - name: "orderer4-metrics" 32 | targetPort: 9444 # container metric portu 33 | port: 9444 -------------------------------------------------------------------------------- /deploy/k8s/orderer/order5-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: orderer5 5 | labels: 6 | app: orderer5 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: orderer5 # deploymenti bu selector üzerinden bulur.deploymentdeki matchLabels ile aynı olmalı. 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7050 # contanier portu 15 | port: 7050 # service portu 16 | 17 | --- 18 | #---------------- Orderer5 Metrics Service --------------- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: orderer5-metrics 23 | labels: 24 | app: orderer5 25 | metrics-service: "true" 26 | spec: 27 | type: ClusterIP 28 | selector: 29 | app: orderer5 30 | ports: 31 | - name: "orderer5-metrics" 32 | targetPort: 9444 # container metric portu 33 | port: 9444 -------------------------------------------------------------------------------- /deploy/k8s/peer/org1/peer0Org1-cli.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: cli-peer0-org1 5 | labels: 6 | app: cli-peer0-org1 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: cli-peer0-org1 11 | template: 12 | metadata: 13 | labels: 14 | app: cli-peer0-org1 15 | spec: 16 | containers: 17 | - name: cli-peer0-org1 18 | image: hyperledger/fabric-tools:2.3 19 | workingDir: / 20 | stdin: true 21 | tty: true 22 | resources: 23 | requests: 24 | memory: "200Mi" 25 | cpu: "90m" 26 | limits: 27 | memory: "300Mi" 28 | cpu: "200m" 29 | env: 30 | - name: ORDERER_CA # orderer ca konfigurasyonu 31 | value: /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 32 | - name: CORE_PEER_ADDRESS # peer adresi 33 | value: peer0-org1:7051 34 | - name: CORE_PEER_ID 35 | value: cli.peer0.org1.example.com 36 | - name: CORE_PEER_LOCALMSPID 37 | value: Org1MSP 38 | - name: CORE_PEER_MSPCONFIGPATH 39 | value: /organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 40 | - name: CORE_PEER_TLS_CERT_FILE 41 | value: /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt 42 | - name: CORE_PEER_TLS_ENABLED 43 | value: "true" 44 | - name: CORE_PEER_TLS_KEY_FILE 45 | value: /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key 46 | - name: CORE_PEER_TLS_ROOTCERT_FILE 47 | value: /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 48 | - name: FABRIC_LOGGING_SPEC 49 | value: ERROR 50 | - name: GOPATH 51 | value: /opt/gopath 52 | - name: SYS_CHANNEL 53 | value: system-channel 54 | - name: CORE_CHAINCODE_BUILDER 55 | value: hyperledger/fabric-ccenv:1.4.8 56 | volumeMounts: 57 | - name: fabricfiles 58 | mountPath: /organizations 59 | subPath: organizations # sertifikalara erişmek için 60 | - name: fabricfiles 61 | mountPath: /configtx 62 | subPath: configtx # configtx.yaml dosyası için. 63 | - name: fabricfiles 64 | mountPath: /channel-artifacts 65 | subPath: channel-artifacts # channel artifact dir 66 | - name: fabricfiles 67 | mountPath: /scripts 68 | subPath: scripts 69 | - name: fabricfiles 70 | mountPath: /opt/gopath/src/github.com/chaincode 71 | subPath: chaincode # chanicode dir 72 | volumes: 73 | - name: fabricfiles 74 | persistentVolumeClaim: 75 | claimName: fabricfiles-pvc 76 | -------------------------------------------------------------------------------- /deploy/k8s/peer/org1/peer0Org1-couchdb-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: peer0-org1-couchdb 5 | labels: 6 | app: peer0-org1-couchdb 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: peer0-org1-couchdb 11 | ports: 12 | - name: couchdb 13 | protocol: TCP 14 | targetPort: 5984 15 | port: 5984 -------------------------------------------------------------------------------- /deploy/k8s/peer/org1/peer0Org1-couchdb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: peer0-org1-couchdb 5 | labels: 6 | app: peer0-org1-couchdb 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: peer0-org1-couchdb 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: peer0-org1-couchdb 16 | spec: 17 | containers: 18 | - name: couchdb 19 | image: hyperledger/fabric-couchdb:0.4.15 20 | resources: 21 | requests: 22 | memory: "200Mi" 23 | cpu: "200m" 24 | limits: 25 | memory: "300Mi" 26 | cpu: "300m" 27 | ports: 28 | - containerPort: 5984 29 | livenessProbe: 30 | tcpSocket: 31 | port: 5984 32 | initialDelaySeconds: 60 33 | timeoutSeconds: 5 34 | failureThreshold: 6 35 | readinessProbe: 36 | tcpSocket: 37 | port: 5984 38 | initialDelaySeconds: 5 39 | timeoutSeconds: 3 40 | periodSeconds: 5 41 | env: 42 | - name: COUCHDB_USER 43 | value: admin 44 | - name: COUCHDB_PASSWORD 45 | value: adminpw 46 | volumeMounts: 47 | - name: fabricfiles 48 | mountPath: /opt/couchdb/data 49 | subPath: state/org1/peer0-couchdb # couchdb datası 50 | volumes: 51 | - name: fabricfiles 52 | persistentVolumeClaim: 53 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/peer/org1/peer0Org1-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: peer0-org1 5 | labels: 6 | app: peer0-org1 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: peer0-org1 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7051 15 | port: 7051 16 | - name: event 17 | protocol: TCP 18 | targetPort: 7061 19 | port: 7061 20 | --- 21 | #---------------- Peer0 Org1 Metrics Service --------------- 22 | apiVersion: v1 23 | kind: Service 24 | metadata: 25 | name: peer0-org1-metrics 26 | labels: 27 | app: peer0-org1 28 | metrics-service: "true" 29 | spec: 30 | type: ClusterIP 31 | selector: 32 | app: peer0-org1 33 | ports: 34 | - name: "peer-metrics" 35 | targetPort: 9443 # container metric portu 36 | port: 9443 -------------------------------------------------------------------------------- /deploy/k8s/peer/org2/peer0Org2-cli.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: cli-peer0-org2 5 | labels: 6 | app: cli-peer0-org2 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: cli-peer0-org2 11 | template: 12 | metadata: 13 | labels: 14 | app: cli-peer0-org2 15 | spec: 16 | containers: 17 | - name: cli-peer0-org2 18 | image: hyperledger/fabric-tools:2.3 19 | workingDir: / 20 | stdin: true 21 | tty: true 22 | resources: 23 | requests: 24 | memory: "200Mi" 25 | cpu: "90m" 26 | limits: 27 | memory: "300Mi" 28 | cpu: "200m" 29 | env: 30 | - name: ORDERER_CA # orderer ca konfigurasyonu 31 | value: /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 32 | - name: CORE_PEER_ADDRESS # peer adresi 33 | value: peer0-org2:7051 34 | - name: CORE_PEER_ID 35 | value: cli.peer0.org2.example.com 36 | - name: CORE_PEER_LOCALMSPID 37 | value: Org2MSP 38 | - name: CORE_PEER_MSPCONFIGPATH 39 | value: /organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 40 | - name: CORE_PEER_TLS_CERT_FILE 41 | value: /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt 42 | - name: CORE_PEER_TLS_ENABLED 43 | value: "true" 44 | - name: CORE_PEER_TLS_KEY_FILE 45 | value: /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key 46 | - name: CORE_PEER_TLS_ROOTCERT_FILE 47 | value: /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 48 | - name: FABRIC_LOGGING_SPEC 49 | value: ERROR 50 | - name: GOPATH 51 | value: /opt/gopath 52 | - name: SYS_CHANNEL 53 | value: system-channel 54 | volumeMounts: 55 | - name: fabricfiles 56 | mountPath: /organizations 57 | subPath: organizations # sertifikalara erişmek için 58 | - name: fabricfiles 59 | mountPath: /configtx 60 | subPath: configtx # configtx.yaml dosyası için. 61 | - name: fabricfiles 62 | mountPath: /channel-artifacts 63 | subPath: channel-artifacts # channel artifact dir 64 | - name: fabricfiles 65 | mountPath: /scripts 66 | subPath: scripts 67 | - name: fabricfiles 68 | mountPath: /opt/gopath/src/github.com/chaincode 69 | subPath: chaincode # chanicode dir 70 | volumes: 71 | - name: fabricfiles 72 | persistentVolumeClaim: 73 | claimName: fabricfiles-pvc 74 | -------------------------------------------------------------------------------- /deploy/k8s/peer/org2/peer0Org2-couchdb-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: peer0-org2-couchdb 5 | labels: 6 | app: peer0-org2-couchdb 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: peer0-org2-couchdb 11 | ports: 12 | - name: couchdb 13 | protocol: TCP 14 | targetPort: 5984 15 | port: 5984 -------------------------------------------------------------------------------- /deploy/k8s/peer/org2/peer0Org2-couchdb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: peer0-org2-couchdb 5 | labels: 6 | app: peer0-org2-couchdb 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: peer0-org2-couchdb 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: peer0-org2-couchdb 16 | spec: 17 | containers: 18 | - name: couchdb 19 | image: hyperledger/fabric-couchdb:0.4.15 20 | resources: 21 | requests: 22 | memory: "200Mi" 23 | cpu: "200m" 24 | limits: 25 | memory: "300Mi" 26 | cpu: "300m" 27 | ports: 28 | - containerPort: 5984 29 | livenessProbe: 30 | tcpSocket: 31 | port: 5984 32 | initialDelaySeconds: 60 33 | timeoutSeconds: 5 34 | failureThreshold: 6 35 | readinessProbe: 36 | tcpSocket: 37 | port: 5984 38 | initialDelaySeconds: 5 39 | timeoutSeconds: 3 40 | periodSeconds: 5 41 | env: 42 | - name: COUCHDB_USER 43 | value: admin 44 | - name: COUCHDB_PASSWORD 45 | value: adminpw 46 | volumeMounts: 47 | - name: fabricfiles 48 | mountPath: /opt/couchdb/data 49 | subPath: state/org2/peer0-couchdb # couchdb datası 50 | volumes: 51 | - name: fabricfiles 52 | persistentVolumeClaim: 53 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/peer/org2/peer0Org2-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: peer0-org2 5 | labels: 6 | app: peer0-org2 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: peer0-org2 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7051 15 | port: 7051 16 | - name: event 17 | protocol: TCP 18 | targetPort: 7061 19 | port: 7061 20 | --- 21 | #---------------- Peer0 org2 Metrics Service --------------- 22 | apiVersion: v1 23 | kind: Service 24 | metadata: 25 | name: peer0-org2-metrics 26 | labels: 27 | app: peer0-org2 28 | metrics-service: "true" 29 | spec: 30 | type: ClusterIP 31 | selector: 32 | app: peer0-org2 33 | ports: 34 | - name: "peer-metrics" 35 | targetPort: 9443 # container metric portu 36 | port: 9443 -------------------------------------------------------------------------------- /deploy/k8s/peer/org3/peer0Org3-cli.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: cli-peer0-org3 5 | labels: 6 | app: cli-peer0-org3 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: cli-peer0-org3 11 | template: 12 | metadata: 13 | labels: 14 | app: cli-peer0-org3 15 | spec: 16 | containers: 17 | - name: cli-peer0-org3 18 | image: hyperledger/fabric-tools:2.3 19 | workingDir: / 20 | stdin: true 21 | tty: true 22 | resources: 23 | requests: 24 | memory: "200Mi" 25 | cpu: "90m" 26 | limits: 27 | memory: "300Mi" 28 | cpu: "200m" 29 | env: 30 | - name: ORDERER_CA # orderer ca konfigurasyonu 31 | value: /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 32 | - name: CORE_PEER_ADDRESS # peer adresi 33 | value: peer0-org3:7051 34 | - name: CORE_PEER_ID 35 | value: cli.peer0.org3.example.com 36 | - name: CORE_PEER_LOCALMSPID 37 | value: Org3MSP 38 | - name: CORE_PEER_MSPCONFIGPATH 39 | value: /organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 40 | - name: CORE_PEER_TLS_CERT_FILE 41 | value: /organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.crt 42 | - name: CORE_PEER_TLS_ENABLED 43 | value: "true" 44 | - name: CORE_PEER_TLS_KEY_FILE 45 | value: /organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.key 46 | - name: CORE_PEER_TLS_ROOTCERT_FILE 47 | value: /organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 48 | - name: FABRIC_LOGGING_SPEC 49 | value: ERROR 50 | - name: GOPATH 51 | value: /opt/gopath 52 | - name: SYS_CHANNEL 53 | value: system-channel 54 | - name: CORE_CHAINCODE_BUILDER 55 | value: hyperledger/fabric-ccenv:1.4.8 56 | volumeMounts: 57 | - name: fabricfiles 58 | mountPath: /organizations 59 | subPath: organizations # sertifikalara erişmek için 60 | - name: fabricfiles 61 | mountPath: /configtx 62 | subPath: configtx # configtx.yaml dosyası için. 63 | - name: fabricfiles 64 | mountPath: /channel-artifacts 65 | subPath: channel-artifacts # channel artifact dir 66 | - name: fabricfiles 67 | mountPath: /scripts 68 | subPath: scripts 69 | - name: fabricfiles 70 | mountPath: /opt/gopath/src/github.com/chaincode 71 | subPath: chaincode # chanicode dir 72 | volumes: 73 | - name: fabricfiles 74 | persistentVolumeClaim: 75 | claimName: fabricfiles-pvc 76 | -------------------------------------------------------------------------------- /deploy/k8s/peer/org3/peer0Org3-couchdb-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: peer0-org3-couchdb 5 | labels: 6 | app: peer0-org3-couchdb 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: peer0-org3-couchdb 11 | ports: 12 | - name: couchdb 13 | protocol: TCP 14 | targetPort: 5984 15 | port: 5984 -------------------------------------------------------------------------------- /deploy/k8s/peer/org3/peer0Org3-couchdb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: peer0-org3-couchdb 5 | labels: 6 | app: peer0-org3-couchdb 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: peer0-org3-couchdb 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: peer0-org3-couchdb 16 | spec: 17 | containers: 18 | - name: couchdb 19 | image: hyperledger/fabric-couchdb:0.4.15 20 | resources: 21 | requests: 22 | memory: "200Mi" 23 | cpu: "200m" 24 | limits: 25 | memory: "300Mi" 26 | cpu: "300m" 27 | ports: 28 | - containerPort: 5984 29 | livenessProbe: 30 | tcpSocket: 31 | port: 5984 32 | initialDelaySeconds: 60 33 | timeoutSeconds: 5 34 | failureThreshold: 6 35 | readinessProbe: 36 | tcpSocket: 37 | port: 5984 38 | initialDelaySeconds: 5 39 | timeoutSeconds: 3 40 | periodSeconds: 5 41 | env: 42 | - name: COUCHDB_USER 43 | value: admin 44 | - name: COUCHDB_PASSWORD 45 | value: adminpw 46 | volumeMounts: 47 | - name: fabricfiles 48 | mountPath: /opt/couchdb/data 49 | subPath: state/org3/peer0-couchdb # couchdb datası 50 | volumes: 51 | - name: fabricfiles 52 | persistentVolumeClaim: 53 | claimName: fabricfiles-pvc -------------------------------------------------------------------------------- /deploy/k8s/peer/org3/peer0Org3-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: peer0-org3 5 | labels: 6 | app: peer0-org3 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: peer0-org3 11 | ports: 12 | - name: grpc 13 | protocol: TCP 14 | targetPort: 7051 15 | port: 7051 16 | - name: event 17 | protocol: TCP 18 | targetPort: 7061 19 | port: 7061 20 | --- 21 | #---------------- Peer0 org3 Metrics Service --------------- 22 | apiVersion: v1 23 | kind: Service 24 | metadata: 25 | name: peer0-org3-metrics 26 | labels: 27 | app: peer0-org3 28 | metrics-service: "true" 29 | spec: 30 | type: ClusterIP 31 | selector: 32 | app: peer0-org3 33 | ports: 34 | - name: "peer-metrics" 35 | targetPort: 9443 # container metric portu 36 | port: 9443 -------------------------------------------------------------------------------- /deploy/k8s/pv/fabricfiles-pv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: fabricfiles-pv 5 | labels: 6 | name: fabricfiles 7 | spec: 8 | storageClassName: default 9 | capacity: 10 | storage: 5Gi 11 | volumeMode: Filesystem 12 | accessModes: 13 | - ReadWriteOnce 14 | nfs: 15 | path: /srv/kubedata/fabricfiles 16 | server: 192.168.12.9 -------------------------------------------------------------------------------- /deploy/k8s/pv/kafka-pv.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolume 4 | metadata: 5 | name: kafka0-pv 6 | labels: 7 | app: kafka 8 | podindex: "0" 9 | spec: 10 | storageClassName: default 11 | capacity: 12 | storage: 1Gi 13 | volumeMode: Filesystem 14 | accessModes: 15 | - ReadWriteOnce 16 | nfs: 17 | path: /srv/kubedata/fabricfiles/broker/kafka0 18 | server: 192.168.12.9 19 | 20 | --- 21 | apiVersion: v1 22 | kind: PersistentVolume 23 | metadata: 24 | name: kafka1-pv 25 | labels: 26 | app: kafka 27 | podindex: "1" 28 | spec: 29 | storageClassName: default 30 | volumeMode: Filesystem 31 | capacity: 32 | storage: 1Gi 33 | accessModes: 34 | - ReadWriteOnce 35 | nfs: 36 | path: /srv/kubedata/fabricfiles/broker/kafka1 37 | server: 192.168.12.9 -------------------------------------------------------------------------------- /deploy/k8s/pv/zookeeper-pv.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolume 4 | metadata: 5 | name: zookeeper0-pv 6 | labels: 7 | app: zookeeper 8 | podindex: "0" 9 | spec: 10 | storageClassName: default 11 | capacity: 12 | storage: 1Gi 13 | volumeMode: Filesystem 14 | accessModes: 15 | - ReadWriteOnce 16 | nfs: 17 | path: /srv/kubedata/fabricfiles/broker/zookeeper0 18 | server: 192.168.12.9 19 | 20 | --- 21 | apiVersion: v1 22 | kind: PersistentVolume 23 | metadata: 24 | name: zookeeper1-pv 25 | labels: 26 | app: zookeeper 27 | podindex: "1" 28 | spec: 29 | storageClassName: default 30 | volumeMode: Filesystem 31 | capacity: 32 | storage: 1Gi 33 | accessModes: 34 | - ReadWriteOnce 35 | nfs: 36 | path: /srv/kubedata/fabricfiles/broker/zookeeper1 37 | server: 192.168.12.9 -------------------------------------------------------------------------------- /deploy/k8s/pvc/fabricfiles-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: fabricfiles-pvc 5 | spec: 6 | storageClassName: default 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 4050Mi 12 | selector: 13 | matchLabels: 14 | name: fabricfiles -------------------------------------------------------------------------------- /deploy/k8s/pvc/kafka-pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: kafka-broker-0 6 | spec: 7 | storageClassName: default 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 1Gi 13 | selector: 14 | matchLabels: 15 | app: kafka 16 | podindex: "0" 17 | 18 | --- 19 | kind: PersistentVolumeClaim 20 | apiVersion: v1 21 | metadata: 22 | name: kafka-broker-1 23 | spec: 24 | storageClassName: default 25 | accessModes: 26 | - ReadWriteOnce 27 | resources: 28 | requests: 29 | storage: 1Gi 30 | selector: 31 | matchLabels: 32 | app: kafka 33 | podindex: "1" -------------------------------------------------------------------------------- /deploy/k8s/pvc/zookeeper-pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: zookeeper-zoo-0 6 | spec: 7 | storageClassName: default 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 1Gi 13 | selector: 14 | matchLabels: 15 | app: zookeeper 16 | podindex: "0" 17 | 18 | --- 19 | kind: PersistentVolumeClaim 20 | apiVersion: v1 21 | metadata: 22 | name: zookeeper-zoo-1 23 | spec: 24 | storageClassName: default 25 | accessModes: 26 | - ReadWriteOnce 27 | resources: 28 | requests: 29 | storage: 1Gi 30 | selector: 31 | matchLabels: 32 | app: zookeeper 33 | podindex: "1" -------------------------------------------------------------------------------- /deploy/k8s/ui/frontend-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: frontend 5 | labels: 6 | app: frontend 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: frontend 11 | ports: 12 | - name: frontend 13 | protocol: TCP 14 | targetPort: 80 15 | port: 80 16 | -------------------------------------------------------------------------------- /deploy/k8s/ui/frontend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: frontend 5 | labels: 6 | app: frontend 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: frontend 11 | template: 12 | metadata: 13 | labels: 14 | app: frontend 15 | spec: 16 | containers: 17 | - name: frontend 18 | image: suayb/hlf-frontend:1.0.0 19 | imagePullPolicy: Always 20 | resources: 21 | requests: 22 | memory: "250Mi" 23 | cpu: "200m" 24 | limits: 25 | memory: "350Mi" 26 | cpu: "300m" 27 | ports: 28 | - containerPort: 80 29 | -------------------------------------------------------------------------------- /deploy/k8s/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Functions ######################################################################### 5 | 6 | 7 | function uninstall(){ 8 | echo "## Uninstalled app" 9 | kubectl delete -f explorer/ 10 | kubectl delete -f ui/ 11 | kubectl delete -f api/ 12 | kubectl delete -f job 13 | kubectl delete -f cc/ 14 | kubectl delete -f peer/org3/ 15 | kubectl delete -f peer/org2/ 16 | kubectl delete -f peer/org1/ 17 | kubectl delete -f peer/ 18 | kubectl delete -f orderer/ 19 | kubectl delete -f ca/ 20 | kubectl delete -f kafka/ 21 | } 22 | 23 | # Let's go ################################################################################### 24 | uninstall -------------------------------------------------------------------------------- /deploy/setup/haproxy-setup/install_haproxy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Variables ######################################## 4 | 5 | # Functions ######################################## 6 | install_haproxy(){ 7 | echo 8 | echo "0.1 HAPROXY - install" 9 | sudo apt install -y -qq haproxy 2>&1 >/dev/null 10 | } 11 | 12 | set_haproxy(){ 13 | 14 | echo 15 | echo "0.2 HAPROXY - configuration" 16 | echo " 17 | global 18 | log 127.0.0.1 local2 19 | chroot /var/lib/haproxy 20 | pidfile /var/run/haproxy.pid 21 | maxconn 4000 22 | user haproxy 23 | group haproxy 24 | daemon 25 | stats socket /var/lib/haproxy/stats 26 | defaults 27 | mode http 28 | log global 29 | option httplog 30 | option dontlognull 31 | option http-server-close 32 | option forwardfor except 127.0.0.0/8 33 | option redispatch 34 | retries 3 35 | timeout http-request 10s 36 | timeout queue 1m 37 | timeout connect 10s 38 | timeout client 1m 39 | timeout server 1m 40 | timeout http-keep-alive 10s 41 | timeout check 10s 42 | maxconn 3000 43 | listen stats 44 | bind *:9000 45 | stats enable 46 | stats uri /stats 47 | stats refresh 2s 48 | stats auth vagrant:vagrant 49 | listen kubernetes-apiserver-https 50 | bind *:6443 51 | mode tcp 52 | option log-health-checks 53 | timeout client 3h 54 | timeout server 3h">>/etc/haproxy/haproxy.cfg 55 | for srv in $(cat /etc/hosts | grep k8sm | grep -v 127.0 | awk '{print $2}');do echo " server "$srv" "$srv":6443 check check-ssl verify none inter 10000">>/etc/haproxy/haproxy.cfg 56 | done 57 | echo " balance roundrobin 58 | listen kubernetes-ingress 59 | bind *:80 60 | mode tcp 61 | option log-health-checks">>/etc/haproxy/haproxy.cfg 62 | 63 | for srv in $(cat /etc/hosts | grep k8sn | grep -v 127.0 | awk '{print $2}');do echo " server "$srv" "$srv":80 check">>/etc/haproxy/haproxy.cfg 64 | done 65 | 66 | check_nodes=`cat /etc/hosts | grep k8sn | grep -v 127.0` 67 | if [ -z "$check_nodes" ] 68 | then 69 | sudo cat /etc/hosts | grep k8sm | grep -v 127.0 | awk '{print " server "$2 " "$2":80 check"}'>>/etc/haproxy/haproxy.cfg 70 | fi 71 | } 72 | 73 | reload_haproxy(){ 74 | echo 75 | echo "0.3 HAPROXY - restart" 76 | systemctl reload haproxy 77 | } 78 | 79 | # Let's Go!! ######################################## 80 | install_haproxy 81 | set_haproxy 82 | reload_haproxy 83 | -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install-prereqs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Variables ######################################## 4 | 5 | KUBERNETES_DASHBOARD_ENABLED=false 6 | CERT_MANAGER_ENABLED=true 7 | JENKINS_ENABLED=false 8 | SONARQUBE_ENABLED=false 9 | ISTIO_ENABLED=false 10 | RANCHER_ENABLED=false 11 | 12 | # DO NOT Execute this script with sudo 13 | if [ $SUDO_USER ]; then 14 | echo "Please DO NOT execute with sudo !!! ./install-prereqs.sh" 15 | echo "Aborting!!!" 16 | exit 0 17 | fi 18 | ./install_k8s_prereqs.sh 19 | ./install_kubespray.sh 20 | ./install_nfs_provisioner.sh 21 | if [ "$KUBERNETES_DASHBOARD_ENABLED" == true ] 22 | then 23 | echo 24 | echo "## Kubernetes Dashboard" 25 | ./install_k8s_dashboard.sh 26 | fi 27 | if [ "$CERT_MANAGER_ENABLED" == true ] 28 | then 29 | echo 30 | echo "## Cert Manager" 31 | ./install_cert_manager.sh 32 | fi 33 | if [ "$ISTIO_ENABLED" == true ] 34 | then 35 | echo 36 | echo "## Istio" 37 | ./install_istio.sh 38 | fi 39 | if [ "$JENKINS_ENABLED" == true ] 40 | then 41 | echo 42 | echo "## Jenkins" 43 | ./install_jenkins.sh 44 | fi 45 | if [ "$SONARQUBE_ENABLED" == true ] 46 | then 47 | echo 48 | echo "## Sonarqube" 49 | ./install_sonarqube.sh 50 | fi 51 | if [ "$RANCHER_ENABLED" == true ] 52 | then 53 | echo 54 | echo "## Rancher" 55 | ./install_rancher.sh 56 | fi 57 | 58 | echo "====== Please Logout & Logback in ======" -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install_cert_manager.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_NAME=cert-manager 4 | NAMESPACE=cert-manager 5 | CHART_VERSION=v1.4.0 6 | LETSENCRYPT_EMAIL=suaybsimsek58@gmail.com 7 | HTTP01_INGRESS_CLASS=nginx 8 | 9 | # Functions ######################################################################### 10 | 11 | prepare_cert_manager(){ 12 | sudo mkdir $HOME/cert_manager 13 | sudo chown ${USER} -R $HOME/cert_manager 14 | kubectl create ns ${NAMESPACE} 15 | } 16 | 17 | disable_resource_validation(){ 18 | kubectl label namespace ${NAMESPACE} certmanager.k8s.io/disable-validation=true 19 | } 20 | 21 | add_helm_repo(){ 22 | helm repo add jetstack https://charts.jetstack.io 23 | } 24 | 25 | create_custom_values(){ 26 | 27 | echo "Custom Values" 28 | echo " 29 | replicaCount: 1 30 | installCRDs: true 31 | "> $HOME/cert_manager/values.production.yaml 32 | } 33 | 34 | install_letsencrypt_issuer(){ 35 | echo "Cluster Issuer" 36 | echo " 37 | apiVersion: cert-manager.io/v1 38 | kind: ClusterIssuer 39 | metadata: 40 | name: letsencrypt-prod 41 | spec: 42 | acme: 43 | email: ${LETSENCRYPT_EMAIL} 44 | server: https://acme-staging-v02.api.letsencrypt.org/directory 45 | privateKeySecretRef: 46 | name: letsencrypt-prod 47 | solvers: 48 | - http01: 49 | ingress: 50 | class: ${HTTP01_INGRESS_CLASS} 51 | "> $HOME/cert_manager/cluster-issuer-prod.yaml 52 | 53 | sleep 20 54 | kubectl apply -f $HOME/cert_manager/cluster-issuer-prod.yaml 55 | } 56 | 57 | install_cert_manager(){ 58 | helm install ${RELEASE_NAME} --wait --timeout 60s --namespace ${NAMESPACE} --version ${CHART_VERSION} jetstack/cert-manager -f $HOME/cert_manager/values.production.yaml 59 | } 60 | 61 | 62 | # Let's go ################################################################################### 63 | prepare_cert_manager 64 | disable_resource_validation 65 | add_helm_repo 66 | create_custom_values 67 | install_cert_manager 68 | install_letsencrypt_issuer -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install_istio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=1.9.4 4 | NAMESPACE=istio-system 5 | 6 | 7 | # Functions ######################################################################### 8 | 9 | prepare_istio(){ 10 | sudo mkdir $HOME/istio 11 | sudo chown ${USER} -R $HOME/istio 12 | kubectl create ns ${NAMESPACE} 13 | } 14 | 15 | install_istioctl(){ 16 | echo 17 | echo "Istioctl - install" 18 | curl -sL "https://github.com/istio/istio/releases/download/$VERSION/istio-$VERSION-linux-amd64.tar.gz" | tar xz 19 | sudo mv istio-$VERSION/bin/istioctl /usr/local/bin/istioctl 20 | sudo chmod +x /usr/local/bin/istioctl 21 | sudo mv istio-$VERSION/tools/istioctl.bash $HOME/istio/istioctl.bash 22 | sudo mv istio-$VERSION/samples/addons $HOME/istio/addons 23 | sudo mv istio-$VERSION/samples/bookinfo $HOME/istio/bookinfo 24 | sudo rm -rf istio-$VERSION 25 | } 26 | 27 | enable_istioctl_autocompletion(){ 28 | echo "source $HOME/istio/istioctl.bash" >>~/.bashrc 29 | } 30 | 31 | install_istio_operator(){ 32 | echo 33 | echo "Istio operator - install" 34 | istioctl operator init 35 | } 36 | 37 | list_istio_profile(){ 38 | echo 39 | echo "Istio profiles" 40 | istioctl profile list 41 | } 42 | 43 | create_custom_profile(){ 44 | echo "Custom Profile" 45 | echo " 46 | apiVersion: install.istio.io/v1alpha1 47 | kind: IstioOperator 48 | metadata: 49 | name: istio-cp 50 | spec: 51 | profile: default 52 | components: 53 | egressGateways: 54 | - name: istio-egressgateway 55 | enabled: true 56 | "> $HOME/istio/istio_default.yaml 57 | } 58 | 59 | install_istio(){ 60 | kubectl -n ${NAMESPACE} apply -f $HOME/istio/istio_default.yaml 61 | } 62 | 63 | install_addons(){ 64 | kubectl apply -f $HOME/istio/addons 65 | kubectl -n ${NAMESPACE} rollout status deployment/kiali 66 | } 67 | 68 | 69 | # Let's go ################################################################################### 70 | prepare_istio 71 | install_istioctl 72 | enable_istioctl_autocompletion 73 | install_istio_operator 74 | list_istio_profile 75 | create_custom_profile 76 | install_istio 77 | install_addons 78 | 79 | 80 | -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install_k8s_dashboard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_NAME=kubernetes-dashboard 4 | NAMESPACE=kubernetes-dashboard 5 | CHART_VERSION=4.0.3 6 | HOSTNAME=kubernetes-dashboard.info 7 | SERVICE_ACCOUNT_NAME=dashboard-admin 8 | 9 | # Functions ######################################################################### 10 | 11 | prepare_kubernetes_dashboard(){ 12 | sudo mkdir $HOME/kubernetes_dashboard 13 | sudo chown ${USER} -R $HOME/kubernetes_dashboard 14 | kubectl create ns ${NAMESPACE} 15 | } 16 | 17 | add_helm_repo(){ 18 | helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/ 19 | } 20 | 21 | create_rbac(){ 22 | 23 | echo "KUBECTL | create RBAC" 24 | # shellcheck disable=SC2016 25 | echo " 26 | apiVersion: v1 27 | kind: ServiceAccount 28 | metadata: 29 | name: ${SERVICE_ACCOUNT_NAME} 30 | namespace: ${NAMESPACE} 31 | --- 32 | kind: ClusterRoleBinding 33 | apiVersion: rbac.authorization.k8s.io/v1 34 | metadata: 35 | name: ${SERVICE_ACCOUNT_NAME}-clusterrolebinding 36 | subjects: 37 | - kind: ServiceAccount 38 | name: ${SERVICE_ACCOUNT_NAME} 39 | apiGroup: \"\" 40 | namespace: ${NAMESPACE} 41 | roleRef: 42 | kind: ClusterRole 43 | name: cluster-admin 44 | apiGroup: \"\" 45 | "> $HOME/kubernetes_dashboard/rbac.yaml 46 | 47 | kubectl apply -f $HOME/kubernetes_dashboard/rbac.yaml 48 | 49 | } 50 | 51 | create_custom_values(){ 52 | 53 | echo "Custom Values" 54 | echo " 55 | replicaCount: 1 56 | enableInsecureLogin: false 57 | ingress: 58 | enabled: true 59 | annotations: 60 | kubernetes.io/ingress.class: nginx 61 | paths: 62 | - / 63 | hosts: 64 | - ${HOSTNAME} 65 | "> $HOME/kubernetes_dashboard/values.production.yaml 66 | } 67 | 68 | install_kubernetes_dashboard(){ 69 | helm install ${RELEASE_NAME} --namespace ${NAMESPACE} --version ${CHART_VERSION} kubernetes-dashboard/kubernetes-dashboard -f $HOME/kubernetes_dashboard/values.production.yaml 70 | } 71 | 72 | get_dashboard-admin_token(){ 73 | token_secret_name="$(kubectl -n ${NAMESPACE} get serviceaccount ${SERVICE_ACCOUNT_NAME} -o=jsonpath='{.secrets[0].name}')" 74 | token="$(kubectl -n ${NAMESPACE} get secret ${token_secret_name} -ojsonpath='{.data.token}' | base64 --decode)" 75 | echo "Admin Token : ${token}" 76 | } 77 | 78 | 79 | # Let's go ################################################################################### 80 | prepare_kubernetes_dashboard 81 | add_helm_repo 82 | create_rbac 83 | create_custom_values 84 | install_kubernetes_dashboard 85 | get_dashboard-admin_token -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install_k8s_prereqs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Variables ######################################## 4 | 5 | 6 | # Functions ######################################## 7 | 8 | prepare_k8s_node(){ 9 | sudo apt update -qq 2>&1 >/dev/null 10 | sudo apt install -y -qq git w3m sipcalc vim tree net-tools telnet git python3-pip sshpass nfs-common 2>&1 >/dev/null 11 | sudo echo "autocmd filetype yaml setlocal ai ts=2 sw=2 et" > /home/vagrant/.vimrc 12 | } 13 | 14 | prepare_ssh(){ 15 | sudo sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config 16 | sudo systemctl restart sshd 17 | } 18 | 19 | # Let's Go!! ######################################## 20 | prepare_k8s_node 21 | prepare_ssh -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install_nfs_provisioner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IP_NFS=$(dig +short nfs.kub) 4 | NFS_PATH=/srv/kubedata 5 | RELEASE_NAME=nfs-provisioner 6 | NAMESPACE=nfs-system 7 | CHART_VERSION=4.0.10 8 | 9 | kubectl_for_root(){ 10 | sudo mkdir /root/.kube 11 | sudo cp /home/vagrant/.kube/config /root/.kube/ 12 | } 13 | 14 | # Functions ######################################################################### 15 | 16 | prepare_nfs_provisioner(){ 17 | sudo mkdir $HOME/nfs_provisioner 18 | sudo chown ${USER} -R $HOME/nfs_provisioner 19 | kubectl create ns ${NAMESPACE} 20 | } 21 | 22 | add_helm_repo(){ 23 | helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ 24 | } 25 | 26 | create_custom_values(){ 27 | 28 | echo "Custom Values" 29 | echo " 30 | replicaCount: 1 31 | image: 32 | pullPolicy: IfNotPresent 33 | storageClass: 34 | name: nfs-client 35 | defaultClass: true 36 | archiveOnDelete: true 37 | accessModes: ReadWriteOnce 38 | reclaimPolicy: Delete 39 | nfs: 40 | server: ${IP_NFS} 41 | path: ${NFS_PATH} 42 | 43 | "> $HOME/nfs_provisioner/values.production.yaml 44 | } 45 | 46 | install_nfs_provisioner(){ 47 | helm install ${RELEASE_NAME} --namespace ${NAMESPACE} --version ${CHART_VERSION} nfs-subdir-external-provisioner/nfs-subdir-external-provisioner -f $HOME/nfs_provisioner/values.production.yaml 48 | } 49 | 50 | 51 | # Let's go ################################################################################### 52 | prepare_nfs_provisioner 53 | add_helm_repo 54 | create_custom_values 55 | install_nfs_provisioner -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install_rancher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_NAME=rancher 4 | NAMESPACE=cattle-system 5 | CHART_VERSION=2.5.8 6 | LETSENCRYPT_EMAIL=suaybsimsek58@gmail.com 7 | HOSTNAME=rancher.info 8 | 9 | # Functions ######################################################################### 10 | 11 | prepare_rancher(){ 12 | sudo mkdir $HOME/rancher 13 | sudo chown ${USER} -R $HOME/rancher 14 | kubectl create ns ${NAMESPACE} 15 | } 16 | 17 | add_helm_repo(){ 18 | helm repo add rancher-latest https://releases.rancher.com/server-charts/latest 19 | } 20 | 21 | create_custom_values(){ 22 | echo "Custom Values" 23 | echo " 24 | replicas: 3 25 | addLocal: true 26 | hostname: ${HOSTNAME} 27 | letsEncrypt: 28 | email: ${LETSENCRYPT_EMAIL} 29 | environment: production 30 | ingress: 31 | extraAnnotations: 32 | kubernetes.io/ingress.class: nginx 33 | tls: 34 | source: rancher 35 | "> $HOME/rancher/values.production.yaml 36 | } 37 | 38 | install_rancher(){ 39 | helm install ${RELEASE_NAME} --namespace ${NAMESPACE} --version ${CHART_VERSION} rancher-latest/rancher -f $HOME/rancher/values.production.yaml 40 | } 41 | 42 | 43 | # Let's go ################################################################################### 44 | prepare_rancher 45 | add_helm_repo 46 | create_custom_values 47 | install_rancher -------------------------------------------------------------------------------- /deploy/setup/kubernetes-setup/install_sonarqube.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_NAME=sonarqube 4 | NAMESPACE=sonarqube-system 5 | CHART_VERSION=9.6.4 6 | POSTGRESQL_USER=sonar 7 | POSTGRESQL_PASSWORD=sonar 8 | POSTGRESQL_DATABASE=sonar 9 | ADMIN_USER=admin 10 | ADMIN_PASSWORD=root 11 | URL_PREFIX=/sonarqube 12 | HOSTNAME=sonarqube.info 13 | 14 | # Functions ######################################################################### 15 | 16 | prepare_sonarqube(){ 17 | sudo mkdir $HOME/sonarqube 18 | sudo chown ${USER} -R $HOME/sonarqube 19 | kubectl create ns ${NAMESPACE} 20 | } 21 | 22 | add_helm_repo(){ 23 | helm repo add oteemocharts https://oteemo.github.io/charts 24 | } 25 | 26 | create_custom_values(){ 27 | echo "Custom Values" 28 | echo " 29 | replicaCount: 1 30 | jdbcDatabaseType: postgresql 31 | service: 32 | type: ClusterIP 33 | externalPort: 9000 34 | postgresql: 35 | enabled: true 36 | postgresqlUsername: ${POSTGRESQL_USER} 37 | postgresqlPassword: ${POSTGRESQL_PASSWORD} 38 | postgresqlDatabase: ${POSTGRESQL_DATABASE} 39 | ingress: 40 | enabled: true 41 | annotations: 42 | kubernetes.io/ingress.class: nginx 43 | tls: [] 44 | hosts: 45 | - name: ${HOSTNAME} 46 | path: ${URL_PREFIX} 47 | account: 48 | adminPassword: ${ADMIN_PASSWORD} 49 | currentAdminPassword: admin 50 | sonarProperties: 51 | sonar.forceAuthentication: true 52 | sonar.web.context: ${URL_PREFIX} 53 | readinessProbe: 54 | sonarWebContext: ${URL_PREFIX}/ 55 | livenessProbe: 56 | sonarWebContext: ${URL_PREFIX}/ 57 | "> $HOME/sonarqube/values.production.yaml 58 | } 59 | 60 | install_sonarqube(){ 61 | helm install ${RELEASE_NAME} --namespace ${NAMESPACE} --version ${CHART_VERSION} oteemocharts/sonarqube -f $HOME/sonarqube/values.production.yaml 62 | } 63 | 64 | 65 | # Let's go ################################################################################### 66 | prepare_sonarqube 67 | add_helm_repo 68 | create_custom_values 69 | install_sonarqube -------------------------------------------------------------------------------- /deploy/setup/nfs-server-setup/copy_fabricfiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NFS_DIR=/srv/kubedata 4 | TARGET_PATH=$NFS_DIR/fabricfiles 5 | FABRIC_FILES_PATH=/vagrant/k8s/fabricfiles 6 | 7 | # Functions ######################################################################### 8 | 9 | function copy_fabricfiles(){ 10 | echo "## Copied fabric files" 11 | echo 12 | sudo cp -a $FABRIC_FILES_PATH/. $TARGET_PATH/ 13 | sudo chmod -R 777 $TARGET_PATH/ 14 | } 15 | 16 | # Let's go ################################################################################### 17 | copy_fabricfiles -------------------------------------------------------------------------------- /deploy/setup/nfs-server-setup/create_fabric_dir.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NFS_DIR=/srv/kubedata 4 | FABRIC_FILES_PATH=$NFS_DIR/fabricfiles 5 | BROKER_PATH=$NFS_DIR/fabricfiles/broker 6 | 7 | # Functions ######################################################################### 8 | 9 | function create_fabricfiles_dir(){ 10 | echo "## Created fabric files path" 11 | echo 12 | sudo mkdir $FABRIC_FILES_PATH 13 | sudo chown -R nobody:nogroup $FABRIC_FILES_PATH 14 | sudo chmod -R 777 $FABRIC_FILES_PATH 15 | } 16 | 17 | 18 | function create_broker_dir(){ 19 | echo "## Created broker path" 20 | echo 21 | sudo mkdir -p $BROKER_PATH 22 | sudo mkdir $BROKER_PATH/zookeeper0 23 | sudo mkdir $BROKER_PATH/zookeeper1 24 | sudo mkdir $BROKER_PATH/kafka0 25 | sudo mkdir $BROKER_PATH/kafka1 26 | sudo chmod -R 777 $BROKER_PATH 27 | } 28 | 29 | # Let's go ################################################################################### 30 | create_fabricfiles_dir 31 | create_broker_dir 32 | -------------------------------------------------------------------------------- /deploy/setup/nfs-server-setup/install_nfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # install nfs server 4 | 5 | 6 | # get some variables ##################################################################### 7 | 8 | IP_RANGE=$(dig +short k8smaster | grep -v 127.0 | sed s/".[0-9]*$"/.0/g) 9 | 10 | NFS_PATH=/srv/kubedata 11 | 12 | 13 | # Functions ##################################################################### 14 | 15 | 16 | prepare_directories(){ 17 | sudo mkdir -p ${NFS_PATH} 18 | sudo chmod 777 -R ${NFS_PATH} 19 | } 20 | 21 | install_nfs(){ 22 | 23 | sudo apt-get install -y nfs-kernel-server 2>&1 > /dev/null 24 | 25 | } 26 | 27 | set_nfs(){ 28 | sudo echo "${NFS_PATH} ${IP_RANGE}/24(rw,sync,no_root_squash,no_subtree_check)">/etc/exports 29 | } 30 | 31 | run_nfs(){ 32 | sudo systemctl restart nfs-server rpcbind 33 | sudo exportfs -a 34 | } 35 | 36 | # Let's go ####################################################################### 37 | prepare_directories 38 | install_nfs 39 | set_nfs 40 | run_nfs -------------------------------------------------------------------------------- /frontend/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | Dockerfile* 4 | docker-compose* 5 | .dockerignore 6 | .git 7 | .gitignore 8 | README.md 9 | LICENSE 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | .history/* 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db -------------------------------------------------------------------------------- /frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1 2 | 3 | FROM node:10-alpine as build-step 4 | 5 | RUN mkdir -p /app 6 | 7 | WORKDIR /app 8 | 9 | COPY package.json /app 10 | 11 | RUN npm install 12 | 13 | COPY . /app 14 | 15 | RUN npm run build --prod 16 | 17 | # Stage 2 18 | 19 | FROM nginx:1.17.1-alpine 20 | 21 | COPY --from=build-step /app/dist/ui /usr/share/nginx/html 22 | -------------------------------------------------------------------------------- /frontend/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /frontend/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /frontend/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('ui app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /frontend/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /frontend/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/ui'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~8.2.14", 15 | "@angular/cdk": "~8.2.3", 16 | "@angular/common": "~8.2.14", 17 | "@angular/compiler": "~8.2.14", 18 | "@angular/core": "~8.2.14", 19 | "@angular/forms": "~8.2.14", 20 | "@angular/material": "^8.2.3", 21 | "@angular/platform-browser": "~8.2.14", 22 | "@angular/platform-browser-dynamic": "~8.2.14", 23 | "@angular/router": "~8.2.14", 24 | "hammerjs": "^2.0.8", 25 | "rxjs": "~6.4.0", 26 | "tslib": "^1.10.0", 27 | "zone.js": "~0.9.1" 28 | }, 29 | "devDependencies": { 30 | "@angular-devkit/build-angular": "~0.803.29", 31 | "@angular/cli": "~8.3.29", 32 | "@angular/compiler-cli": "~8.2.14", 33 | "@angular/language-service": "~8.2.14", 34 | "@types/node": "~8.9.4", 35 | "@types/jasmine": "~3.3.8", 36 | "@types/jasminewd2": "~2.0.3", 37 | "codelyzer": "^5.0.0", 38 | "jasmine-core": "~3.4.0", 39 | "jasmine-spec-reporter": "~4.2.1", 40 | "karma": "~4.1.0", 41 | "karma-chrome-launcher": "~2.2.0", 42 | "karma-coverage-istanbul-reporter": "~2.0.1", 43 | "karma-jasmine": "~2.0.1", 44 | "karma-jasmine-html-reporter": "^1.4.0", 45 | "protractor": "~7.0.0", 46 | "ts-node": "~7.0.0", 47 | "tslint": "~5.15.0", 48 | "typescript": "~3.5.3" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /frontend/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { AssetListComponent } from './asset-list/asset-list.component'; 4 | const routes: Routes = [ 5 | { 6 | path: '', 7 | component: AssetListComponent, 8 | } 9 | ]; 10 | 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forRoot(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class AppRoutingModule { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /frontend/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/frontend/src/app/app.component.css -------------------------------------------------------------------------------- /frontend/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Asset Transfer

4 | 5 | 6 |
7 | 8 |
9 | 10 |
11 | 12 | 13 |
14 | -------------------------------------------------------------------------------- /frontend/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.debugElement.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'ui'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.debugElement.componentInstance; 22 | expect(app.title).toEqual('ui'); 23 | }); 24 | 25 | it('should render title', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.debugElement.nativeElement; 29 | expect(compiled.querySelector('.content span').textContent).toContain('ui app is running!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /frontend/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'ui'; 10 | } 11 | -------------------------------------------------------------------------------- /frontend/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | 4 | import { AppRoutingModule } from './app-routing.module'; 5 | import { AppComponent } from './app.component'; 6 | import { HttpClientModule } from '@angular/common/http'; 7 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 8 | import {MatToolbarModule} from '@angular/material/toolbar'; 9 | import {MatIconModule} from '@angular/material/icon'; 10 | import { MatSidenavModule, } from '@angular/material/sidenav'; 11 | import { MatListModule, } from "@angular/material/list"; 12 | import { MatButtonModule } from "@angular/material/button"; 13 | import { AssetListComponent } from './asset-list/asset-list.component'; 14 | import {MatTableModule} from '@angular/material/table'; 15 | import { MatTooltipModule } from '@angular/material/tooltip'; 16 | import { MatFormFieldModule } from '@angular/material/form-field'; 17 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 18 | import { MatInputModule} from "@angular/material/input"; 19 | import {MatCardModule} from '@angular/material/card'; 20 | import { AssetDialogComponent } from './asset-dialog/asset-dialog.component'; 21 | import { MatDialogModule } from '@angular/material/dialog'; 22 | import { HistoryDialogComponent } from './history-dialog/history-dialog.component'; 23 | @NgModule({ 24 | declarations: [ 25 | AppComponent, 26 | AssetListComponent, 27 | AssetDialogComponent, 28 | HistoryDialogComponent 29 | ], 30 | imports: [ 31 | BrowserModule, 32 | AppRoutingModule, 33 | HttpClientModule, 34 | BrowserAnimationsModule, 35 | MatToolbarModule, 36 | MatIconModule, 37 | MatToolbarModule, 38 | MatSidenavModule, 39 | MatListModule, 40 | MatButtonModule, 41 | MatIconModule, 42 | MatTableModule, 43 | MatTooltipModule, 44 | MatFormFieldModule, 45 | ReactiveFormsModule, 46 | FormsModule, 47 | MatFormFieldModule, 48 | MatInputModule, 49 | MatCardModule, 50 | MatDialogModule 51 | ], 52 | providers: [], 53 | bootstrap: [AppComponent], 54 | entryComponents:[AssetDialogComponent,HistoryDialogComponent] 55 | }) 56 | export class AppModule { } 57 | -------------------------------------------------------------------------------- /frontend/src/app/asset-dialog/asset-dialog.component.css: -------------------------------------------------------------------------------- 1 | .example-container{ 2 | text-align: center 3 | } 4 | 5 | .form-container{ 6 | width: 100 px; 7 | margin: 0 px auto; 8 | margin-top: 200 px 9 | } 10 | 11 | .form-field{ 12 | display: block 13 | } -------------------------------------------------------------------------------- /frontend/src/app/asset-dialog/asset-dialog.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 |
6 | 7 | ID 8 | 9 | 10 | 11 | 12 | Owner 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Color 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Size 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | Appraisal Value 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /frontend/src/app/asset-dialog/asset-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AssetDialogComponent } from './asset-dialog.component'; 4 | 5 | describe('AssetDialogComponent', () => { 6 | let component: AssetDialogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AssetDialogComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AssetDialogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /frontend/src/app/asset-dialog/asset-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject, OnInit } from '@angular/core'; 2 | 3 | import { FormBuilder, FormGroup, Validators } from '@angular/forms'; 4 | import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; 5 | import { Asset } from '../asset.model'; 6 | @Component({ 7 | selector: 'app-asset-dialog', 8 | templateUrl: './asset-dialog.component.html', 9 | styleUrls: ['./asset-dialog.component.css'] 10 | }) 11 | export class AssetDialogComponent implements OnInit { 12 | assetForm: FormGroup; 13 | constructor(public dialogRef: MatDialogRef, 14 | private formBuilder: FormBuilder, 15 | @Inject(MAT_DIALOG_DATA) public data: any) { 16 | this.assetForm = this.formBuilder.group({ 17 | "ID": [null, Validators.required], 18 | "owner": [null, Validators.required], 19 | "color": [null, Validators.required], 20 | "size": [null, Validators.required], 21 | "appraisedValue": [null, Validators.required] 22 | }); 23 | if (data.asset){ 24 | this.assetForm.setValue(data.asset); 25 | this.assetForm.controls['ID'].disable(); 26 | } 27 | } 28 | 29 | ngOnInit(): void { 30 | } 31 | 32 | submit() { 33 | this.dialogRef.close(Object.assign(this.assetForm.getRawValue() as Asset)); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /frontend/src/app/asset-list/asset-list.component.css: -------------------------------------------------------------------------------- 1 | table { 2 | width: 100%; 3 | } -------------------------------------------------------------------------------- /frontend/src/app/asset-list/asset-list.component.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 57 | 58 | 59 | 60 | 61 | 62 |
# {{i+1}} ID {{element.ID}} Owner {{element.owner}} Size {{element.size}} Color {{element.color}} Appraised Value {{element.appraisedValue}} Actions 46 | 49 | 52 | 53 | 56 |
63 | 64 | -------------------------------------------------------------------------------- /frontend/src/app/asset-list/asset-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AssetListComponent } from './asset-list.component'; 4 | 5 | describe('AssetListComponent', () => { 6 | let component: AssetListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AssetListComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AssetListComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /frontend/src/app/asset-list/asset-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { MatDialog } from '@angular/material/dialog'; 3 | import { AssetDialogComponent } from '../asset-dialog/asset-dialog.component'; 4 | import { Asset } from '../asset.model'; 5 | import { HistoryDialogComponent } from '../history-dialog/history-dialog.component'; 6 | import { HttpService } from '../services/http.service'; 7 | 8 | @Component({ 9 | selector: 'app-asset-list', 10 | templateUrl: './asset-list.component.html', 11 | styleUrls: ['./asset-list.component.css'] 12 | }) 13 | export class AssetListComponent implements OnInit { 14 | assets: Asset[] = [] 15 | displayedColumns: string[] = ['sno', 'id', 'owner', 'size', 'color', 'appraisedValue', 'actions']; 16 | dataSource; 17 | ngOnInit(): void { 18 | this.getAssets(); 19 | 20 | } 21 | constructor(private httpService: HttpService, private dialog: MatDialog) { } 22 | title = 'ui'; 23 | 24 | 25 | getAssets() { 26 | this.httpService.getAssets().subscribe((response:any)=>{ 27 | let data=response; 28 | this.assets= data.map(item=>item.Record) 29 | this.dataSource = this.assets; 30 | }); 31 | } 32 | 33 | createDialog() { 34 | const dialogRef = this.dialog.open(AssetDialogComponent, { 35 | width: '400px', 36 | data: {asset:null,button:"Create Asset"} 37 | }); 38 | 39 | dialogRef.afterClosed().subscribe(result => { 40 | if (result) { 41 | console.log(result) 42 | this.httpService.createAsset(result).subscribe(data=>{ 43 | console.log(data); 44 | this.getAssets(); 45 | }) 46 | } 47 | }); 48 | } 49 | 50 | 51 | updateAsset(id: string,asset: Asset) { 52 | const dialogRef = this.dialog.open(AssetDialogComponent, { 53 | width: '400px', 54 | data: {asset:asset,button:"Update Asset"} 55 | }); 56 | 57 | dialogRef.afterClosed().subscribe(result => { 58 | if (result) { 59 | this.httpService.updateAsset(id,result).subscribe(data=>{ 60 | this.getAssets() 61 | }); 62 | } 63 | }); 64 | } 65 | deleteAsset(id: string) { 66 | console.log(id) 67 | if(confirm("Are you sure you want to delete?")) 68 | this.httpService.deleteAsset(id).subscribe(data=>{ 69 | this.getAssets() 70 | }); 71 | } 72 | 73 | history(id:string){ 74 | 75 | 76 | this.httpService.getHistory(id).subscribe(data=>{ 77 | console.log(data); 78 | this.dialog.open(HistoryDialogComponent, { 79 | width: '500px', 80 | data 81 | }); 82 | }); 83 | 84 | 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /frontend/src/app/asset.model.ts: -------------------------------------------------------------------------------- 1 | export interface Asset { 2 | ID: string; 3 | color: string; 4 | size: number; 5 | owner: string; 6 | appraisedValue: number; 7 | } 8 | 9 | export interface History { 10 | record: Asset; 11 | txId: string; 12 | timestamp: string; 13 | isDelete: boolean; 14 | } -------------------------------------------------------------------------------- /frontend/src/app/history-dialog/history-dialog.component.css: -------------------------------------------------------------------------------- 1 | .bold{ 2 | font-weight: bolder; 3 | } 4 | div{ 5 | white-space: nowrap; 6 | overflow: hidden; 7 | text-overflow: ellipsis; 8 | } -------------------------------------------------------------------------------- /frontend/src/app/history-dialog/history-dialog.component.html: -------------------------------------------------------------------------------- 1 | 2 |

Asset History #{{history[0].record.ID}}

3 |
4 | 5 | 6 | 7 |
8 | ID: {{asset.record.ID}} 9 |
10 |
11 | Color: {{asset.record.color}} 12 |
13 |
14 | Size: {{asset.record.size}} 15 |
16 | 17 |
18 | Owner: {{asset.record.owner}} 19 |
20 | 21 |
22 | Appraised Value: {{asset.record.appraisedValue}} 23 |
24 | 25 |
26 | TxID: {{asset.txId}} 27 |
28 |
29 | Timestamp: {{asset.timestamp | date :'dd-MM-yyyy hh:mm a'}} 30 |
31 |
32 | Deleted: {{asset.isDelete}} 33 |
34 |
35 | 36 | 37 |
-------------------------------------------------------------------------------- /frontend/src/app/history-dialog/history-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HistoryDialogComponent } from './history-dialog.component'; 4 | 5 | describe('HistoryDialogComponent', () => { 6 | let component: HistoryDialogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ HistoryDialogComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HistoryDialogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /frontend/src/app/history-dialog/history-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject, OnInit } from '@angular/core'; 2 | import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; 3 | import { History } from '../asset.model'; 4 | 5 | @Component({ 6 | selector: 'app-history-dialog', 7 | templateUrl: './history-dialog.component.html', 8 | styleUrls: ['./history-dialog.component.css'] 9 | }) 10 | export class HistoryDialogComponent implements OnInit { 11 | history:History[]; 12 | constructor(public dialogRef: MatDialogRef, 13 | @Inject(MAT_DIALOG_DATA) public data: History[] 14 | ) { 15 | this.history=data; 16 | console.log(data) 17 | } 18 | 19 | ngOnInit(): void { 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /frontend/src/app/services/http.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { HttpService } from './http.service'; 4 | 5 | describe('HttpService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: HttpService = TestBed.get(HttpService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/src/app/services/http.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from '@angular/common/http'; 2 | import { Injectable } from '@angular/core'; 3 | import { Observable, of } from "rxjs"; 4 | import { environment } from 'src/environments/environment'; 5 | import { Asset, History } from '../asset.model'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class HttpService { 11 | 12 | constructor(private http: HttpClient) { } 13 | 14 | getAssets() { 15 | return this.http.get(`${environment.baseUrl}/api/assets`); 16 | } 17 | 18 | createAsset(asset: Asset) { 19 | return this.http.post(`${environment.baseUrl}/api/assets`, asset) 20 | } 21 | 22 | updateAsset(id: string,result: any) { 23 | let data = { 24 | owner: result.owner, 25 | color: result.color, 26 | size: result.size, 27 | appraisedValue: result.appraisedValue 28 | } 29 | return this.http.put(`${environment.baseUrl}/api/assets/${id}`, data) 30 | } 31 | 32 | getHistory(id: string): Observable { 33 | return this.http.get(`${environment.baseUrl}/api/assets/${id}`); 34 | } 35 | 36 | deleteAsset(id: string) { 37 | return this.http.delete(`${environment.baseUrl}/api/assets/${id}`) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /frontend/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/frontend/src/assets/.gitkeep -------------------------------------------------------------------------------- /frontend/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | baseUrl:'http://api.hlf-k8.tk' 4 | }; 5 | -------------------------------------------------------------------------------- /frontend/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | baseUrl:'http://api.hlf-k8.tk' 8 | }; 9 | 10 | /* 11 | * For easier debugging in development mode, you can import the following file 12 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 13 | * 14 | * This import should be commented out in production mode because it will have a negative impact 15 | * on performance if an error is thrown. 16 | */ 17 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 18 | -------------------------------------------------------------------------------- /frontend/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/frontend/src/favicon.ico -------------------------------------------------------------------------------- /frontend/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ui 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /frontend/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'hammerjs'; 2 | import { enableProdMode } from '@angular/core'; 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | 5 | import { AppModule } from './app/app.module'; 6 | import { environment } from './environments/environment'; 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic().bootstrapModule(AppModule) 13 | .catch(err => console.error(err)); 14 | -------------------------------------------------------------------------------- /frontend/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /frontend/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /frontend/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.ts" 13 | ], 14 | "exclude": [ 15 | "src/test.ts", 16 | "src/**/*.spec.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ] 21 | }, 22 | "angularCompilerOptions": { 23 | "fullTemplateTypeCheck": true, 24 | "strictInjectionParameters": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /frontend/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /frontend/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "array-type": false, 5 | "arrow-parens": false, 6 | "deprecation": { 7 | "severity": "warning" 8 | }, 9 | "component-class-suffix": true, 10 | "contextual-lifecycle": true, 11 | "directive-class-suffix": true, 12 | "directive-selector": [ 13 | true, 14 | "attribute", 15 | "app", 16 | "camelCase" 17 | ], 18 | "component-selector": [ 19 | true, 20 | "element", 21 | "app", 22 | "kebab-case" 23 | ], 24 | "import-blacklist": [ 25 | true, 26 | "rxjs/Rx" 27 | ], 28 | "interface-name": false, 29 | "max-classes-per-file": false, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-consecutive-blank-lines": false, 47 | "no-console": [ 48 | true, 49 | "debug", 50 | "info", 51 | "time", 52 | "timeEnd", 53 | "trace" 54 | ], 55 | "no-empty": false, 56 | "no-inferrable-types": [ 57 | true, 58 | "ignore-params" 59 | ], 60 | "no-non-null-assertion": true, 61 | "no-redundant-jsdoc": true, 62 | "no-switch-case-fall-through": true, 63 | "no-var-requires": false, 64 | "object-literal-key-quotes": [ 65 | true, 66 | "as-needed" 67 | ], 68 | "object-literal-sort-keys": false, 69 | "ordered-imports": false, 70 | "quotemark": [ 71 | true, 72 | "single" 73 | ], 74 | "trailing-comma": false, 75 | "no-conflicting-lifecycle": true, 76 | "no-host-metadata-property": true, 77 | "no-input-rename": true, 78 | "no-inputs-metadata-property": true, 79 | "no-output-native": true, 80 | "no-output-on-prefix": true, 81 | "no-output-rename": true, 82 | "no-outputs-metadata-property": true, 83 | "template-banana-in-box": true, 84 | "template-no-negated-async": true, 85 | "use-lifecycle-interface": true, 86 | "use-pipe-transform-interface": true 87 | }, 88 | "rulesDirectory": [ 89 | "codelyzer" 90 | ] 91 | } -------------------------------------------------------------------------------- /hlf-api/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | wallet/ 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/**/target/ 6 | !**/src/test/**/target/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | !**/src/main/**/build/ 31 | !**/src/test/**/build/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /hlf-api/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/hlf-api/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /hlf-api/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/SpringBootHlfExampleApplication.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootHlfExampleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringBootHlfExampleApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/config/ApiDocConfig.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.config; 2 | 3 | import io.swagger.v3.oas.models.Components; 4 | import io.swagger.v3.oas.models.OpenAPI; 5 | import io.swagger.v3.oas.models.info.Info; 6 | import io.swagger.v3.oas.models.info.License; 7 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | @Configuration(proxyBeanMethods = false) 12 | @EnableConfigurationProperties(ApiDocProperties.class) 13 | public class ApiDocConfig { 14 | 15 | @Bean 16 | public OpenAPI customOpenAPI(ApiDocProperties apiDocProperties) { 17 | return new OpenAPI() 18 | .components(new Components()) 19 | .info(metaData(apiDocProperties)); 20 | } 21 | 22 | 23 | private Info metaData(ApiDocProperties apiDocProperties) { 24 | return new Info() 25 | .title(apiDocProperties.getTitle()) 26 | .description(apiDocProperties.getDescription()) 27 | .version(apiDocProperties.getVersion()) 28 | .termsOfService(apiDocProperties.getTermsOfServiceUrl()) 29 | .license(new License(). 30 | name(apiDocProperties.getLicense()) 31 | .url(apiDocProperties.getLicenseUrl())); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/config/ApiDocProperties.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.config; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | 7 | @ConfigurationProperties("api-docs") 8 | @Getter 9 | @Setter 10 | public class ApiDocProperties { 11 | 12 | private String title; 13 | private String description; 14 | private String version; 15 | private String termsOfServiceUrl; 16 | private String license; 17 | private String licenseUrl; 18 | } 19 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.config; 2 | 3 | 4 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.util.CollectionUtils; 8 | import org.springframework.web.cors.CorsConfiguration; 9 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 10 | import org.springframework.web.filter.CorsFilter; 11 | 12 | @Configuration(proxyBeanMethods = false) 13 | @EnableConfigurationProperties(CorsProperties.class) 14 | public class CorsConfig { 15 | 16 | @Bean 17 | public CorsFilter corsFilter(CorsProperties corsProperties) { 18 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 19 | CorsConfiguration config = new CorsConfiguration(); 20 | config.setAllowedOrigins(corsProperties.getAllowedOrigins()); 21 | config.setAllowedMethods(corsProperties.getAllowedMethods()); 22 | config.setAllowedHeaders(corsProperties.getAllowedHeaders()); 23 | config.setAllowCredentials(corsProperties.getAllowCredentials()); 24 | config.setMaxAge(corsProperties.getMaxAge()); 25 | if(!CollectionUtils.isEmpty(corsProperties.getAllowedOrigins())) { 26 | source.registerCorsConfiguration("/api/**", config); 27 | } 28 | return new CorsFilter(source); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/config/CorsProperties.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.config; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | 7 | import java.util.List; 8 | 9 | @ConfigurationProperties("cors") 10 | @Getter 11 | @Setter 12 | public class CorsProperties { 13 | 14 | private List allowedOrigins; 15 | private List allowedMethods; 16 | private List allowedHeaders; 17 | private Boolean allowCredentials; 18 | private Long maxAge; 19 | } 20 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/controller/CAUserController.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.controller; 2 | 3 | import io.susimsek.springboothlfexample.model.request.CAUserRegistrationDTO; 4 | import io.susimsek.springboothlfexample.model.response.CAUserDTO; 5 | import io.susimsek.springboothlfexample.service.CAUserService; 6 | import io.swagger.v3.oas.annotations.Operation; 7 | import io.swagger.v3.oas.annotations.Parameter; 8 | import io.swagger.v3.oas.annotations.media.Content; 9 | import io.swagger.v3.oas.annotations.media.Schema; 10 | import io.swagger.v3.oas.annotations.responses.ApiResponse; 11 | import io.swagger.v3.oas.annotations.responses.ApiResponses; 12 | import io.swagger.v3.oas.annotations.tags.Tag; 13 | import lombok.RequiredArgsConstructor; 14 | import org.springframework.http.HttpStatus; 15 | import org.springframework.http.ResponseEntity; 16 | import org.springframework.web.bind.annotation.PostMapping; 17 | import org.springframework.web.bind.annotation.RequestBody; 18 | import org.springframework.web.bind.annotation.RequestMapping; 19 | import org.springframework.web.bind.annotation.RestController; 20 | 21 | import javax.validation.Valid; 22 | 23 | @Tag(name = "ca user", description = "the CA User API") 24 | @RestController 25 | @RequestMapping("/api") 26 | @RequiredArgsConstructor 27 | public class CAUserController { 28 | 29 | private final CAUserService caUserService; 30 | 31 | @Operation(summary = "Create user", tags = { "ca user" }) 32 | @ApiResponses(value = { 33 | @ApiResponse(responseCode = "201", description = "successful operation", 34 | content = { 35 | @Content(mediaType = "application/json", schema = @Schema(implementation = CAUserDTO.class)), 36 | @Content(mediaType = "application/xml", schema = @Schema(implementation = CAUserDTO.class)) 37 | } 38 | ), 39 | @ApiResponse(responseCode = "400", description = "Invalid CA User supplied", content = @Content) 40 | }) 41 | @PostMapping(value = "/ca-users/sign-up", consumes = { "application/json", "application/xml"}) 42 | public ResponseEntity registerUser(@Parameter(description="CA User to add. Cannot null or empty.", required=true, schema=@Schema(implementation = CAUserRegistrationDTO.class)) @RequestBody @Valid CAUserRegistrationDTO user) throws Exception { 43 | CAUserDTO caUserDTO = caUserService.registerUser(user); 44 | return ResponseEntity.status(HttpStatus.CREATED) 45 | .body(caUserDTO); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/exception/ExceptionTranslator.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.exception; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.boot.web.error.ErrorAttributeOptions; 5 | import org.springframework.boot.web.servlet.error.ErrorAttributes; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.ResponseStatus; 9 | import org.springframework.web.bind.annotation.RestControllerAdvice; 10 | import org.springframework.web.context.request.RequestAttributes; 11 | import org.springframework.web.context.request.WebRequest; 12 | 13 | import javax.validation.ConstraintViolationException; 14 | import java.util.Map; 15 | 16 | @RestControllerAdvice 17 | @RequiredArgsConstructor 18 | public class ExceptionTranslator { 19 | 20 | private final ErrorAttributes errorAttributes; 21 | 22 | @ExceptionHandler(ConstraintViolationException.class) 23 | @ResponseStatus(HttpStatus.BAD_REQUEST) 24 | public Map processConstraintViolationException(WebRequest request) { 25 | request.setAttribute("javax.servlet.error.status_code", HttpStatus.BAD_REQUEST.value(), RequestAttributes.SCOPE_REQUEST); 26 | return errorAttributes.getErrorAttributes(request, ErrorAttributeOptions.defaults()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/exception/RecordAlreadyExistsException.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.exception; 2 | 3 | 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.web.bind.annotation.ResponseStatus; 6 | 7 | @ResponseStatus(HttpStatus.CONFLICT) 8 | public class RecordAlreadyExistsException extends RuntimeException { 9 | 10 | public RecordAlreadyExistsException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/exception/RecordNotFoundException.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.exception; 2 | 3 | 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.web.bind.annotation.ResponseStatus; 6 | 7 | @ResponseStatus(HttpStatus.NOT_FOUND) 8 | public class RecordNotFoundException extends RuntimeException { 9 | 10 | public RecordNotFoundException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/model/request/AssetRegistrationRequestDTO.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.model.request; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | import javax.validation.constraints.Max; 9 | import javax.validation.constraints.Min; 10 | import javax.validation.constraints.NotBlank; 11 | import javax.validation.constraints.Size; 12 | 13 | @Getter 14 | @Setter 15 | public class AssetRegistrationRequestDTO { 16 | 17 | @Schema(description = "Unique identifier of the Asset.", example = "asset9", required = true) 18 | @NotBlank 19 | @Size(max = 25) 20 | @JsonProperty("ID") 21 | private String id; 22 | 23 | @Schema(description = "Owner of the Asset.", example = "tom", required = true) 24 | @NotBlank 25 | @Size(max = 25) 26 | private String owner; 27 | 28 | @Schema(description = "Color of the Asset.", example = "red", required = true) 29 | @NotBlank 30 | @Size(max = 25) 31 | private String color; 32 | 33 | @Schema(description = "Size of the Asset.", example = "12", required = true) 34 | @Min(1) 35 | @Max(50) 36 | private int size; 37 | 38 | @Schema(description = "Appraised Value of the Asset.", example = "20", required = true) 39 | @Min(1) 40 | @Max(500) 41 | private int appraisedValue; 42 | } -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/model/request/AssetUpdateRequestDTO.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.model.request; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import javax.validation.constraints.Max; 8 | import javax.validation.constraints.Min; 9 | import javax.validation.constraints.NotBlank; 10 | import javax.validation.constraints.Size; 11 | 12 | @Getter 13 | @Setter 14 | public class AssetUpdateRequestDTO { 15 | 16 | @Schema(description = "Owner of the Asset.", example = "tom", required = true) 17 | @NotBlank 18 | @Size(max = 25) 19 | private String owner; 20 | 21 | @Schema(description = "Color of the Asset.", example = "red", required = true) 22 | @NotBlank 23 | @Size(max = 25) 24 | private String color; 25 | 26 | @Schema(description = "Size of the Asset.", example = "12", required = true) 27 | @Min(1) 28 | @Max(50) 29 | private int size; 30 | 31 | @Schema(description = "Appraised Value of the Asset.", example = "20", required = true) 32 | @Min(1) 33 | @Max(500) 34 | private int appraisedValue; 35 | } 36 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/model/request/CAUserRegistrationDTO.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.model.request; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | import javax.validation.constraints.Size; 9 | 10 | @Getter 11 | @Setter 12 | public class CAUserRegistrationDTO { 13 | 14 | @Schema(description = "Unique identifier of the Org MSP.", 15 | example = "Org1MSP", required = true) 16 | @NotBlank 17 | @Size(max = 25) 18 | private String org; 19 | 20 | @Schema(description = "Unique identifier of the User.", 21 | example = "max", required = true) 22 | @NotBlank 23 | @Size(max = 50) 24 | private String userId; 25 | } 26 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/model/response/AssetDTO.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.model.response; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Setter 10 | public class AssetDTO { 11 | @Schema(description = "Unique identifier of the Asset.", example = "asset9", required = true) 12 | @JsonProperty("ID") 13 | private String id; 14 | 15 | @Schema(description = "Owner of the Asset.", example = "tom", required = true) 16 | private String owner; 17 | 18 | @Schema(description = "Color of the Asset.", example = "red", required = true) 19 | private String color; 20 | 21 | @Schema(description = "Size of the Asset.", example = "12", required = true) 22 | private int size; 23 | 24 | @Schema(description = "Appraised Value of the Asset.", example = "20", required = true) 25 | private int appraisedValue; 26 | } -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/model/response/AssetHistoryDTO.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.model.response; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @Getter 10 | @Setter 11 | public class AssetHistoryDTO { 12 | 13 | @Schema(description = "Deletion status of the Transaction.", example = "false", required = true) 14 | private boolean isDelete; 15 | 16 | @Schema(description = "Asset Information.", required = true) 17 | private AssetDTO record; 18 | 19 | @Schema(description = "Unique identifier of the Transaction.", example = "45b4523648a6c52fb00bfdbfdd3ae2f52474c9fe71d328914de89fa7ce2c1681", required = true) 20 | private String txId; 21 | 22 | @Schema(description = "Creation Date of the Transaction.", example = "2021-09-22T16:44:26.3014639Z", required = true) 23 | private LocalDateTime timestamp; 24 | } -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/model/response/AssetItemDTO.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.model.response; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Setter 10 | public class AssetItemDTO { 11 | 12 | @Schema(description = "Asset Information.", required = true) 13 | @JsonProperty("Record") 14 | private AssetDTO assetDTO; 15 | 16 | @Schema(description = "Unique identifier of the Asset.", required = true) 17 | @JsonProperty("Key") 18 | private String key; 19 | } -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/model/response/CAUserDTO.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.model.response; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.*; 5 | 6 | @Getter 7 | @Setter 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Builder 11 | public class CAUserDTO { 12 | 13 | @Schema(description = "Unique identifier of the Org MSP.", 14 | example = "Org1MSP", required = true) 15 | private String org; 16 | 17 | @Schema(description = "Unique identifier of the User.", 18 | example = "max", required = true) 19 | private String userId; 20 | 21 | @Schema(description = "Affiliation of the User.", 22 | example = "org1.department1", required = true) 23 | private String affiliation; 24 | } 25 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/service/AssetService.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.service; 2 | 3 | import io.susimsek.springboothlfexample.model.request.AssetRegistrationRequestDTO; 4 | import io.susimsek.springboothlfexample.model.request.AssetUpdateRequestDTO; 5 | import io.susimsek.springboothlfexample.model.response.AssetDTO; 6 | import io.susimsek.springboothlfexample.model.response.AssetHistoryDTO; 7 | import io.susimsek.springboothlfexample.model.response.AssetItemDTO; 8 | import org.hyperledger.fabric.gateway.ContractException; 9 | 10 | import java.util.List; 11 | import java.util.concurrent.TimeoutException; 12 | 13 | public interface AssetService { 14 | AssetDTO createAsset(AssetRegistrationRequestDTO asset) throws InterruptedException, TimeoutException, ContractException; 15 | List findAllAssets() throws ContractException; 16 | AssetDTO updateAsset(String assetId, AssetUpdateRequestDTO asset) throws InterruptedException, TimeoutException, ContractException; 17 | List findAssetHistory(String assetId) throws ContractException; 18 | void deleteAsset(String assetId) throws ContractException, InterruptedException, TimeoutException; 19 | } 20 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/service/CAUserService.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.service; 2 | 3 | import io.susimsek.springboothlfexample.model.request.CAUserRegistrationDTO; 4 | import io.susimsek.springboothlfexample.model.response.CAUserDTO; 5 | 6 | public interface CAUserService { 7 | 8 | CAUserDTO registerUser(CAUserRegistrationDTO user) throws Exception; 9 | } 10 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/service/impl/CAUserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.service.impl; 2 | 3 | 4 | import io.github.susimsek.hlf.ca.user.service.FabricCAUserService; 5 | import io.susimsek.springboothlfexample.exception.RecordAlreadyExistsException; 6 | import io.susimsek.springboothlfexample.model.request.CAUserRegistrationDTO; 7 | import io.susimsek.springboothlfexample.model.response.CAUserDTO; 8 | import io.susimsek.springboothlfexample.service.CAUserService; 9 | import io.susimsek.springboothlfexample.service.mapper.CAUserMapper; 10 | import io.susimsek.springboothlfexample.util.CAUserUtil; 11 | import io.susimsek.springboothlfexample.util.HlfExceptionMessageUtil; 12 | import lombok.RequiredArgsConstructor; 13 | import org.hyperledger.fabric_ca.sdk.exception.RegistrationException; 14 | import org.springframework.stereotype.Service; 15 | 16 | @Service 17 | @RequiredArgsConstructor 18 | public class CAUserServiceImpl implements CAUserService { 19 | 20 | private final FabricCAUserService fabricCAUserService; 21 | private final CAUserMapper caUserMapper; 22 | 23 | @Override 24 | public CAUserDTO registerUser(CAUserRegistrationDTO user) throws Exception { 25 | try { 26 | fabricCAUserService.enrollAdmin(user.getOrg()); 27 | fabricCAUserService.registerAndEnrollUser(user.getOrg(),user.getUserId(), CAUserUtil.AFFILIATION); 28 | CAUserDTO caUserDTO = caUserMapper.cAUserRegistrationDTOToCAUserDTO(user); 29 | caUserDTO.setAffiliation(CAUserUtil.AFFILIATION); 30 | return caUserDTO; 31 | } catch (RegistrationException ex) { 32 | if(ex.getMessage().contains(HlfExceptionMessageUtil.IDENTITY_ALREADY_EXISTS_MESSAGE)){ 33 | throw new RecordAlreadyExistsException(String.format("Identity %s is already registered",user.getUserId())); 34 | } 35 | throw ex; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/service/mapper/AssetMapper.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.service.mapper; 2 | 3 | import io.susimsek.springboothlfexample.model.request.AssetRegistrationRequestDTO; 4 | import io.susimsek.springboothlfexample.model.request.AssetUpdateRequestDTO; 5 | import io.susimsek.springboothlfexample.model.response.AssetDTO; 6 | import org.mapstruct.Mapper; 7 | import org.mapstruct.Mapping; 8 | 9 | @Mapper 10 | public interface AssetMapper { 11 | 12 | AssetDTO assetRegistrationRequestDTOToAssetDTO(AssetRegistrationRequestDTO assetRegistrationRequestDTO); 13 | 14 | @Mapping(target = "id", ignore = true) 15 | AssetDTO assetUpdateRequestDTOToAssetDTO(AssetUpdateRequestDTO assetUpdateRequestDTO); 16 | } 17 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/service/mapper/CAUserMapper.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.service.mapper; 2 | 3 | import io.susimsek.springboothlfexample.model.request.CAUserRegistrationDTO; 4 | import io.susimsek.springboothlfexample.model.response.CAUserDTO; 5 | import org.mapstruct.Mapper; 6 | import org.mapstruct.Mapping; 7 | 8 | @Mapper 9 | public interface CAUserMapper { 10 | 11 | @Mapping(target = "affiliation", ignore = true) 12 | CAUserDTO cAUserRegistrationDTOToCAUserDTO(CAUserRegistrationDTO userRegistrationDTO); 13 | } 14 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/util/CAUserUtil.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.util; 2 | 3 | public final class CAUserUtil { 4 | 5 | public static final String AFFILIATION = "org1.department1"; 6 | } 7 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/util/HlfExceptionMessageUtil.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.util; 2 | 3 | public final class HlfExceptionMessageUtil { 4 | 5 | public static final String IDENTITY_ALREADY_EXISTS_MESSAGE = "already registered"; 6 | public static final String ASSET_ALREADY_EXISTS_MESSAGE = "already exists"; 7 | public static final String ASSET_NOT_FOUND_MESSAGE = "does not exist"; 8 | } 9 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.util; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.io.IOException; 9 | import java.util.List; 10 | 11 | @Component 12 | @RequiredArgsConstructor 13 | public class JsonUtil { 14 | 15 | private final ObjectMapper objectMapper; 16 | 17 | public List mapToListObject(byte[] data, Class t){ 18 | try { 19 | return objectMapper.readValue(data, new TypeReference>() {}); 20 | } catch (IOException ex) { 21 | throw new RuntimeException(ex); 22 | } 23 | } 24 | 25 | public T mapToObject(byte[] data, Class t){ 26 | try { 27 | return objectMapper.readValue(data, t); 28 | } catch (IOException ex) { 29 | throw new RuntimeException(ex); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /hlf-api/src/main/java/io/susimsek/springboothlfexample/util/TransactionUtil.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample.util; 2 | 3 | public final class TransactionUtil { 4 | public static final String GET_ALL_ASSETS = "GetAllAssets"; 5 | public static final String GET_ASSET_HISTORY = "GetAssetHistory"; 6 | public static final String CREATE_ASSET = "CreateAsset"; 7 | public static final String UPDATE_ASSET = "UpdateAsset"; 8 | public static final String DELETE_ASSET = "DeleteAsset"; 9 | } 10 | -------------------------------------------------------------------------------- /hlf-api/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | management.endpoint.health.probes.enabled=true 2 | management.health.livenessState.enabled=true 3 | management.health.readinessState.enabled=true 4 | management.endpoint.health.show-details=always 5 | 6 | server.error.include-message=always 7 | server.error.include-binding-errors=always 8 | server.error.include-exception=false 9 | server.error.include-stacktrace=never 10 | 11 | springdoc.swagger-ui.display-request-duration=true 12 | springdoc.swagger-ui.tags-sorter=alpha 13 | springdoc.swagger-ui.operations-sorter=alpha 14 | springdoc.swagger-ui.disable-swagger-default-url=false 15 | springdoc.swagger-ui.use-root-path=true 16 | 17 | hyperledger-fabric.wallet-path=wallet 18 | hyperledger-fabric.network-config=classpath:cp/connection-org1.json 19 | hyperledger-fabric.ca-client.admin-user-id=admin 20 | hyperledger-fabric.ca-client.admin-password=adminpw 21 | hyperledger-fabric.ca-client.ca-name=ca-org1 22 | hyperledger-fabric.gateway.ca-user.registration-enabled=true 23 | hyperledger-fabric.gateway.ca-user.user-id=tom1 24 | hyperledger-fabric.gateway.ca-user.org-msp=Org1MSP 25 | hyperledger-fabric.gateway.ca-user.affiliation=org1.department1 26 | hyperledger-fabric.gateway.channel-name=mychannel 27 | hyperledger-fabric.gateway.chaincode-name=basic 28 | 29 | api-docs.title=Asset Transfer Rest API 30 | api-docs.description=Blockchain based Asset Transfer Rest API. 31 | api-docs.version=1.0.0 32 | api-docs.terms-of-service-url=http://swagger.io/terms/ 33 | api-docs.license=Apache 2.0 34 | api-docs.license-url=http://springdoc.org 35 | 36 | cors.allowed-origins=http://hlf-k8.tk 37 | cors.allowed-methods=GET,PUT,POST,PATCH,DELETE,OPTIONS 38 | cors.allowed-headers=* 39 | cors.allow-credentials=true 40 | cors.max-age=3600 -------------------------------------------------------------------------------- /hlf-api/src/main/resources/cp/connection-org1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-network-org1", 3 | "version": "1.0.0", 4 | "client": { 5 | "organization": "Org1", 6 | "connection": { 7 | "timeout": { 8 | "peer": { 9 | "endorser": "300" 10 | }, 11 | "orderer": "300" 12 | } 13 | } 14 | }, 15 | 16 | "organizations": { 17 | "Org1": { 18 | "mspid": "Org1MSP", 19 | "peers": [ 20 | "peer0-org1" 21 | ], 22 | "certificateAuthorities": [ 23 | "ca-org1" 24 | ] 25 | } 26 | }, 27 | "peers": { 28 | "peer0-org1": { 29 | "url": "grpcs://localhost:7051", 30 | "tlsCACerts": { 31 | "pem": "-----BEGIN CERTIFICATE-----\nMIICGDCCAb+gAwIBAgIUe8WxZ7rAi0uR3YGJVHqL6kjPDNwwCgYIKoZIzj0EAwIw\naTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcg\nWW9yazEQMA4GA1UEChMHY2Etb3JnMTEQMA4GA1UECxMHY2Etb3JnMTEQMA4GA1UE\nAxMHY2Etb3JnMTAeFw0yMTEwMTcxMDQ4MDBaFw0zNjEwMTMxMDQ4MDBaMGkxCzAJ\nBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazERMA8GA1UEBxMITmV3IFlvcmsx\nEDAOBgNVBAoTB2NhLW9yZzExEDAOBgNVBAsTB2NhLW9yZzExEDAOBgNVBAMTB2Nh\nLW9yZzEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARNdZV6TqH/elDw3PtASVxW\nyYqnaoVtgg7jhbSmylUAstr4DhV3Mi+bl30T6hrKFLetsTfKnpooCzW7Xn4SBd6J\no0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4E\nFgQUPMrAEAPVzCmgq59V+6iwd3rIm7EwCgYIKoZIzj0EAwIDRwAwRAIgQD45ka+i\nOigW8AA/ZRo7JaIFJfuOXxs8Kf2TbMbttFgCIFhbKcz/RMeO2PBGxH2lOS7pFhkI\n4NLCosMsNtAwsVLk\n-----END CERTIFICATE-----\n" 32 | }, 33 | "grpcOptions": { 34 | "ssl-target-name-override": "peer0-org1", 35 | "hostnameOverride": "peer0-org1" 36 | } 37 | } 38 | }, 39 | "certificateAuthorities": { 40 | "ca-org1": { 41 | "url": "https://localhost:7054", 42 | "caName": "ca-org1", 43 | "tlsCACerts": { 44 | "pem": ["-----BEGIN CERTIFICATE-----\nMIICGDCCAb+gAwIBAgIUe8WxZ7rAi0uR3YGJVHqL6kjPDNwwCgYIKoZIzj0EAwIw\naTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcg\nWW9yazEQMA4GA1UEChMHY2Etb3JnMTEQMA4GA1UECxMHY2Etb3JnMTEQMA4GA1UE\nAxMHY2Etb3JnMTAeFw0yMTEwMTcxMDQ4MDBaFw0zNjEwMTMxMDQ4MDBaMGkxCzAJ\nBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazERMA8GA1UEBxMITmV3IFlvcmsx\nEDAOBgNVBAoTB2NhLW9yZzExEDAOBgNVBAsTB2NhLW9yZzExEDAOBgNVBAMTB2Nh\nLW9yZzEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARNdZV6TqH/elDw3PtASVxW\nyYqnaoVtgg7jhbSmylUAstr4DhV3Mi+bl30T6hrKFLetsTfKnpooCzW7Xn4SBd6J\no0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4E\nFgQUPMrAEAPVzCmgq59V+6iwd3rIm7EwCgYIKoZIzj0EAwIDRwAwRAIgQD45ka+i\nOigW8AA/ZRo7JaIFJfuOXxs8Kf2TbMbttFgCIFhbKcz/RMeO2PBGxH2lOS7pFhkI\n4NLCosMsNtAwsVLk\n-----END CERTIFICATE-----\n"] 45 | }, 46 | "httpOptions": { 47 | "verify": false 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /hlf-api/src/test/java/io/susimsek/springboothlfexample/SpringBootHlfExampleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package io.susimsek.springboothlfexample; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringBootHlfExampleApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /images/backend1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/backend1.png -------------------------------------------------------------------------------- /images/backend2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/backend2.png -------------------------------------------------------------------------------- /images/backend3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/backend3.png -------------------------------------------------------------------------------- /images/backend4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/backend4.png -------------------------------------------------------------------------------- /images/backend5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/backend5.png -------------------------------------------------------------------------------- /images/explorer1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/explorer1.png -------------------------------------------------------------------------------- /images/explorer2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/explorer2.png -------------------------------------------------------------------------------- /images/explorer3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/explorer3.png -------------------------------------------------------------------------------- /images/explorer4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/explorer4.png -------------------------------------------------------------------------------- /images/explorer5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/explorer5.png -------------------------------------------------------------------------------- /images/frontend1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/frontend1.png -------------------------------------------------------------------------------- /images/frontend2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/frontend2.png -------------------------------------------------------------------------------- /images/frontend3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/frontend3.png -------------------------------------------------------------------------------- /images/frontend4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/frontend4.png -------------------------------------------------------------------------------- /images/grafana1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/grafana1.png -------------------------------------------------------------------------------- /images/grafana2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/grafana2.png -------------------------------------------------------------------------------- /images/grafana3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/grafana3.png -------------------------------------------------------------------------------- /images/spring-boot-hlf-k8s-fullstack-blockchain-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/spring-boot-hlf-k8s-fullstack-blockchain-app.png -------------------------------------------------------------------------------- /images/used-technologies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/used-technologies.png -------------------------------------------------------------------------------- /images/vagrant-k8s-installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susimsek/spring-boot-hlf-k8s-fullstack-blockchain-app/29e21a13fb90749da834014b6e0766a004ffef04/images/vagrant-k8s-installation.png --------------------------------------------------------------------------------