diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java index b3ca91f9..b3f8cb7f 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java @@ -27,6 +27,7 @@ import org.hyperledger.fabric.shim.ChaincodeBase; import org.hyperledger.fabric.shim.ChaincodeServer; import org.hyperledger.fabric.shim.ChaincodeStub; +import org.hyperledger.fabric.shim.NettyChaincodeServer; import org.hyperledger.fabric.shim.ResponseUtils; import org.hyperledger.fabric.traces.Traces; @@ -114,7 +115,8 @@ private Response processRequest(final ChaincodeStub stub) { // based on the routing information the serializer can be found // TRANSACTION target as this on the 'inbound' to invoke a tx - final SerializerInterface si = serializers.getSerializer(txFn.getRouting().getSerializerName(), Serializer.TARGET.TRANSACTION); + final SerializerInterface si = serializers.getSerializer(txFn.getRouting().getSerializerName(), + Serializer.TARGET.TRANSACTION); final ExecutionService executor = ExecutionFactory.getInstance().createExecutionService(si); logger.info(() -> "Got routing:" + txFn.getRouting()); @@ -159,7 +161,7 @@ TxFunction getRouting(final InvocationRequest request) { * * @param args */ - public static void main(final String[] args) { + public static void main(final String[] args) throws Exception { final ContractRouter cfc = new ContractRouter(args); cfc.findAllContracts(); @@ -171,10 +173,16 @@ public static void main(final String[] args) { MetadataBuilder.initialize(cfc.getRoutingRegistry(), cfc.getTypeRegistry()); logger.info(() -> "Metadata follows:" + MetadataBuilder.debugString()); - // commence routing, once this has returned the chaincode and contract api is - // 'open for chaining' - cfc.startRouting(); - + // check if this should be running in client or server mode + if (cfc.isServer()) { + logger.info("Starting chaincode as server"); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(cfc, + cfc.getChaincodeServerConfig()); + chaincodeServer.start(); + } else { + logger.info("Starting chaincode as client"); + cfc.startRouting(); + } } protected TypeRegistry getTypeRegistry() { @@ -190,14 +198,15 @@ protected RoutingRegistry getRoutingRegistry() { * * @param chaincodeServer */ - public void startRouterWithChaincodeServer(final ChaincodeServer chaincodeServer) throws IOException, InterruptedException { + public void startRouterWithChaincodeServer(final ChaincodeServer chaincodeServer) + throws IOException, InterruptedException { findAllContracts(); logger.fine(getRoutingRegistry().toString()); MetadataBuilder.initialize(getRoutingRegistry(), getTypeRegistry()); logger.info(() -> "Metadata follows:" + MetadataBuilder.debugString()); - logger.info("Starting ChaincodeServer"); chaincodeServer.start(); } + } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java index 604b309e..6bd66b0a 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java @@ -13,6 +13,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.nio.file.Files; import java.nio.file.Paths; import java.security.Security; @@ -51,8 +53,11 @@ * Abstract implementation of {@link Chaincode}. * *

- * All chaincode implementations must extend the abstract class ChaincodeBase. - * It is possible to implement chaincode by extending ChaincodeBase directly however new projects should implement {@link org.hyperledger.fabric.contract.ContractInterface} and use the contract programming model instead. + * All chaincode implementations must extend the abstract class + * ChaincodeBase. It is possible to implement chaincode by + * extending ChaincodeBase directly however new projects should + * implement {@link org.hyperledger.fabric.contract.ContractInterface} and use + * the contract programming model instead. * * @see org.hyperledger.fabric.contract */ @@ -96,17 +101,23 @@ public abstract class ChaincodeBase implements Chaincode { private boolean tlsEnabled = false; private String tlsClientKeyPath; private String tlsClientCertPath; + private String tlsClientKeyFile; + private String tlsClientCertFile; private String tlsClientRootCertPath; private String id; private String localMspId = ""; + private String chaincodeServerAddress = ""; + private static final String CHAINCODE_SERVER_ADDRESS = "CHAINCODE_SERVER_ADDRESS"; private static final String CORE_CHAINCODE_ID_NAME = "CORE_CHAINCODE_ID_NAME"; private static final String CORE_PEER_ADDRESS = "CORE_PEER_ADDRESS"; private static final String CORE_PEER_TLS_ENABLED = "CORE_PEER_TLS_ENABLED"; private static final String CORE_PEER_TLS_ROOTCERT_FILE = "CORE_PEER_TLS_ROOTCERT_FILE"; private static final String ENV_TLS_CLIENT_KEY_PATH = "CORE_TLS_CLIENT_KEY_PATH"; private static final String ENV_TLS_CLIENT_CERT_PATH = "CORE_TLS_CLIENT_CERT_PATH"; + private static final String ENV_TLS_CLIENT_KEY_FILE = "CORE_TLS_CLIENT_KEY_FILE"; + private static final String ENV_TLS_CLIENT_CERT_FILE = "CORE_TLS_CLIENT_CERT_FILE"; private static final String CORE_PEER_LOCALMSPID = "CORE_PEER_LOCALMSPID"; private static final String MAX_INBOUND_MESSAGE_SIZE = "MAX_INBOUND_MESSAGE_SIZE"; private Properties props; @@ -120,8 +131,10 @@ private int getMaxInboundMessageSize() { if (this.props == null) { throw new IllegalStateException("Chaincode config not available"); } - final int maxMsgSize = Integer.parseInt(this.props.getProperty(MAX_INBOUND_MESSAGE_SIZE, DEFAULT_MAX_INBOUND_MESSAGE_SIZE)); - final String msgSizeInfo = String.format("Maximum Inbound Message Size [%s] = %d", MAX_INBOUND_MESSAGE_SIZE, maxMsgSize); + final int maxMsgSize = Integer + .parseInt(this.props.getProperty(MAX_INBOUND_MESSAGE_SIZE, DEFAULT_MAX_INBOUND_MESSAGE_SIZE)); + final String msgSizeInfo = String.format("Maximum Inbound Message Size [%s] = %d", MAX_INBOUND_MESSAGE_SIZE, + maxMsgSize); LOGGER.info(msgSizeInfo); return maxMsgSize; } @@ -165,7 +178,6 @@ protected final void connectToPeer() throws IOException { final InvocationTaskManager itm = InvocationTaskManager.getManager(this, chaincodeId); - // This is a critical method - it is the one time that a // protobuf service is invoked. The single 'register' call // is made, and two streams are created. @@ -200,7 +212,9 @@ public void onNext(final ChaincodeMessage chaincodeMessage) { @Override public void onError(final Throwable t) { - LOGGER.severe(() -> "An error occured on the chaincode stream. Shutting down the chaincode stream." + Logging.formatError(t)); + LOGGER.severe( + () -> "An error occured on the chaincode stream. Shutting down the chaincode stream." + + Logging.formatError(t)); chaincodeSupportClient.shutdown(itm); } @@ -220,11 +234,14 @@ public void onCompleted() { /** * connect external chaincode to peer for chat. + * * @param requestObserver reqeust from peer - * @return itm - The InnvocationTask Manager handles the message level communication with the peer. + * @return itm - The InnvocationTask Manager handles the message level + * communication with the peer. * @throws IOException validation fields exception */ - protected StreamObserver connectToPeer(final StreamObserver requestObserver) throws IOException { + protected StreamObserver connectToPeer( + final StreamObserver requestObserver) throws IOException { validateOptions(); if (requestObserver == null) { throw new IOException("StreamObserver 'requestObserver' for chat with peer can't be null"); @@ -254,7 +271,8 @@ public void onNext(final ChaincodeMessage chaincodeMessage) { @Override public void onError(final Throwable t) { - LOGGER.severe(() -> "An error occured on the chaincode stream. Shutting down the chaincode stream." + Logging.formatError(t)); + LOGGER.severe(() -> "An error occured on the chaincode stream. Shutting down the chaincode stream." + + Logging.formatError(t)); chaincodeSupportClient.shutdown(itm); } @@ -310,33 +328,60 @@ private Level mapLevel(final String level) { if (level != null) { switch (level.toUpperCase().trim()) { - case "CRITICAL": - case "ERROR": - return Level.SEVERE; - case "WARNING": - case "WARN": - return Level.WARNING; - case "INFO": - return Level.INFO; - case "NOTICE": - return Level.CONFIG; - case "DEBUG": - return Level.FINEST; - default: - break; + case "CRITICAL": + case "ERROR": + return Level.SEVERE; + case "WARNING": + case "WARN": + return Level.WARNING; + case "INFO": + return Level.INFO; + case "NOTICE": + return Level.CONFIG; + case "DEBUG": + return Level.FINEST; + default: + break; } } return Level.INFO; } + + private SocketAddress parseHostPort(final String hostAddrStr) { + String[] hostArr = hostAddrStr.split(":"); + String h; + int p; + + if (hostArr.length == 2) { + p = Integer.valueOf(hostArr[1].trim()); + h = hostArr[0].trim(); + } else { + final String msg = String.format( + "peer address argument should be in host:port format, current %s in wrong", hostAddrStr); + LOGGER.severe(msg); + throw new IllegalArgumentException(msg); + } + return new InetSocketAddress(h, p); + } + + /** + * Use the CHAINCODE_SERVER_ADDRESS as the key to swap mode. + * + * @return true if this should be run as `chaincode-as-a-service` + */ + public boolean isServer() { + return !chaincodeServerAddress.isEmpty(); + } + /** * Validate init parameters from env chaincode base. */ public void validateOptions() { if (this.id == null || this.id.isEmpty()) { - throw new IllegalArgumentException( - format("The chaincode id must be specified using either the -i or --i command line options or the %s environment variable.", - CORE_CHAINCODE_ID_NAME)); + throw new IllegalArgumentException(format( + "The chaincode id must be specified using either the -i or --i command line options or the %s environment variable.", + CORE_CHAINCODE_ID_NAME)); } if (this.tlsEnabled) { if (tlsClientCertPath == null) { @@ -390,10 +435,7 @@ protected final void processCommandLineOptions(final String[] args) { LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>"); LOGGER.info("CORE_CHAINCODE_ID_NAME: " + this.id); LOGGER.info("CORE_PEER_ADDRESS: " + this.host + ":" + this.port); - LOGGER.info("CORE_PEER_TLS_ENABLED: " + this.tlsEnabled); - LOGGER.info("CORE_PEER_TLS_ROOTCERT_FILE: " + this.tlsClientRootCertPath); - LOGGER.info("CORE_TLS_CLIENT_KEY_PATH: " + this.tlsClientKeyPath); - LOGGER.info("CORE_TLS_CLIENT_CERT_PATH: " + this.tlsClientCertPath); + } /** @@ -417,6 +459,10 @@ public final void processEnvironmentOptions() { } } + if (System.getenv().containsKey(CHAINCODE_SERVER_ADDRESS)) { + this.chaincodeServerAddress = System.getenv(CHAINCODE_SERVER_ADDRESS); + } + if (System.getenv().containsKey(CORE_PEER_LOCALMSPID)) { this.localMspId = System.getenv(CORE_PEER_LOCALMSPID); } @@ -426,6 +472,9 @@ public final void processEnvironmentOptions() { this.tlsClientRootCertPath = System.getenv(CORE_PEER_TLS_ROOTCERT_FILE); this.tlsClientKeyPath = System.getenv(ENV_TLS_CLIENT_KEY_PATH); this.tlsClientCertPath = System.getenv(ENV_TLS_CLIENT_CERT_PATH); + + this.tlsClientKeyFile = System.getenv(ENV_TLS_CLIENT_KEY_FILE); + this.tlsClientCertFile = System.getenv(ENV_TLS_CLIENT_CERT_FILE); } LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>"); @@ -435,7 +484,10 @@ public final void processEnvironmentOptions() { LOGGER.info("CORE_PEER_TLS_ROOTCERT_FILE: " + this.tlsClientRootCertPath); LOGGER.info("CORE_TLS_CLIENT_KEY_PATH: " + this.tlsClientKeyPath); LOGGER.info("CORE_TLS_CLIENT_CERT_PATH: " + this.tlsClientCertPath); + LOGGER.info("CORE_TLS_CLIENT_KEY_FILE: " + this.tlsClientKeyFile); + LOGGER.info("CORE_TLS_CLIENT_CERT_FILE: " + this.tlsClientCertFile); LOGGER.info("CORE_PEER_LOCALMSPID: " + this.localMspId); + LOGGER.info("CHAINCODE_SERVER_ADDRESS: " + this.chaincodeServerAddress); LOGGER.info("LOGLEVEL: " + this.logLevel); } @@ -473,6 +525,26 @@ public Properties getChaincodeConfig() { return this.props; } + /** + * The properties for starting as chaincode-as-a-service. + * + * @return ChaincodeServerProperties populated + */ + public final ChaincodeServerProperties getChaincodeServerConfig() { + ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + + chaincodeServerProperties.setServerAddress(parseHostPort(chaincodeServerAddress)); + + if (tlsEnabled) { + + // set values on the server properties + chaincodeServerProperties.setTlsEnabled(true); + chaincodeServerProperties.setKeyFile(this.tlsClientCertFile); + chaincodeServerProperties.setKeyCertChainFile(this.tlsClientCertFile); + } + return chaincodeServerProperties; + } + /** * create NettyChannel for host:port with tls if tlsEnabled. * @@ -584,6 +656,7 @@ final String getTlsClientRootCertPath() { /** * Chaincode name / Chaincode id. + * * @return string */ String getId() { diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java index fd84aba3..6e9f0192 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java @@ -5,11 +5,11 @@ */ package org.hyperledger.fabric.shim; -import java.io.IOException; +import java.net.SocketAddress; public final class ChaincodeServerProperties { - private int portChaincodeServer = 9999; + private SocketAddress serverAddress; private int maxInboundMetadataSize = 100 * 1024 * 1024; private int maxInboundMessageSize = 100 * 1024 * 1024; private int maxConnectionAgeSeconds = 5; @@ -27,12 +27,11 @@ public ChaincodeServerProperties() { } public ChaincodeServerProperties( - int portChaincodeServer, int maxInboundMetadataSize, - int maxInboundMessageSize, int maxConnectionAgeSeconds, - int keepAliveTimeoutSeconds, int permitKeepAliveTimeMinutes, - int keepAliveTimeMinutes, boolean permitKeepAliveWithoutCalls) { + final int portChaincodeServer, final int maxInboundMetadataSize, final int maxInboundMessageSize, + final int maxConnectionAgeSeconds, final int keepAliveTimeoutSeconds, final int permitKeepAliveTimeMinutes, + final int keepAliveTimeMinutes, final boolean permitKeepAliveWithoutCalls) { - this.portChaincodeServer = portChaincodeServer; + this.serverAddress = null; this.maxInboundMetadataSize = maxInboundMetadataSize; this.maxInboundMessageSize = maxInboundMessageSize; this.maxConnectionAgeSeconds = maxConnectionAgeSeconds; @@ -46,7 +45,7 @@ public int getMaxInboundMetadataSize() { return maxInboundMetadataSize; } - public void setMaxInboundMetadataSize(int maxInboundMetadataSize) { + public void setMaxInboundMetadataSize(final int maxInboundMetadataSize) { this.maxInboundMetadataSize = maxInboundMetadataSize; } @@ -54,7 +53,7 @@ public int getMaxInboundMessageSize() { return maxInboundMessageSize; } - public void setMaxInboundMessageSize(int maxInboundMessageSize) { + public void setMaxInboundMessageSize(final int maxInboundMessageSize) { this.maxInboundMessageSize = maxInboundMessageSize; } @@ -62,7 +61,7 @@ public int getMaxConnectionAgeSeconds() { return maxConnectionAgeSeconds; } - public void setMaxConnectionAgeSeconds(int maxConnectionAgeSeconds) { + public void setMaxConnectionAgeSeconds(final int maxConnectionAgeSeconds) { this.maxConnectionAgeSeconds = maxConnectionAgeSeconds; } @@ -70,7 +69,7 @@ public int getKeepAliveTimeoutSeconds() { return keepAliveTimeoutSeconds; } - public void setKeepAliveTimeoutSeconds(int keepAliveTimeoutSeconds) { + public void setKeepAliveTimeoutSeconds(final int keepAliveTimeoutSeconds) { this.keepAliveTimeoutSeconds = keepAliveTimeoutSeconds; } @@ -78,7 +77,7 @@ public int getPermitKeepAliveTimeMinutes() { return permitKeepAliveTimeMinutes; } - public void setPermitKeepAliveTimeMinutes(int permitKeepAliveTimeMinutes) { + public void setPermitKeepAliveTimeMinutes(final int permitKeepAliveTimeMinutes) { this.permitKeepAliveTimeMinutes = permitKeepAliveTimeMinutes; } @@ -86,7 +85,7 @@ public int getKeepAliveTimeMinutes() { return keepAliveTimeMinutes; } - public void setKeepAliveTimeMinutes(int keepAliveTimeMinutes) { + public void setKeepAliveTimeMinutes(final int keepAliveTimeMinutes) { this.keepAliveTimeMinutes = keepAliveTimeMinutes; } @@ -94,19 +93,19 @@ public boolean getPermitKeepAliveWithoutCalls() { return permitKeepAliveWithoutCalls; } - public int getPortChaincodeServer() { - return portChaincodeServer; + public SocketAddress getServerAddress() { + return serverAddress; } - public void setPortChaincodeServer(int portChaincodeServer) { - this.portChaincodeServer = portChaincodeServer; + public void setServerAddress(final SocketAddress address) { + this.serverAddress = address; } public boolean isPermitKeepAliveWithoutCalls() { return permitKeepAliveWithoutCalls; } - public void setPermitKeepAliveWithoutCalls(boolean permitKeepAliveWithoutCalls) { + public void setPermitKeepAliveWithoutCalls(final boolean permitKeepAliveWithoutCalls) { this.permitKeepAliveWithoutCalls = permitKeepAliveWithoutCalls; } @@ -114,7 +113,7 @@ public String getKeyPassword() { return keyPassword; } - public void setKeyPassword(String keyPassword) { + public void setKeyPassword(final String keyPassword) { this.keyPassword = keyPassword; } @@ -122,7 +121,7 @@ public String getKeyCertChainFile() { return keyCertChainFile; } - public void setKeyCertChainFile(String keyCertChainFile) { + public void setKeyCertChainFile(final String keyCertChainFile) { this.keyCertChainFile = keyCertChainFile; } @@ -130,7 +129,7 @@ public String getKeyFile() { return keyFile; } - public void setKeyFile(String keyFile) { + public void setKeyFile(final String keyFile) { this.keyFile = keyFile; } @@ -138,7 +137,7 @@ public String getTrustCertCollectionFile() { return trustCertCollectionFile; } - public void setTrustCertCollectionFile(String trustCertCollectionFile) { + public void setTrustCertCollectionFile(final String trustCertCollectionFile) { this.trustCertCollectionFile = trustCertCollectionFile; } @@ -146,37 +145,39 @@ public boolean isTlsEnabled() { return tlsEnabled; } - public void setTlsEnabled(boolean tlsEnabled) { + public void setTlsEnabled(final boolean tlsEnabled) { this.tlsEnabled = tlsEnabled; } - public void validate() throws IOException { - if (this.getPortChaincodeServer() <= 0) { - throw new IOException("chaincodeServerProperties.getPortChaincodeServer() must be more then 0"); + public void validate() { + if (this.getServerAddress() == null) { + throw new IllegalArgumentException("chaincodeServerProperties.getServerAddress() must be set"); } if (this.getKeepAliveTimeMinutes() <= 0) { - throw new IOException("chaincodeServerProperties.getKeepAliveTimeMinutes() must be more then 0"); + throw new IllegalArgumentException("chaincodeServerProperties.getKeepAliveTimeMinutes() must be more then 0"); } if (this.getKeepAliveTimeoutSeconds() <= 0) { - throw new IOException("chaincodeServerProperties.getKeepAliveTimeoutSeconds() must be more then 0"); + throw new IllegalArgumentException("chaincodeServerProperties.getKeepAliveTimeoutSeconds() must be more then 0"); } if (this.getPermitKeepAliveTimeMinutes() <= 0) { - throw new IOException("chaincodeServerProperties.getPermitKeepAliveTimeMinutes() must be more then 0"); + throw new IllegalArgumentException("chaincodeServerProperties.getPermitKeepAliveTimeMinutes() must be more then 0"); } if (this.getMaxConnectionAgeSeconds() <= 0) { - throw new IOException("chaincodeServerProperties.getMaxConnectionAgeSeconds() must be more then 0"); + throw new IllegalArgumentException("chaincodeServerProperties.getMaxConnectionAgeSeconds() must be more then 0"); } if (this.getMaxInboundMetadataSize() <= 0) { - throw new IOException("chaincodeServerProperties.getMaxInboundMetadataSize() must be more then 0"); + throw new IllegalArgumentException("chaincodeServerProperties.getMaxInboundMetadataSize() must be more then 0"); } if (this.getMaxInboundMessageSize() <= 0) { - throw new IOException("chaincodeServerProperties.getMaxInboundMessageSize() must be more then 0"); + throw new IllegalArgumentException("chaincodeServerProperties.getMaxInboundMessageSize() must be more then 0"); } if (this.isTlsEnabled() && (this.getKeyCertChainFile() == null || this.getKeyCertChainFile().isEmpty() || this.getKeyFile() == null || this.getKeyFile().isEmpty())) { - throw new IOException("if chaincodeServerProperties.isTlsEnabled() must be more specified" + throw new IllegalArgumentException("if chaincodeServerProperties.isTlsEnabled() must be more specified" + " chaincodeServerProperties.getKeyCertChainFile() and chaincodeServerProperties.getKeyFile()" + " with optional chaincodeServerProperties.getKeyPassword()"); } } + + } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java index 365909c4..4d6e9c33 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java @@ -13,8 +13,7 @@ import io.grpc.netty.shaded.io.netty.handler.ssl.ApplicationProtocolNames; import io.grpc.netty.shaded.io.netty.handler.ssl.ClientAuth; import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import java.util.logging.Logger; import java.io.File; import java.io.IOException; @@ -26,7 +25,7 @@ */ public final class NettyGrpcServer implements GrpcServer { - private static final Log LOGGER = LogFactory.getLog(NettyGrpcServer.class); + private static final Logger LOGGER = Logger.getLogger(NettyGrpcServer.class.getName()); private final Server server; @@ -39,14 +38,14 @@ public final class NettyGrpcServer implements GrpcServer { */ public NettyGrpcServer(final ChaincodeBase chaincodeBase, final ChaincodeServerProperties chaincodeServerProperties) throws IOException { if (chaincodeBase == null) { - throw new IOException("chaincode must be specified"); + throw new IllegalArgumentException("chaincode must be specified"); } if (chaincodeServerProperties == null) { - throw new IOException("chaincodeServerProperties must be specified"); + throw new IllegalArgumentException("chaincodeServerProperties must be specified"); } chaincodeServerProperties.validate(); - final NettyServerBuilder serverBuilder = NettyServerBuilder.forPort(chaincodeServerProperties.getPortChaincodeServer()) + final NettyServerBuilder serverBuilder = NettyServerBuilder.forAddress(chaincodeServerProperties.getServerAddress()) .addService(new ChatChaincodeWithPeer(chaincodeBase)) .keepAliveTime(chaincodeServerProperties.getKeepAliveTimeMinutes(), TimeUnit.MINUTES) .keepAliveTimeout(chaincodeServerProperties.getKeepAliveTimeoutSeconds(), TimeUnit.SECONDS) @@ -84,7 +83,7 @@ public NettyGrpcServer(final ChaincodeBase chaincodeBase, final ChaincodeServerP } LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>:\n"); - LOGGER.info("PortChaincodeServer:" + chaincodeServerProperties.getPortChaincodeServer()); + LOGGER.info("ServerAddress:" + chaincodeServerProperties.getServerAddress().toString()); LOGGER.info("MaxInboundMetadataSize:" + chaincodeServerProperties.getMaxInboundMetadataSize()); LOGGER.info("MaxInboundMessageSize:" + chaincodeServerProperties.getMaxInboundMessageSize()); LOGGER.info("MaxConnectionAgeSeconds:" + chaincodeServerProperties.getMaxConnectionAgeSeconds()); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractRouterTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractRouterTest.java index bdc9d93a..81b9706e 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractRouterTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractRouterTest.java @@ -14,6 +14,7 @@ import static org.junit.Assert.assertThat; import java.io.IOException; +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; @@ -392,6 +393,7 @@ public void createContractRuntimeExceptions() { @Test public void testStartingContractRouterWithStartingAChaincodeServer() throws IOException { ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setServerAddress(new InetSocketAddress("0.0.0.0", 9999)); final ContractRouter r = new ContractRouter(new String[]{"-i", "testId"}); ChaincodeServer chaincodeServer = new NettyChaincodeServer(r, chaincodeServerProperties); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeServerImplTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeServerImplTest.java index 55c92eae..766fb2a6 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeServerImplTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeServerImplTest.java @@ -23,6 +23,7 @@ class ChaincodeServerImplTest { void setEnv() { environmentVariables.set("CORE_CHAINCODE_ID_NAME", "mycc"); environmentVariables.set("CORE_PEER_ADDRESS", "localhost:7052"); + environmentVariables.set("CHAINCODE_SERVER_ADDRESS", "0.0.0.0:9999"); environmentVariables.set("CORE_PEER_TLS_ENABLED", "false"); environmentVariables.set("CORE_PEER_TLS_ROOTCERT_FILE", "src/test/resources/ca.crt"); environmentVariables.set("CORE_TLS_CLIENT_KEY_PATH", "src/test/resources/client.key.enc"); @@ -37,13 +38,14 @@ void clearEnv() { environmentVariables.clear("CORE_PEER_TLS_ROOTCERT_FILE"); environmentVariables.clear("CORE_TLS_CLIENT_KEY_PATH"); environmentVariables.clear("CORE_TLS_CLIENT_CERT_PATH"); + environmentVariables.clear("CHAINCODE_SERVER_ADDRESS"); } @Test void init() { try { final ChaincodeBase chaincodeBase = new EmptyChaincode(); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeBase.getChaincodeServerConfig()); } catch (Exception e) { e.printStackTrace(); } @@ -54,7 +56,7 @@ void initEnvNotSet() { clearEnv(); try { final ChaincodeBase chaincodeBase = new EmptyChaincode(); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeBase.getChaincodeServerConfig()); } catch (Exception e) { e.printStackTrace(); } @@ -64,7 +66,7 @@ void initEnvNotSet() { void startAndStop() { try { final ChaincodeBase chaincodeBase = new ContractRouter(new String[] {"-a", "127.0.0.1:7052", "-i", "testId"}); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeBase.getChaincodeServerConfig()); new Thread(() -> { try { chaincodeServer.start(); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/NettyGrpcServerTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/NettyGrpcServerTest.java index ef2ff34a..642cf056 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/NettyGrpcServerTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/NettyGrpcServerTest.java @@ -30,6 +30,7 @@ void setEnv() { environmentVariables.set("CORE_PEER_TLS_ROOTCERT_FILE", "src/test/resources/ca.crt"); environmentVariables.set("CORE_TLS_CLIENT_KEY_PATH", "src/test/resources/client.key.enc"); environmentVariables.set("CORE_TLS_CLIENT_CERT_PATH", "src/test/resources/client.crt.enc"); + environmentVariables.set("CHAINCODE_SERVER_ADDRESS", "0.0.0.0:9999"); } @AfterEach @@ -40,6 +41,7 @@ void clearEnv() { environmentVariables.clear("CORE_PEER_TLS_ROOTCERT_FILE"); environmentVariables.clear("CORE_TLS_CLIENT_KEY_PATH"); environmentVariables.clear("CORE_TLS_CLIENT_CERT_PATH"); + environmentVariables.clear("CHAINCODE_SERVER_ADDRESS"); } @Test @@ -47,7 +49,7 @@ void initNoTls() { try { final ChaincodeBase chaincodeBase = new EmptyChaincode(); chaincodeBase.processEnvironmentOptions(); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeBase.getChaincodeServerConfig()); } catch (IOException e) { e.printStackTrace(); } @@ -55,168 +57,125 @@ void initNoTls() { @Test void validationNoChaincodeServerPropertiesg() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, null); - }, - "ChaincodeServerProperties must be specified" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, null); + }, "ChaincodeServerProperties must be specified"); } @Test void validationPortChaincodeServer() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setPortChaincodeServer(-1); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getPortChaincodeServer() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setServerAddress(null); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getServerAddress() must be set"); } @Test void validationKeepAliveTimeMinutes() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setKeepAliveTimeMinutes(-1); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getKeepAliveTimeMinutes() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setKeepAliveTimeMinutes(-1); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getKeepAliveTimeMinutes() must be more then 0"); } @Test void validationKeepAliveTimeoutSeconds() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setKeepAliveTimeoutSeconds(-1); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getKeepAliveTimeoutSeconds() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setKeepAliveTimeoutSeconds(-1); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getKeepAliveTimeoutSeconds() must be more then 0"); } @Test void validationPermitKeepAliveTimeMinutes() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setPermitKeepAliveTimeMinutes(-1); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getPermitKeepAliveTimeMinutes() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setPermitKeepAliveTimeMinutes(-1); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getPermitKeepAliveTimeMinutes() must be more then 0"); } @Test void validationMaxConnectionAgeSeconds() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setMaxConnectionAgeSeconds(-1); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getMaxConnectionAgeSeconds() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setMaxConnectionAgeSeconds(-1); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getMaxConnectionAgeSeconds() must be more then 0"); } @Test void validationMaxInboundMetadataSize() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setMaxInboundMetadataSize(-1); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getMaxInboundMetadataSize() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setMaxInboundMetadataSize(-1); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getMaxInboundMetadataSize() must be more then 0"); } @Test void validationMaxInboundMessageSize() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setMaxInboundMessageSize(-1); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getMaxInboundMessageSize() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setMaxInboundMessageSize(-1); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getMaxInboundMessageSize() must be more then 0"); } @Test void validationTlsEnabledButKeyNotSet() { - Assertions.assertThrows( - IOException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); - chaincodeServerProperties.setTlsEnabled(true); - chaincodeServerProperties.setKeyFile(null); - chaincodeServerProperties.setKeyCertChainFile(null); - chaincodeServerProperties.setKeyPassword(null); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); - }, - "ChaincodeServerProperties.getMaxInboundMessageSize() must be more then 0" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + chaincodeServerProperties.setTlsEnabled(true); + chaincodeServerProperties.setKeyFile(null); + chaincodeServerProperties.setKeyCertChainFile(null); + chaincodeServerProperties.setKeyPassword(null); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeServerProperties); + }, "ChaincodeServerProperties.getMaxInboundMessageSize() must be more then 0"); } @Test void initNull() { - Assertions.assertThrows( - IOException.class, - () -> { - ChaincodeServer chaincodeServer = new NettyChaincodeServer(null, new ChaincodeServerProperties()); - }, - "chaincode must be specified" - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + ChaincodeServer chaincodeServer = new NettyChaincodeServer(null, new ChaincodeServerProperties()); + }, "chaincode must be specified"); } @Test void initNullEnvNotSet() { clearEnv(); - try { + Assertions.assertThrows(IllegalArgumentException.class, () -> { ChaincodeServer chaincodeServer = new NettyChaincodeServer(null, new ChaincodeServerProperties()); - } catch (IOException e) { - e.printStackTrace(); - } + }); + } @Test void initEnvNotSet() { clearEnv(); - Assertions.assertThrows( - IllegalArgumentException.class, - () -> { - final ChaincodeBase chaincodeBase = new EmptyChaincode(); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); - } - ); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + final ChaincodeBase chaincodeBase = new EmptyChaincode(); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + }); } @Test void initEnvSetPortChaincodeServerAndCoreChaincodeIdName() throws IOException { clearEnv(); environmentVariables.set("CORE_CHAINCODE_ID_NAME", "mycc"); + environmentVariables.set("CHAINCODE_SERVER_ADDRESS", "0.0.0.0:9999"); ChaincodeBase chaincodeBase = new EmptyChaincode(); chaincodeBase.processEnvironmentOptions(); @@ -224,7 +183,7 @@ void initEnvSetPortChaincodeServerAndCoreChaincodeIdName() throws IOException { Metrics.initialize(props); Traces.initialize(props); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeBase.getChaincodeServerConfig()); } @@ -232,6 +191,7 @@ void initEnvSetPortChaincodeServerAndCoreChaincodeIdName() throws IOException { void startAndStopSetCoreChaincodeIdName() { clearEnv(); environmentVariables.set("CORE_CHAINCODE_ID_NAME", "mycc"); + environmentVariables.set("CHAINCODE_SERVER_ADDRESS", "0.0.0.0:9999"); try { ChaincodeBase chaincodeBase = new EmptyChaincode(); chaincodeBase.processEnvironmentOptions(); @@ -239,15 +199,14 @@ void startAndStopSetCoreChaincodeIdName() { Metrics.initialize(props); Traces.initialize(props); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeBase.getChaincodeServerConfig()); new Thread(() -> { try { chaincodeServer.start(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } - } - ).start(); + }).start(); try { Thread.sleep(1000); } catch (InterruptedException e) { @@ -265,15 +224,14 @@ void startAndStop() { try { final ChaincodeBase chaincodeBase = new EmptyChaincode(); chaincodeBase.processEnvironmentOptions(); - ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, new ChaincodeServerProperties()); + ChaincodeServer chaincodeServer = new NettyChaincodeServer(chaincodeBase, chaincodeBase.getChaincodeServerConfig()); new Thread(() -> { try { chaincodeServer.start(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } - } - ).start(); + }).start(); try { Thread.sleep(1000); } catch (InterruptedException e) { @@ -291,7 +249,7 @@ void startAndStopTlsPassword() { try { final ChaincodeBase chaincodeBase = new EmptyChaincode(); chaincodeBase.processEnvironmentOptions(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + final ChaincodeServerProperties chaincodeServerProperties = chaincodeBase.getChaincodeServerConfig(); chaincodeServerProperties.setTlsEnabled(true); chaincodeServerProperties.setKeyFile("src/test/resources/client.key.password-protected"); chaincodeServerProperties.setKeyCertChainFile("src/test/resources/client.crt"); @@ -303,8 +261,7 @@ void startAndStopTlsPassword() { } catch (IOException | InterruptedException e) { e.printStackTrace(); } - } - ).start(); + }).start(); try { Thread.sleep(1000); } catch (InterruptedException e) { @@ -322,7 +279,7 @@ void startAndStopTlsWithoutPassword() { try { final ChaincodeBase chaincodeBase = new EmptyChaincode(); chaincodeBase.processEnvironmentOptions(); - final ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties(); + final ChaincodeServerProperties chaincodeServerProperties = chaincodeBase.getChaincodeServerConfig(); chaincodeServerProperties.setTlsEnabled(true); chaincodeServerProperties.setKeyFile("src/test/resources/client.key"); chaincodeServerProperties.setKeyCertChainFile("src/test/resources/client.crt"); @@ -333,8 +290,7 @@ void startAndStopTlsWithoutPassword() { } catch (IOException | InterruptedException e) { e.printStackTrace(); } - } - ).start(); + }).start(); try { Thread.sleep(1000); } catch (InterruptedException e) {