├── .github └── workflows │ └── maven.yml ├── .gitignore ├── README.md ├── fabric-network-builder-bbe ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── ecsoya │ │ └── fabric │ │ └── builder │ │ ├── BbeNetworkBuilder.java │ │ ├── BbeNetworkBuilderException.java │ │ ├── BbeNetworkGenerator.java │ │ └── BbeNetworkTest.java │ └── resources │ ├── bbe │ ├── README.md │ ├── org-orderer │ │ └── .gitkeep │ ├── org1 │ │ └── .gitkeep │ └── org2 │ │ └── .gitkeep │ └── network │ └── .gitkeep ├── fabric-network-builder-local ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── ecsoya │ │ └── fabric │ │ └── builder │ │ ├── NetworkBuilder.java │ │ ├── NetworkBuilderException.java │ │ ├── NetworkGenerator.java │ │ └── NetworkTest.java │ └── resources │ ├── crypto-config │ └── .gitkeep │ └── network │ └── .gitkeep └── pom.xml /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Set up JDK 1.8 13 | uses: actions/setup-java@v1 14 | with: 15 | java-version: 1.8 16 | - name: Build with Maven 17 | run: mvn -B package --file pom.xml 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | dependency-reduced-pom.xml 8 | buildNumber.properties 9 | .mvn/timing.properties 10 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 11 | .mvn/wrapper/maven-wrapper.jar 12 | .settings/ 13 | .classpath 14 | .project 15 | .DS_Store 16 | *.idea/ 17 | *.iml 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fabric Network Builder 2 | 3 | Build fabric network config file(*.yml) for Fabric Java SDK or Fabric Gateway Java. 4 | 5 | -------------------------------------------------------------------------------- /fabric-network-builder-bbe/README.md: -------------------------------------------------------------------------------- 1 | #fabric-network-builder-bbe 2 | 3 | Builder yml for fabric network, which can be loaded by `org.hyperledger.fabric.sdk.NetworkConfig` 4 | 5 | How to use: 6 | 7 | 1. Download fabric network `crypto 网络证书` from BBE, and unzip to `src/main/resources/bbe`. 8 | 9 | 2. Config organiztion, peer and IP address in `BbeNetworkGenerator`. 10 | 11 | 3. Run the `BbeNetworkGenerator`, and you'll get the fabric network config file from `src/main/resources/network`. 12 | 13 | 4. Run `BbeNetworkTest` to test it. -------------------------------------------------------------------------------- /fabric-network-builder-bbe/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | io.github.ecsoya 5 | fabric-network-builder 6 | 1.0.0-SNAPSHOT 7 | 8 | fabric-network-builder-bbe 9 | fabric-network-builder-bbe 10 | Fabric network builder for BBE (Baidu Blockchain Engine) 11 | -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/java/org/ecsoya/fabric/builder/BbeNetworkBuilder.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.IntStream; 11 | 12 | import org.hyperledger.fabric.sdk.NetworkConfig; 13 | 14 | import com.google.gson.JsonArray; 15 | import com.google.gson.JsonObject; 16 | 17 | /** 18 | * 19 | * Build a yml file of fabric network, which can be loaded by 20 | * {@link NetworkConfig}. 21 | * 22 | * @author ecsoya 23 | * 24 | */ 25 | public class BbeNetworkBuilder { 26 | 27 | private String name; 28 | 29 | private String[] orgs; 30 | 31 | private int peers = 4; 32 | 33 | private String channel; 34 | 35 | private boolean usePem = true; 36 | 37 | private Map> urls = new HashMap<>(); 38 | private Map> ports = new HashMap<>(); 39 | private File root; 40 | private String client; 41 | 42 | public BbeNetworkBuilder() { 43 | } 44 | 45 | public BbeNetworkBuilder root(File root) { 46 | this.root = root; 47 | return this; 48 | } 49 | 50 | public BbeNetworkBuilder name(String name) { 51 | this.name = name; 52 | return this; 53 | } 54 | 55 | public BbeNetworkBuilder usePem(boolean usePem) { 56 | this.usePem = usePem; 57 | return this; 58 | } 59 | 60 | public BbeNetworkBuilder url(String org, String peer, String url) { 61 | Map value = urls.get(org); 62 | if (value == null) { 63 | value = new HashMap<>(); 64 | urls.put(org, value); 65 | } 66 | if (peer == null) { 67 | peer = org; 68 | } 69 | value.put(peer, url); 70 | return this; 71 | } 72 | 73 | public BbeNetworkBuilder port(String org, String peer, int port) { 74 | Map value = ports.get(org); 75 | if (value == null) { 76 | value = new HashMap<>(); 77 | ports.put(org, value); 78 | } 79 | if (peer == null) { 80 | peer = org; 81 | } 82 | value.put(peer, port); 83 | return this; 84 | } 85 | 86 | public BbeNetworkBuilder orgs(String... orgs) { 87 | this.orgs = orgs; 88 | return this; 89 | } 90 | 91 | public BbeNetworkBuilder channel(String channel) { 92 | this.channel = channel; 93 | return this; 94 | } 95 | 96 | public BbeNetworkBuilder client(String client) { 97 | this.client = client; 98 | return this; 99 | } 100 | 101 | public JsonObject build() throws BbeNetworkBuilderException { 102 | if (name == null) { 103 | throw new BbeNetworkBuilderException("The network name is not specified."); 104 | } 105 | if (orgs == null) { 106 | throw new BbeNetworkBuilderException("The client organization is not specified."); 107 | } 108 | 109 | if (channel == null || channel.equals("")) { 110 | throw new BbeNetworkBuilderException("The network channels is not specified."); 111 | } 112 | 113 | if (root == null || !root.exists()) { 114 | throw new BbeNetworkBuilderException("The network root directory is not existed."); 115 | } 116 | JsonObject root = new JsonObject(); 117 | 118 | root.addProperty("name", name); 119 | root.addProperty("version", "1.0.0"); 120 | root.addProperty("x-type", "hlfv1"); 121 | 122 | // client 123 | JsonObject client = buildClient(); 124 | root.add("client", client); 125 | 126 | // channels 127 | JsonObject channels = buildChannels(); 128 | root.add("channels", channels); 129 | 130 | // organizations 131 | JsonObject organizations = buildOrganizations(); 132 | root.add("organizations", organizations); 133 | 134 | // orderers 135 | JsonObject orderers = buildOrderers(); 136 | root.add("orderers", orderers); 137 | 138 | // peers 139 | JsonObject peers = buildPeers(); 140 | root.add("peers", peers); 141 | 142 | // certificateAuthorities 143 | JsonObject certificateAuthorities = buildCertificateAuthorities(); 144 | root.add("certificateAuthorities", certificateAuthorities); 145 | return root; 146 | } 147 | 148 | private JsonObject buildCertificateAuthorities() throws BbeNetworkBuilderException { 149 | JsonObject root = new JsonObject(); 150 | 151 | for (String org : orgs) { 152 | JsonObject node = buildCertificateAuthorityNode(org); 153 | root.add("ca." + org, node); 154 | } 155 | 156 | return root; 157 | } 158 | 159 | private JsonObject buildCertificateAuthorityNode(String org) throws BbeNetworkBuilderException { 160 | JsonObject node = new JsonObject(); 161 | 162 | node.addProperty("url", "https://" + getUrl(org, null) + ":7054"); 163 | 164 | JsonObject grpcOptions = new JsonObject(); 165 | grpcOptions.addProperty("ssl-target-name-override", "ca." + org); 166 | grpcOptions.addProperty("allow-insecure", 0); 167 | grpcOptions.addProperty("trustServerCertificate", true); 168 | grpcOptions.addProperty("hostnameOverride", "ca." + org); 169 | node.add("grpcOptions", grpcOptions); 170 | 171 | JsonObject httpOptions = new JsonObject(); 172 | httpOptions.addProperty("verify", false); 173 | node.add("httpOptions", httpOptions); 174 | 175 | JsonArray registrar = new JsonArray(); 176 | 177 | JsonObject admin = new JsonObject(); 178 | admin.addProperty("enrollId", "admin"); 179 | admin.addProperty("enrollSecret", "adminpw"); 180 | registrar.add(admin); 181 | 182 | node.add("registrar", registrar); 183 | JsonObject tlsCACerts = new JsonObject(); 184 | if (!usePem) { 185 | tlsCACerts.addProperty("path", getCaCertPath(org)); 186 | } else { 187 | tlsCACerts.addProperty("pem", getCaCertPem(org)); 188 | } 189 | node.add("tlsCACerts", tlsCACerts); 190 | 191 | return node; 192 | } 193 | 194 | private String getUrl(String org, String peer) throws BbeNetworkBuilderException { 195 | Map value = urls.get(org); 196 | if (value == null || value.isEmpty()) { 197 | throw new BbeNetworkBuilderException("Unnable to find URL for org: " + org); 198 | } 199 | if (peer == null) { 200 | peer = "*"; 201 | } 202 | if (value.containsKey(peer)) { 203 | return value.get(peer); 204 | } else if (value.containsKey(org)) { 205 | return value.get(org); 206 | } else if (value.containsKey("*")) { 207 | return value.get("*"); 208 | } 209 | throw new BbeNetworkBuilderException("Unnable to find URL for peer: " + peer + " in org: " + org); 210 | } 211 | 212 | private Integer getPort(String org, String peer, int defaultValue) { 213 | Map value = ports.get(org); 214 | if (value == null) { 215 | return defaultValue; 216 | } 217 | if (peer == null) { 218 | peer = org; 219 | } 220 | if (value.containsKey(peer)) { 221 | return value.get(peer); 222 | } 223 | return defaultValue; 224 | } 225 | 226 | private List getPeers() { 227 | return IntStream.range(0, peers).mapToObj(i -> "peer" + i).collect(Collectors.toList()); 228 | } 229 | 230 | private JsonObject buildPeers() throws BbeNetworkBuilderException { 231 | JsonObject root = new JsonObject(); 232 | 233 | for (String org : orgs) { 234 | for (String p : getPeers()) { 235 | // String name = p + "." + org; 236 | String name = org + "-" + p; 237 | JsonObject node = new JsonObject(); 238 | node.addProperty("url", "grpcs://" + getUrl(org, p) + ":" + getPort("*", p, 7051)); 239 | // node.addProperty("eventUrl", "grpcs://" + getUrl(o, "*") + ":" + getPort("*", "event_" + p, 7053)); 240 | 241 | JsonObject grpcOptions = new JsonObject(); 242 | grpcOptions.addProperty("ssl-target-name-override", name); 243 | grpcOptions.addProperty("grpc.http2.keepalive_time", 15); 244 | grpcOptions.addProperty("request-timeout", 120001); 245 | // grpcOptions.addProperty("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000); 246 | grpcOptions.addProperty("hostnameOverride", name); 247 | node.add("grpcOptions", grpcOptions); 248 | 249 | JsonObject tlsCACerts = new JsonObject(); 250 | if (!usePem) { 251 | tlsCACerts.addProperty("path", getPeerCertPath(org, p)); 252 | } else { 253 | tlsCACerts.addProperty("pem", getPeerCertPem(org, p)); 254 | } 255 | node.add("tlsCACerts", tlsCACerts); 256 | root.add(name, node); 257 | } 258 | } 259 | return root; 260 | } 261 | 262 | private JsonObject buildOrderers() throws BbeNetworkBuilderException { 263 | JsonObject node = new JsonObject(); 264 | List allOrderers = getOrderers(); 265 | // allOrderers.add(0, ordererOrg); 266 | for (String org : allOrderers) { 267 | JsonObject orgNode = new JsonObject(); 268 | orgNode.addProperty("url", "grpcs://" + getUrl(org, null) + ":7050"); 269 | 270 | JsonObject grpcOptions = new JsonObject(); 271 | grpcOptions.addProperty("grpc-max-send-message-length", 15); 272 | grpcOptions.addProperty("grpc.keepalive_time_ms", 360000); 273 | grpcOptions.addProperty("grpc.keepalive_timeout_ms", 180000); 274 | grpcOptions.addProperty("hostnameOverride", org); 275 | orgNode.add("grpcOptions", grpcOptions); 276 | 277 | JsonObject tlsCACerts = new JsonObject(); 278 | if (!usePem) { 279 | tlsCACerts.addProperty("path", getOrdererCertPath(org)); 280 | } else { 281 | tlsCACerts.addProperty("pem", getOrdererCertPem(org)); 282 | } 283 | orgNode.add("tlsCACerts", tlsCACerts); 284 | node.add(org, orgNode); 285 | } 286 | return node; 287 | } 288 | 289 | private JsonObject buildOrganizations() throws BbeNetworkBuilderException { 290 | JsonObject node = new JsonObject(); 291 | // JsonObject ordererOrgNode = buildOrgNode(ordererOrg, 0); 292 | // node.add(ordererOrg, ordererOrgNode); 293 | 294 | for (int i = 0; i < orgs.length; i++) { 295 | String org = orgs[i]; 296 | JsonObject child = buildOrgNode(org, peers); 297 | node.add(org, child); 298 | } 299 | return node; 300 | } 301 | 302 | private JsonObject buildOrgNode(String org, int numOfPeers) throws BbeNetworkBuilderException { 303 | JsonObject ordererOrgNode = new JsonObject(); 304 | ordererOrgNode.addProperty("mspid", org + "MSP"); 305 | 306 | JsonArray certificateAuthorities = new JsonArray(); 307 | certificateAuthorities.add("ca." + org); 308 | ordererOrgNode.add("certificateAuthorities", certificateAuthorities); 309 | 310 | JsonObject adminPrivateKey = new JsonObject(); 311 | if (!usePem) { 312 | adminPrivateKey.addProperty("path", getAdminPrivateKeyPath(org)); 313 | } else { 314 | adminPrivateKey.addProperty("pem", getAdminPrivateKeyPem(org)); 315 | } 316 | ordererOrgNode.add("adminPrivateKey", adminPrivateKey); 317 | 318 | JsonObject signedCert = new JsonObject(); 319 | if (!usePem) { 320 | signedCert.addProperty("path", getAdminCertPath(org)); 321 | } else { 322 | signedCert.addProperty("pem", getAdminCertPem(org)); 323 | } 324 | ordererOrgNode.add("signedCert", signedCert); 325 | if (numOfPeers > 0) { 326 | JsonArray peers = new JsonArray(); 327 | for (int i = 0; i < numOfPeers; i++) { 328 | // peers.add("peer" + i + "." + org); 329 | peers.add(org + "-" + "peer" + i); 330 | } 331 | ordererOrgNode.add("peers", peers); 332 | } 333 | return ordererOrgNode; 334 | } 335 | 336 | private String getCaCertPath(String org) throws BbeNetworkBuilderException { 337 | return org + "/ca/ca." + org + "-cert.pem"; 338 | } 339 | 340 | private String getCaCertPem(String org) throws BbeNetworkBuilderException { 341 | File file = new File(root, getCaCertPath(org)); 342 | try { 343 | return new String(Files.readAllBytes(file.toPath())); 344 | } catch (IOException e) { 345 | // throw new NetworkBuilderException(e); 346 | return null; 347 | } 348 | } 349 | 350 | private String getOrdererCertPem(String org) throws BbeNetworkBuilderException { 351 | File file = new File(root, getOrdererCertPath(org)); 352 | try { 353 | return new String(Files.readAllBytes(file.toPath())); 354 | } catch (IOException e) { 355 | throw new BbeNetworkBuilderException(e); 356 | } 357 | } 358 | 359 | private String getOrdererCertPath(String org) { 360 | return "org-orderer/orderers/" + org + "/msp/tlscacerts/tlsca.org-orderer-cert.pem"; 361 | } 362 | 363 | private String getPeerCertPem(String org, String peer) throws BbeNetworkBuilderException { 364 | File file = new File(root, getPeerCertPath(org, peer)); 365 | try { 366 | return new String(Files.readAllBytes(file.toPath())); 367 | } catch (IOException e) { 368 | throw new BbeNetworkBuilderException(e); 369 | } 370 | } 371 | 372 | private String getPeerCertPath(String org, String peer) { 373 | return org + "/peers/" + peer + "/msp/tlscacerts/tlsca." + org + "-cert.pem"; 374 | } 375 | 376 | private String getAdminCertPem(String org) throws BbeNetworkBuilderException { 377 | File file = new File(root, getAdminCertPath(org)); 378 | 379 | try { 380 | return new String(Files.readAllBytes(file.toPath())); 381 | } catch (IOException e) { 382 | // throw new NetworkBuilderException(e); 383 | return null; 384 | } 385 | } 386 | 387 | private String getAdminCertPath(String org) { 388 | return org + "/users/Admin@" + org + "/msp/admincerts/Admin@" + org + "-cert.pem"; 389 | } 390 | 391 | private String getAdminPrivateKeyPem(String org) throws BbeNetworkBuilderException { 392 | File dir = new File(root, getAdminPrivateKeyPath(org)); 393 | if (!dir.exists()) { 394 | return null; 395 | // throw new NetworkBuilderException("Can not find private key for " + org); 396 | } 397 | File[] listFiles = dir.listFiles(); 398 | if (listFiles.length == 0) { 399 | return null; 400 | } 401 | File keyFile = listFiles[0]; 402 | try { 403 | return new String(Files.readAllBytes(keyFile.toPath())); 404 | } catch (IOException e) { 405 | throw new BbeNetworkBuilderException(e); 406 | } 407 | } 408 | 409 | private String getAdminPrivateKeyPath(String org) { 410 | return org + "/users/Admin@" + org + "/msp/keystore"; 411 | } 412 | 413 | private List getOrderers() { 414 | return IntStream.range(0, orgs.length).mapToObj(i -> "orderer" + i).collect(Collectors.toList()); 415 | } 416 | 417 | private JsonObject buildChannels() { 418 | JsonObject channelsNode = new JsonObject(); 419 | 420 | JsonObject node = new JsonObject(); 421 | // orderers 422 | JsonArray orderers = new JsonArray(); 423 | // orderers.add(ordererOrg ); 424 | for (String orderer : getOrderers()) { 425 | orderers.add(orderer); 426 | } 427 | node.add("orderers", orderers); 428 | 429 | // peers 430 | JsonObject peersNode = new JsonObject(); 431 | for (String org : orgs) { 432 | for (String peer : getPeers()) { 433 | 434 | JsonObject o = new JsonObject(); 435 | if (peer.equals("peer0")) { 436 | o.addProperty("endorsingPeer", true); 437 | o.addProperty("chaincodeQuery", true); 438 | o.addProperty("ledgerQuery", true); 439 | o.addProperty("eventSource", true); 440 | } else if (peer.equals("peer1")) { 441 | o.addProperty("endorsingPeer", false); 442 | o.addProperty("chaincodeQuery", true); 443 | o.addProperty("ledgerQuery", false); 444 | o.addProperty("eventSource", false); 445 | } else if (peer.equals("peer2")) { 446 | o.addProperty("endorsingPeer", false); 447 | o.addProperty("chaincodeQuery", false); 448 | o.addProperty("ledgerQuery", true); 449 | o.addProperty("eventSource", false); 450 | } else if (peer.equals("peer3")) { 451 | o.addProperty("endorsingPeer", false); 452 | o.addProperty("chaincodeQuery", false); 453 | o.addProperty("ledgerQuery", false); 454 | o.addProperty("eventSource", true); 455 | } 456 | // peersNode.add(peer + "." + org, o); 457 | peersNode.add(org + "-" + peer, o); 458 | } 459 | 460 | } 461 | node.add("peers", peersNode); 462 | 463 | // policies 464 | JsonObject policies = new JsonObject(); 465 | JsonObject queryChannelConfig = new JsonObject(); 466 | queryChannelConfig.addProperty("minResponses", 1); 467 | queryChannelConfig.addProperty("maxTargets", 1); 468 | 469 | JsonObject retryOpts = new JsonObject(); 470 | retryOpts.addProperty("attempts", 5); 471 | retryOpts.addProperty("initialBackoff", "500ms"); 472 | retryOpts.addProperty("maxBackoff", "5s"); 473 | retryOpts.addProperty("backoffFactor", "2.0"); 474 | queryChannelConfig.add("retryOpts", retryOpts); 475 | node.add("policies", policies); 476 | channelsNode.add(channel, node); 477 | 478 | return channelsNode; 479 | } 480 | 481 | private JsonObject buildClient() { 482 | JsonObject client = new JsonObject(); 483 | 484 | JsonObject logging = new JsonObject(); 485 | logging.addProperty("level", "debug"); 486 | client.add("logging", logging); 487 | 488 | JsonObject connection = new JsonObject(); 489 | JsonObject timeout = new JsonObject(); 490 | JsonObject peer = new JsonObject(); 491 | peer.addProperty("endorser", 30000); 492 | peer.addProperty("eventHub", 30000); 493 | peer.addProperty("eventReg", 30000); 494 | timeout.add("peer", peer); 495 | timeout.addProperty("orderer", 30000); 496 | 497 | connection.add("timeout", timeout); 498 | client.add("connection", connection); 499 | 500 | client.addProperty("organization", this.client); 501 | 502 | // JsonObject credentialStore = new JsonObject(); 503 | // credentialStore.addProperty("path", "tmp/hfc-kvs"); 504 | // 505 | // JsonObject cryptoStore = new JsonObject(); 506 | // cryptoStore.addProperty("path", "tmp/hfc-cvs"); 507 | // credentialStore.add("cryptoStore", cryptoStore); 508 | // 509 | // credentialStore.addProperty("wallet", "cellshop"); 510 | // client.add("credentialStore", credentialStore); 511 | return client; 512 | } 513 | 514 | } 515 | -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/java/org/ecsoya/fabric/builder/BbeNetworkBuilderException.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | public class BbeNetworkBuilderException extends Exception { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = -3303490998239593821L; 9 | 10 | public BbeNetworkBuilderException() { 11 | super(); 12 | } 13 | 14 | public BbeNetworkBuilderException(String message, Throwable cause, boolean enableSuppression, 15 | boolean writableStackTrace) { 16 | super(message, cause, enableSuppression, writableStackTrace); 17 | } 18 | 19 | public BbeNetworkBuilderException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | 23 | public BbeNetworkBuilderException(String message) { 24 | super(message); 25 | } 26 | 27 | public BbeNetworkBuilderException(Throwable cause) { 28 | super(cause); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/java/org/ecsoya/fabric/builder/BbeNetworkGenerator.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.nio.file.StandardOpenOption; 7 | 8 | import org.hyperledger.fabric.sdk.NetworkConfig; 9 | import org.yaml.snakeyaml.Yaml; 10 | 11 | import com.google.gson.Gson; 12 | import com.google.gson.JsonObject; 13 | 14 | /** 15 | * Build a yml file of fabric network, which can be loaded by {@link NetworkConfig}. 16 | * 17 | * @author ecsoya 18 | * 19 | */ 20 | public class BbeNetworkGenerator { 21 | 22 | public static void main(String[] args) { 23 | String[] clients = { "org1", "org2" }; 24 | File root = new File("src/main/resources/bbe/"); 25 | try { 26 | for (String client : clients) { 27 | JsonObject json = new BbeNetworkBuilder() 28 | // Name of fabric network 29 | .name("example-fabric") 30 | // Current client 31 | .client(client) 32 | // All orgs: org1, org2... 33 | .orgs(clients) 34 | // Channel 35 | .channel("common") 36 | 37 | // Root Directory of crypto files. 38 | .root(root) 39 | 40 | // IP address binding for peer of orgs, '*' means all peers of a org. 41 | 42 | // org1 ip address 43 | .url("org1", "*", "106.13.184.40") 44 | 45 | // org2 ip address 46 | .url("org2", "*", "106.13.171.253") 47 | 48 | // orderers ip address 49 | .url("orderer0", null, "106.13.184.40") 50 | .url("orderer", null, "106.13.184.40") 51 | .url("orderer1", null, "106.13.171.253") 52 | 53 | // peers ip address for org2 54 | .url("org2", "peer0", "106.13.181.5") 55 | .url("org2", "peer1", "106.13.172.33") 56 | .url("org2", "peer2", "106.12.3.91") 57 | .url("org2", "peer3", "106.13.164.160") 58 | 59 | // peers ip address for org1 60 | .url("org1", "peer0", "106.13.161.205") 61 | .url("org1", "peer1", "106.12.47.80") 62 | .url("org1", "peer2", "106.13.172.79") 63 | .url("org1", "peer3", "106.12.95.182") 64 | 65 | // bind port to peers, default is 7051 for all peers and 7050 for all orderers. 66 | // .port("org1", "peer1", 7051) 67 | 68 | // Build to JSON. 69 | .build(); 70 | 71 | Gson gson = new Gson(); 72 | String value = gson.toJson(json); 73 | 74 | // Write the network config file to yml. 75 | Yaml yaml = new Yaml(); 76 | Object map = yaml.load(value); 77 | String yvalue = yaml.dump(map); 78 | 79 | // Output 80 | File file = new File(new File("src/main/resources/network/"), "connection-" + client + ".yml"); 81 | if (!file.exists()) { 82 | Files.write(file.toPath(), yvalue.getBytes(), StandardOpenOption.CREATE_NEW, 83 | StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE); 84 | } else { 85 | Files.write(file.toPath(), yvalue.getBytes(), StandardOpenOption.TRUNCATE_EXISTING, 86 | StandardOpenOption.WRITE); 87 | } 88 | 89 | } 90 | } catch (BbeNetworkBuilderException e) { 91 | e.printStackTrace(); 92 | } catch (IOException e) { 93 | e.printStackTrace(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/java/org/ecsoya/fabric/builder/BbeNetworkTest.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.hyperledger.fabric.sdk.NetworkConfig; 7 | import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; 8 | import org.hyperledger.fabric.sdk.exception.NetworkConfigurationException; 9 | 10 | public class BbeNetworkTest { 11 | 12 | public static void main(String[] args) { 13 | File file = new File("src/main/resources/network/connection-org1.yml"); 14 | 15 | try { 16 | NetworkConfig network = NetworkConfig.fromYamlFile(file); 17 | System.out.println(network); 18 | } catch (InvalidArgumentException e) { 19 | e.printStackTrace(); 20 | } catch (NetworkConfigurationException e) { 21 | e.printStackTrace(); 22 | } catch (IOException e) { 23 | e.printStackTrace(); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/resources/bbe/README.md: -------------------------------------------------------------------------------- 1 | Download BBE cropto files to here. -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/resources/bbe/org-orderer/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecsoya/fabric-network-builder/85f05e83817656ea63c8a74d5e81c3bcb777dc76/fabric-network-builder-bbe/src/main/resources/bbe/org-orderer/.gitkeep -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/resources/bbe/org1/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecsoya/fabric-network-builder/85f05e83817656ea63c8a74d5e81c3bcb777dc76/fabric-network-builder-bbe/src/main/resources/bbe/org1/.gitkeep -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/resources/bbe/org2/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecsoya/fabric-network-builder/85f05e83817656ea63c8a74d5e81c3bcb777dc76/fabric-network-builder-bbe/src/main/resources/bbe/org2/.gitkeep -------------------------------------------------------------------------------- /fabric-network-builder-bbe/src/main/resources/network/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecsoya/fabric-network-builder/85f05e83817656ea63c8a74d5e81c3bcb777dc76/fabric-network-builder-bbe/src/main/resources/network/.gitkeep -------------------------------------------------------------------------------- /fabric-network-builder-local/README.md: -------------------------------------------------------------------------------- 1 | #fabric-network-builder-local 2 | 3 | Builder yml for fabric network, which can be loaded by `org.hyperledger.fabric.sdk.NetworkConfig` 4 | 5 | How to use: 6 | 7 | 1. Copy fabric network `crypto-config` to `src/main/resources/crypto-config`. 8 | 9 | 2. Config organiztion, peer and IP address in `NetworkGenerator`. 10 | 11 | 3. Run the `NetworkGenerator`, and you'll get the fabric network config file from `src/main/resources/network`. 12 | 13 | 4. Run `NetworkTest` to test it. 14 | 15 | 16 | ### 中文使用 17 | 18 | 1. 将fabric网络的`证书文件`拷贝到`resource`目录下。 19 | 2. 在`NetworkGenerator`中配置`组织`、`peer`的IP地址。 20 | 3. 运行`NetworkGenerator`,生成fabric的网络连接文件`connection-*.yml`。 21 | 4. 通过`NetworkTest`测试。 22 | 23 | -------------------------------------------------------------------------------- /fabric-network-builder-local/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | io.github.ecsoya 5 | fabric-network-builder 6 | 1.0.0-SNAPSHOT 7 | 8 | fabric-network-builder-local 9 | fabric-network-builder-local 10 | Localhost fabric network builder 11 | -------------------------------------------------------------------------------- /fabric-network-builder-local/src/main/java/org/ecsoya/fabric/builder/NetworkBuilder.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import com.google.gson.JsonArray; 13 | import com.google.gson.JsonObject; 14 | 15 | public class NetworkBuilder { 16 | 17 | private String domain; 18 | 19 | private String name; 20 | 21 | private String clientOrg; 22 | 23 | private String ordererOrg; 24 | 25 | private String[] orderers; 26 | 27 | private String[] peerOrgs; 28 | 29 | private String[] peers; 30 | 31 | private String[] channels; 32 | 33 | private Map> urls = new HashMap<>(); 34 | private Map> ports = new HashMap<>(); 35 | private File root; 36 | 37 | public NetworkBuilder(String domain) { 38 | this.domain = domain; 39 | } 40 | 41 | public NetworkBuilder root(File root) { 42 | this.root = root; 43 | return this; 44 | } 45 | 46 | public NetworkBuilder name(String name) { 47 | this.name = name; 48 | return this; 49 | } 50 | 51 | public NetworkBuilder url(String org, String peer, String url) { 52 | Map value = urls.get(org); 53 | if (value == null) { 54 | value = new HashMap<>(); 55 | urls.put(org, value); 56 | } 57 | if (peer == null) { 58 | peer = org; 59 | } 60 | value.put(peer, url); 61 | return this; 62 | } 63 | 64 | public NetworkBuilder port(String org, String peer, int port) { 65 | Map value = ports.get(org); 66 | if (value == null) { 67 | value = new HashMap<>(); 68 | ports.put(org, value); 69 | } 70 | if (peer == null) { 71 | peer = org; 72 | } 73 | value.put(peer, port); 74 | return this; 75 | } 76 | 77 | public NetworkBuilder clientOrg(String clientOrg) { 78 | this.clientOrg = clientOrg; 79 | return this; 80 | } 81 | 82 | public NetworkBuilder ordererOrg(String ordererOrg) { 83 | this.ordererOrg = ordererOrg; 84 | return this; 85 | } 86 | 87 | public NetworkBuilder peerOrgs(String... peerOrgs) { 88 | this.peerOrgs = peerOrgs; 89 | return this; 90 | } 91 | 92 | public NetworkBuilder orderers(String... orderers) { 93 | this.orderers = orderers; 94 | return this; 95 | } 96 | 97 | public NetworkBuilder peers(String... peers) { 98 | this.peers = peers; 99 | return this; 100 | } 101 | 102 | public NetworkBuilder channels(String... channels) { 103 | this.channels = channels; 104 | return this; 105 | } 106 | 107 | public JsonObject build() throws NetworkBuilderException { 108 | if (name == null) { 109 | throw new NetworkBuilderException("The network name is not specified."); 110 | } 111 | if (ordererOrg == null) { 112 | throw new NetworkBuilderException("The network ordererOrg is not specified."); 113 | } 114 | if (clientOrg == null) { 115 | throw new NetworkBuilderException("The client organization is not specified."); 116 | } 117 | 118 | if (channels == null || channels.length == 0) { 119 | throw new NetworkBuilderException("The network channels is not specified."); 120 | } 121 | 122 | if (peerOrgs == null || peerOrgs.length == 0) { 123 | throw new NetworkBuilderException("The network peerOrgs is not specified."); 124 | } 125 | 126 | if (peers == null || peers.length == 0) { 127 | throw new NetworkBuilderException("The network peers is not specified."); 128 | } 129 | if (orderers == null || orderers.length == 0) { 130 | throw new NetworkBuilderException("The network orderers is not specified."); 131 | } 132 | 133 | if (root == null || !root.exists()) { 134 | throw new NetworkBuilderException("The network root directory is not existed."); 135 | } 136 | JsonObject root = new JsonObject(); 137 | 138 | root.addProperty("name", name); 139 | root.addProperty("version", "1.0.0"); 140 | root.addProperty("x-type", "hlfv1"); 141 | 142 | // client 143 | JsonObject client = buildClient(); 144 | root.add("client", client); 145 | 146 | // channels 147 | JsonObject channels = buildChannels(); 148 | root.add("channels", channels); 149 | 150 | // organizations 151 | JsonObject organizations = buildOrganizations(); 152 | root.add("organizations", organizations); 153 | 154 | // orderers 155 | JsonObject orderers = buildOrderers(); 156 | root.add("orderers", orderers); 157 | 158 | // peers 159 | JsonObject peers = buildPeers(); 160 | root.add("peers", peers); 161 | 162 | // certificateAuthorities 163 | JsonObject certificateAuthorities = buildCertificateAuthorities(); 164 | root.add("certificateAuthorities", certificateAuthorities); 165 | return root; 166 | } 167 | 168 | private JsonObject buildCertificateAuthorities() throws NetworkBuilderException { 169 | JsonObject root = new JsonObject(); 170 | 171 | // JsonObject caroot = buildCertificateAuthorityNode(ordererOrg); 172 | // root.add("ca." + ordererOrg + "." + domain, caroot); 173 | 174 | for (String org : peerOrgs) { 175 | JsonObject node = buildCertificateAuthorityNode(org); 176 | root.add("ca." + org + "." + domain, node); 177 | } 178 | 179 | return root; 180 | } 181 | 182 | private JsonObject buildCertificateAuthorityNode(String org) throws NetworkBuilderException { 183 | JsonObject node = new JsonObject(); 184 | node.addProperty("caName", "ca-" + org); 185 | node.addProperty("url", "https://" + getUrl(org, null) + ":7054"); 186 | 187 | JsonObject grpcOptions = new JsonObject(); 188 | grpcOptions.addProperty("ssl-target-name-override", "ca." + org + "." + domain); 189 | grpcOptions.addProperty("allow-insecure", 0); 190 | grpcOptions.addProperty("trustServerCertificate", true); 191 | grpcOptions.addProperty("hostnameOverride", "ca." + org + "." + domain); 192 | node.add("grpcOptions", grpcOptions); 193 | 194 | JsonObject httpOptions = new JsonObject(); 195 | httpOptions.addProperty("verify", false); 196 | node.add("httpOptions", httpOptions); 197 | 198 | JsonArray registrar = new JsonArray(); 199 | 200 | JsonObject admin = new JsonObject(); 201 | admin.addProperty("enrollId", "admin"); 202 | admin.addProperty("enrollSecret", "adminpw"); 203 | registrar.add(admin); 204 | 205 | node.add("registrar", registrar); 206 | JsonObject tlsCACerts = new JsonObject(); 207 | // tlsCACerts.addProperty("path", getCaCertPath(org)); 208 | tlsCACerts.addProperty("pem", getCaCertPem(org)); 209 | node.add("tlsCACerts", tlsCACerts); 210 | 211 | return node; 212 | } 213 | 214 | private String getUrl(String org, String peer) throws NetworkBuilderException { 215 | Map value = urls.get(org); 216 | if (value == null || value.isEmpty()) { 217 | throw new NetworkBuilderException("Unnable to find URL for org: " + org); 218 | } 219 | if (peer == null) { 220 | peer = "*"; 221 | } 222 | if (value.containsKey(peer)) { 223 | return value.get(peer); 224 | } else if (value.containsKey(org)) { 225 | return value.get(org); 226 | } else if (value.containsKey("*")) { 227 | return value.get("*"); 228 | } 229 | throw new NetworkBuilderException("Unnable to find URL for peer: " + peer + " in org: " + org); 230 | } 231 | 232 | private Integer getPort(String org, String peer, int defaultValue) { 233 | Map value = ports.get(org); 234 | if (value == null) { 235 | return defaultValue; 236 | } 237 | if (peer == null) { 238 | peer = org; 239 | } 240 | if (value.containsKey(peer)) { 241 | return value.get(peer); 242 | } 243 | return defaultValue; 244 | } 245 | 246 | private JsonObject buildPeers() throws NetworkBuilderException { 247 | JsonObject root = new JsonObject(); 248 | 249 | for (String o : peerOrgs) { 250 | for (String p : peers) { 251 | String name = p + "." + o + "." + domain; 252 | JsonObject node = new JsonObject(); 253 | node.addProperty("url", "grpcs://" + getUrl(o, "*") + ":" + getPort(o, p, 7051)); 254 | // node.addProperty("eventUrl", "grpcs://" + getUrl(o, "*") + ":" + getPort("*", "event_" + p, 7053)); 255 | 256 | JsonObject grpcOptions = new JsonObject(); 257 | grpcOptions.addProperty("ssl-target-name-override", name); 258 | grpcOptions.addProperty("grpc.http2.keepalive_time", 15); 259 | grpcOptions.addProperty("request-timeout", 120001); 260 | // grpcOptions.addProperty("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000); 261 | grpcOptions.addProperty("hostnameOverride", name); 262 | node.add("grpcOptions", grpcOptions); 263 | 264 | JsonObject tlsCACerts = new JsonObject(); 265 | // tlsCACerts.addProperty("path", getPeerCertPath(o, p)); 266 | tlsCACerts.addProperty("pem", getPeerCertPem(o, p)); 267 | node.add("tlsCACerts", tlsCACerts); 268 | root.add(name, node); 269 | } 270 | } 271 | return root; 272 | } 273 | 274 | private JsonObject buildOrderers() throws NetworkBuilderException { 275 | JsonObject node = new JsonObject(); 276 | List allOrderers = new ArrayList<>(Arrays.asList(orderers)); 277 | // allOrderers.add(0, ordererOrg); 278 | for (String org : allOrderers) { 279 | JsonObject orgNode = new JsonObject(); 280 | orgNode.addProperty("url", "grpcs://" + getUrl(org, null) + ":7050"); 281 | 282 | JsonObject grpcOptions = new JsonObject(); 283 | grpcOptions.addProperty("grpc-max-send-message-length", 15); 284 | grpcOptions.addProperty("grpc.keepalive_time_ms", 360000); 285 | grpcOptions.addProperty("grpc.keepalive_timeout_ms", 180000); 286 | grpcOptions.addProperty("hostnameOverride", org + "." + domain); 287 | orgNode.add("grpcOptions", grpcOptions); 288 | 289 | JsonObject tlsCACerts = new JsonObject(); 290 | // tlsCACerts.addProperty("path", getOrdererCertPath(org)); 291 | tlsCACerts.addProperty("pem", getOrdererCertPem(org)); 292 | orgNode.add("tlsCACerts", tlsCACerts); 293 | node.add(org + "." + domain, orgNode); 294 | } 295 | return node; 296 | } 297 | 298 | private JsonObject buildOrganizations() throws NetworkBuilderException { 299 | JsonObject node = new JsonObject(); 300 | // JsonObject ordererOrgNode = buildOrgNode(ordererOrg, 0); 301 | // node.add(ordererOrg, ordererOrgNode); 302 | 303 | for (String org : peerOrgs) { 304 | JsonObject child = buildOrgNode(org, peers.length); 305 | node.add(org, child); 306 | } 307 | return node; 308 | } 309 | 310 | private JsonObject buildOrgNode(String org, int numOfPeers) throws NetworkBuilderException { 311 | JsonObject ordererOrgNode = new JsonObject(); 312 | ordererOrgNode.addProperty("mspid", org + "MSP"); 313 | 314 | JsonArray certificateAuthorities = new JsonArray(); 315 | certificateAuthorities.add("ca." + org + "." + domain); 316 | ordererOrgNode.add("certificateAuthorities", certificateAuthorities); 317 | 318 | JsonObject adminPrivateKey = new JsonObject(); 319 | // adminPrivateKey.addProperty("path", getAdminPrivateKeyPath(org)); 320 | adminPrivateKey.addProperty("pem", getAdminPrivateKeyPem(org)); 321 | ordererOrgNode.add("adminPrivateKey", adminPrivateKey); 322 | 323 | JsonObject signedCert = new JsonObject(); 324 | // signedCert.addProperty("path", getAdminCertPath(org)); 325 | signedCert.addProperty("pem", getAdminCertPem(org)); 326 | ordererOrgNode.add("signedCert", signedCert); 327 | if (numOfPeers > 0) { 328 | JsonArray peers = new JsonArray(); 329 | for (int i = 0; i < numOfPeers; i++) { 330 | peers.add("peer" + i + "." + org + "." + domain); 331 | } 332 | ordererOrgNode.add("peers", peers); 333 | } 334 | return ordererOrgNode; 335 | } 336 | 337 | private String getCaCertPem(String org) throws NetworkBuilderException { 338 | File file = new File(root, 339 | "peerOrganizations/" + org + "." + domain + "/ca/ca." + org + "." + domain + "-cert.pem"); 340 | try { 341 | return new String(Files.readAllBytes(file.toPath())); 342 | } catch (IOException e) { 343 | // throw new NetworkBuilderException(e); 344 | return null; 345 | } 346 | } 347 | 348 | private String getOrdererCertPem(String org) throws NetworkBuilderException { 349 | File file = new File(root, "ordererOrganizations/" + domain + "/orderers/" + org + "." + domain 350 | + "/msp/tlscacerts/tlsca." + domain + "-cert.pem"); 351 | try { 352 | return new String(Files.readAllBytes(file.toPath())); 353 | } catch (IOException e) { 354 | throw new NetworkBuilderException(e); 355 | } 356 | } 357 | 358 | private String getPeerCertPem(String org, String peer) throws NetworkBuilderException { 359 | File file = new File(root, "peerOrganizations/" + org + "." + domain + "/peers/" + peer + "." + org + "." 360 | + domain + "/msp/tlscacerts/tlsca." + org + "." + domain + "-cert.pem"); 361 | try { 362 | return new String(Files.readAllBytes(file.toPath())); 363 | } catch (IOException e) { 364 | throw new NetworkBuilderException(e); 365 | } 366 | } 367 | 368 | private File getAdminCertPath(String org) throws NetworkBuilderException { 369 | File file = null; 370 | if (org.equals(ordererOrg)) { 371 | file = new File(root, "ordererOrganizations/" + domain + "/" + "users/Admin@" + domain 372 | + "/msp/admincerts/Admin@" + domain + "-cert.pem"); 373 | 374 | } else { 375 | file = new File(root, "peerOrganizations/" + org + "." + domain + "/users/Admin@" + org + "." + domain 376 | + "/msp/admincerts/Admin@" + org + "." + domain + "-cert.pem"); 377 | } 378 | if (!file.exists()) { 379 | if (org.equals(ordererOrg)) { 380 | file = new File(root, "ordererOrganizations/" + domain + "/" + "users/Admin@" + domain 381 | + "/msp/signcerts/Admin@" + domain + "-cert.pem"); 382 | 383 | } else { 384 | file = new File(root, "peerOrganizations/" + org + "." + domain + "/users/Admin@" + org + "." + domain 385 | + "/msp/signcerts/Admin@" + org + "." + domain + "-cert.pem"); 386 | } 387 | } 388 | 389 | return file; 390 | } 391 | 392 | private String getAdminCertPem(String org) throws NetworkBuilderException { 393 | File file = getAdminCertPath(org); 394 | if (!file.exists()) { 395 | return null; 396 | } 397 | try { 398 | return new String(Files.readAllBytes(file.toPath())); 399 | } catch (IOException e) { 400 | // throw new NetworkBuilderException(e); 401 | return null; 402 | } 403 | } 404 | 405 | private String getAdminPrivateKeyPem(String org) throws NetworkBuilderException { 406 | File dir = null; 407 | if (org.equals(ordererOrg)) { 408 | dir = new File(root, "ordererOrganizations/" + domain + "/" + "users/Admin@" + domain + "/msp/keystore"); 409 | } else { 410 | dir = new File(root, 411 | "peerOrganizations/" + org + "." + domain + "/users/Admin@" + org + "." + domain + "/msp/keystore"); 412 | } 413 | 414 | if (!dir.exists()) { 415 | return null; 416 | // throw new NetworkBuilderException("Can not find private key for " + org); 417 | } 418 | File[] listFiles = dir.listFiles(); 419 | if (listFiles.length == 0) { 420 | return null; 421 | } 422 | File keyFile = listFiles[0]; 423 | try { 424 | return new String(Files.readAllBytes(keyFile.toPath())); 425 | } catch (IOException e) { 426 | throw new NetworkBuilderException(e); 427 | } 428 | } 429 | 430 | private JsonObject buildChannels() { 431 | JsonObject channelsNode = new JsonObject(); 432 | 433 | for (String channel : channels) { 434 | JsonObject node = new JsonObject(); 435 | // orderers 436 | JsonArray orderers = new JsonArray(); 437 | // orderers.add(ordererOrg + "." + domain); 438 | for (String org : this.orderers) { 439 | orderers.add(org + "." + domain); 440 | } 441 | node.add("orderers", orderers); 442 | 443 | // peers 444 | JsonObject peersNode = new JsonObject(); 445 | for (String org : peerOrgs) { 446 | for (String peer : peers) { 447 | 448 | JsonObject o = new JsonObject(); 449 | if (peer.equals("peer0")) { 450 | o.addProperty("endorsingPeer", true); 451 | o.addProperty("chaincodeQuery", true); 452 | o.addProperty("ledgerQuery", true); 453 | o.addProperty("eventSource", true); 454 | } else { 455 | o.addProperty("endorsingPeer", false); 456 | o.addProperty("chaincodeQuery", true); 457 | o.addProperty("ledgerQuery", true); 458 | o.addProperty("eventSource", false); 459 | } 460 | peersNode.add(peer + "." + org + "." + domain, o); 461 | } 462 | 463 | } 464 | node.add("peers", peersNode); 465 | 466 | // policies 467 | JsonObject policies = new JsonObject(); 468 | JsonObject queryChannelConfig = new JsonObject(); 469 | queryChannelConfig.addProperty("minResponses", 1); 470 | queryChannelConfig.addProperty("maxTargets", 1); 471 | 472 | JsonObject retryOpts = new JsonObject(); 473 | retryOpts.addProperty("attempts", 5); 474 | retryOpts.addProperty("initialBackoff", "500ms"); 475 | retryOpts.addProperty("maxBackoff", "5s"); 476 | retryOpts.addProperty("backoffFactor", "2.0"); 477 | queryChannelConfig.add("retryOpts", retryOpts); 478 | node.add("policies", policies); 479 | channelsNode.add(channel, node); 480 | } 481 | 482 | return channelsNode; 483 | } 484 | 485 | private JsonObject buildClient() { 486 | JsonObject client = new JsonObject(); 487 | 488 | JsonObject logging = new JsonObject(); 489 | logging.addProperty("level", "debug"); 490 | client.add("logging", logging); 491 | 492 | JsonObject connection = new JsonObject(); 493 | JsonObject timeout = new JsonObject(); 494 | JsonObject peer = new JsonObject(); 495 | peer.addProperty("endorser", 30000); 496 | peer.addProperty("eventHub", 30000); 497 | peer.addProperty("eventReg", 30000); 498 | timeout.add("peer", peer); 499 | timeout.addProperty("orderer", 30000); 500 | 501 | connection.add("timeout", timeout); 502 | client.add("connection", connection); 503 | 504 | client.addProperty("organization", clientOrg); 505 | 506 | JsonObject credentialStore = new JsonObject(); 507 | credentialStore.addProperty("path", "tmp/hfc-kvs"); 508 | 509 | JsonObject cryptoStore = new JsonObject(); 510 | cryptoStore.addProperty("path", "tmp/hfc-cvs"); 511 | credentialStore.add("cryptoStore", cryptoStore); 512 | 513 | credentialStore.addProperty("wallet", "bts"); 514 | client.add("credentialStore", credentialStore); 515 | return client; 516 | } 517 | 518 | } 519 | -------------------------------------------------------------------------------- /fabric-network-builder-local/src/main/java/org/ecsoya/fabric/builder/NetworkBuilderException.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | public class NetworkBuilderException extends Exception { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = -3303490998239593821L; 9 | 10 | public NetworkBuilderException() { 11 | super(); 12 | } 13 | 14 | public NetworkBuilderException(String message, Throwable cause, boolean enableSuppression, 15 | boolean writableStackTrace) { 16 | super(message, cause, enableSuppression, writableStackTrace); 17 | } 18 | 19 | public NetworkBuilderException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | 23 | public NetworkBuilderException(String message) { 24 | super(message); 25 | } 26 | 27 | public NetworkBuilderException(Throwable cause) { 28 | super(cause); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /fabric-network-builder-local/src/main/java/org/ecsoya/fabric/builder/NetworkGenerator.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.nio.file.StandardOpenOption; 7 | 8 | import org.hyperledger.fabric.sdk.NetworkConfig; 9 | import org.yaml.snakeyaml.Yaml; 10 | 11 | import com.google.gson.Gson; 12 | import com.google.gson.JsonObject; 13 | 14 | /** 15 | * 16 | * Build a yml file of fabric network, which can be loaded by {@link NetworkConfig}. 17 | * 18 | * @author ecsoya 19 | * 20 | */ 21 | public class NetworkGenerator { 22 | 23 | public static void main(String[] args) { 24 | String domain = "example.com"; 25 | String[] clients = { "org1", "org2" }; 26 | 27 | for (int i = 0; i < clients.length; i++) { 28 | try { 29 | File root = new File("src/main/resources"); 30 | 31 | JsonObject json = new NetworkBuilder(domain). 32 | // Name of fabric network. 33 | name("example-fabric-network"). 34 | // Root organization name 35 | clientOrg(clients[i]) 36 | // Order org 37 | .ordererOrg("orderer") 38 | // All orderers: order1, order2... 39 | .orderers("orderer") 40 | // All orgs: org1, org2... 41 | .peerOrgs(clients) 42 | // All peers: peer0, peer1... 43 | .peers("peer0", "peer1") 44 | // Channel name 45 | .channels("common") 46 | 47 | // Root Directory of crypto files. 48 | .root(new File(root, "crypto-config")) 49 | 50 | // IP address binding for peer of orgs, '*' means all peers of a org. 51 | .url("org1", "*", "192.168.0.1").url("org2", "*", "192.168.0.1") 52 | .url("orderer", "*", "192.168.0.1") 53 | 54 | // Port binding for peer of orgs, '*' means all peers of a org. 55 | .port("org1", "peer0", 7051) 56 | .port("org1", "peer1", 8051) 57 | .port("org2", "peer0", 9051) 58 | .port("org2", "peer1", 10051) 59 | 60 | // Build to JSON. 61 | .build(); 62 | 63 | Gson gson = new Gson(); 64 | String value = gson.toJson(json); 65 | 66 | // Write the network config file to yml. 67 | Yaml yaml = new Yaml(); 68 | Object map = yaml.load(value); 69 | String yvalue = yaml.dump(map); 70 | 71 | // Output 72 | File file = new File(root, "network/connection-" + clients[i] + ".yml"); 73 | if (!file.exists()) { 74 | Files.write(file.toPath(), yvalue.getBytes(), StandardOpenOption.CREATE_NEW, 75 | StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE); 76 | } else { 77 | Files.write(file.toPath(), yvalue.getBytes(), StandardOpenOption.TRUNCATE_EXISTING, 78 | StandardOpenOption.WRITE); 79 | } 80 | 81 | } catch (NetworkBuilderException e) { 82 | e.printStackTrace(); 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /fabric-network-builder-local/src/main/java/org/ecsoya/fabric/builder/NetworkTest.java: -------------------------------------------------------------------------------- 1 | package org.ecsoya.fabric.builder; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.hyperledger.fabric.sdk.NetworkConfig; 7 | import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; 8 | import org.hyperledger.fabric.sdk.exception.NetworkConfigurationException; 9 | 10 | public class NetworkTest { 11 | 12 | public static void main(String[] args) { 13 | File file = new File("src/main/resources/network/connection-org1.yml"); 14 | 15 | try { 16 | NetworkConfig network = NetworkConfig.fromYamlFile(file); 17 | System.out.println(network); 18 | } catch (InvalidArgumentException e) { 19 | e.printStackTrace(); 20 | } catch (NetworkConfigurationException e) { 21 | e.printStackTrace(); 22 | } catch (IOException e) { 23 | e.printStackTrace(); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /fabric-network-builder-local/src/main/resources/crypto-config/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecsoya/fabric-network-builder/85f05e83817656ea63c8a74d5e81c3bcb777dc76/fabric-network-builder-local/src/main/resources/crypto-config/.gitkeep -------------------------------------------------------------------------------- /fabric-network-builder-local/src/main/resources/network/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecsoya/fabric-network-builder/85f05e83817656ea63c8a74d5e81c3bcb777dc76/fabric-network-builder-local/src/main/resources/network/.gitkeep -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | io.github.ecsoya 6 | fabric-network-builder 7 | 1.0.0-SNAPSHOT 8 | pom 9 | fabric-network-builder 10 | Builder for Fabric Networks 11 | 12 | 13 | 14 | 15 | 16 | com.google.code.gson 17 | gson 18 | 2.8.6 19 | 20 | 21 | 22 | 23 | org.yaml 24 | snakeyaml 25 | 1.25 26 | 27 | 28 | 29 | org.hyperledger.fabric 30 | fabric-gateway-java 31 | 1.4.2 32 | 33 | 34 | 35 | 36 | fabric-network-builder-local 37 | fabric-network-builder-bbe 38 | 39 | 40 | 41 | 42 | 43 | org.apache.maven.plugins 44 | maven-compiler-plugin 45 | 3.2 46 | 47 | 1.8 48 | 1.8 49 | UTF-8 50 | 51 | 52 | 53 | 54 | 55 | --------------------------------------------------------------------------------