Я пытаюсь получить доступ к своей сети Hyperledger Fabric из приложения Spring Boot , используя Java SDK .
Версии:
- OpenJDK 11
- Hyperledger 1.2 (fabric-sdk-java 1.2.0)
- Spring Boot 2.0.5.RELEASE
- Docker 18.06.1-ce
Работает нормально из стандартного приложения на основе Java Spring, в основном так (чтение криптографических материалов из локальной папки webapps ):
private final static String PATH_CRYPTO_CONFIG = System.getProperty("user.dir") + "/webapps/myapp/crypto-config";
private final static String ORG1_PEER0_NAME = "peer0.myorg.ch";
private final static String ORG1_PEER0_ADDRESS = "grpcs://peer0.myorg.ch:7051";
private final static String ORG1_PEER0_CERT = PATH_CRYPTO_CONFIG + "/peerOrganizations/myorg.ch/peers/peer0.myorg.ch/tls/server.crt";
private final static String ORG1_ADMIN_PK = PATH_CRYPTO_CONFIG + "/peerOrganizations/myorg.ch/users/Admin@myorg.ch/msp/keystore/e3f7400bc142ebde34649dee2968757783a6a1ac873c22e5718575cefcdab7e7_sk";
private final static String ORG1_ADMIN_PEM = PATH_CRYPTO_CONFIG + "/peerOrganizations/myorg.ch/users/Admin@myorg.ch/msp/signcerts/Admin@myorg.ch-cert.pem";
private final static String ORDERER_NAME = "orderer.myorg.ch";
private final static String ORDERER_ADDRESS = "grpcs://orderer.myorg.ch:7050";
private final static String ORDERER_CERT = PATH_CRYPTO_CONFIG + "/ordererOrganizations/myorg.ch/orderers/orderer.myorg.ch/tls/server.crt";
public void init() {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
HFClient client = HFClient.createNewInstance();
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
client.setCryptoSuite(cryptoSuite);
User myOrgAdmin = new AppUser("Admin", ORG1_ADMIN_PK, ORG1_ADMIN_PEM, "MyOrgMSP");
client.setUserContext(myOrgAdmin);
Channel ciChannel = client.newChannel("ci-channel");
Properties ordererProperties = new Properties();
ordererProperties.setProperty("pemFile", ORDERER_CERT);
ordererProperties.setProperty("hostnameOverride", ORDERER_NAME);
ordererProperties.setProperty("sslProvider", "openSSL");
ordererProperties.setProperty("negotiationType", "TLS");
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[]{5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[]{8L, TimeUnit.SECONDS});
Orderer orderer = client.newOrderer(ORDERER_NAME, ORDERER_ADDRESS, ordererProperties);
Properties peer0MyOrgProperties = new Properties();
peer0MyOrgProperties.setProperty("pemFile", ORG1_PEER0_CERT);
peer0MyOrgProperties.setProperty("hostnameOverride", ORG1_PEER0_NAME + ":7051");
peer0MyOrgProperties.setProperty("sslProvider", "openSSL");
peer0MyOrgProperties.setProperty("negotiationType", "TLS");
peer0MyOrgProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
Peer peer0MyOrg = client.newPeer(ORG1_PEER0_NAME, ORG1_PEER0_ADDRESS, peer0MyOrgProperties);
ciChannel.addOrderer(orderer);
ciChannel.addPeer(peer0MyOrg, Channel.PeerOptions.createPeerOptions().setPeerRoles(EnumSet.of(Peer.PeerRole.SERVICE_DISCOVERY, Peer.PeerRole.LEDGER_QUERY, Peer.PeerRole.EVENT_SOURCE, Peer.PeerRole.CHAINCODE_QUERY)));
ciChannel.initialize();
}
Но я не могу заставить его работать при переходе на Spring Boot приложение , упакованное как JAR .
Действительно, работая с файлом JAR и встроенным Tomcat, я могуне указывать пути к криптографическим файлам.Мне нужно использовать ClassPathResource
, и я могу получать файлы только в виде потоков.
Поэтому вместо использования pemFile
для указания сертификатов я использую pemBytes
таким образом ( crypto-config папка была добавлена как ресурс):
private final static String ORG1_PEER0_NAME = "peer0.myorg.ch";
private final static String ORG1_PEER0_ADDRESS = "grpcs://peer0.myorg.ch:7051";
private final static String ORG1_PEER0_CERT = "peerOrganizations/myorg.ch/peers/peer0.myorg.ch/tls/server.crt";
private final static String ORG1_ADMIN_PK = "peerOrganizations/myorg.ch/users/Admin@myorg.ch/msp/keystore/e3f7400bc142ebde34649dee2968757783a6a1ac873c22e5718575cefcdab7e7_sk";
private final static String ORG1_ADMIN_PEM = "peerOrganizations/myorg.ch/users/Admin@myorg.ch/msp/signcerts/Admin@myorg.ch-cert.pem";
private final static String ORDERER_NAME = "orderer.myorg.ch";
private final static String ORDERER_ADDRESS = "grpcs://orderer.myorg.ch:7050";
private final static String ORDERER_CERT = "ordererOrganizations/myorg.ch/orderers/orderer.myorg.ch/tls/server.crt";
public void init() {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
HFClient client = HFClient.createNewInstance();
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
client.setCryptoSuite(cryptoSuite);
User myOrgAdmin = new AppUser("Admin", ORG1_ADMIN_PK, ORG1_ADMIN_PEM, "MyOrgMSP");
client.setUserContext(myOrgAdmin);
Channel ciChannel = client.newChannel("ci-channel");
Properties ordererProperties = new Properties();
ordererProperties.put("pemBytes", FileCopyUtils.copyToByteArray(new ClassPathResource(ORDERER_CERT).getInputStream()));
ordererProperties.setProperty("hostnameOverride", ORDERER_NAME);
ordererProperties.setProperty("sslProvider", "openSSL");
ordererProperties.setProperty("negotiationType", "TLS");
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[]{5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[]{8L, TimeUnit.SECONDS});
Orderer orderer = client.newOrderer(ORDERER_NAME, ORDERER_ADDRESS, ordererProperties);
Properties peer0MyOrgProperties = new Properties();
peer0MyOrgProperties.put("pemBytes", FileCopyUtils.copyToByteArray(new ClassPathResource(ORG1_PEER0_CERT).getInputStream()));
peer0MyOrgProperties.setProperty("hostnameOverride", ORG1_PEER0_NAME + ":7051");
peer0MyOrgProperties.setProperty("sslProvider", "openSSL");
peer0MyOrgProperties.setProperty("negotiationType", "TLS");
peer0MyOrgProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
Peer peer0MyOrg = client.newPeer(ORG1_PEER0_NAME, ORG1_PEER0_ADDRESS, peer0MyOrgProperties);
ciChannel.addOrderer(orderer);
ciChannel.addPeer(peer0MyOrg, Channel.PeerOptions.createPeerOptions().setPeerRoles(EnumSet.of(Peer.PeerRole.SERVICE_DISCOVERY, Peer.PeerRole.LEDGER_QUERY, Peer.PeerRole.EVENT_SOURCE, Peer.PeerRole.CHAINCODE_QUERY)));
ciChannel.initialize();
}
Ошибка:
myapp | 2018-10-24 10:59:19.318 ERROR 1 --- [nio-8080-exec-4] org.hyperledger.fabric.sdk.Channel : Sending proposal to peer0.myorg.ch failed because of: gRPC failure=Status{code=UNKNOWN, description=null, cause=java.lang.AbstractMethodError
myapp | at io.netty.internal.tcnative.SSL.readFromSSL(Native Method)
myapp | at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.readPlaintextData(ReferenceCountedOpenSslEngine.java:488)
at [...]
myapp | java.lang.Exception: io.grpc.StatusRuntimeException: UNKNOWN
myapp | at org.hyperledger.fabric.sdk.Channel.sendProposalToPeers(Channel.java:3619) ~[fabric-sdk-java-1.2.0.jar!/:na]
at [...]
myapp | Caused by: io.grpc.StatusRuntimeException: UNKNOWN
myapp | at io.grpc.Status.asRuntimeException(Status.java:526) ~[grpc-core-1.13.2.jar!/:1.13.2]
at [...]
myapp | Caused by: java.lang.AbstractMethodError: null
myapp | at io.netty.internal.tcnative.SSL.readFromSSL(Native Method) ~[netty-tcnative-boringssl-static-2.0.10.Final.jar!/:2.0.10.Final]
at [...]
myapp | 2018-10-24 10:59:19.359 WARN 1 --- [nio-8080-exec-4] org.hyperledger.fabric.sdk.Channel : Channel ci-channel could not load peer CA certificates from any peers.
myapp | 2018-10-24 10:59:19.367 INFO 1 --- [nio-8080-exec-4] o.h.fabric.sdk.ServiceDiscovery : Channel ci-channel doing discovery with peer: Peer peer0.myorg.ch url: grpcs://peer0.myorg.ch:7051
myapp | 2018-10-24 10:59:19.823 WARN 1 --- [nio-8080-exec-4] o.h.fabric.sdk.ServiceDiscovery : Channel ci-channel peer Peer peer0.myorg.ch url: grpcs://peer0.myorg.ch:7051 service discovery error io.grpc.StatusRuntimeException: UNKNOWN
myapp | 2018-10-24 10:59:20.444 WARN 1 --- [ault-executor-2] o.h.fabric.sdk.PeerEventServiceClient : Received error on peer eventing service on channel ci-channel, peer peer0.myorg.ch, url grpcs://peer0.myorg.ch:7051, attempts 1. UNKNOWN
Я попытался:
- вывести содержимое сертификатов и получиложидаемый результат
- создание временных файлов из потоков и указание путей с использованием
pemFile
- понижения до Java 8
- добавление более новой
tcnative
зависимости ( netty-tcnative 2.0.18.Final )
Но с этой ошибкой все равно не получится.