1313import java .io .File ;
1414import java .io .IOException ;
1515import java .io .InputStream ;
16+ import java .net .InetSocketAddress ;
17+ import java .net .SocketAddress ;
1618import java .nio .file .Files ;
1719import java .nio .file .Paths ;
1820import java .security .Security ;
5153 * Abstract implementation of {@link Chaincode}.
5254 *
5355 * <p>
54- * All chaincode implementations must extend the abstract class <code>ChaincodeBase</code>.
55- * It is possible to implement chaincode by extending <code>ChaincodeBase</code> directly however new projects should implement {@link org.hyperledger.fabric.contract.ContractInterface} and use the contract programming model instead.
56+ * All chaincode implementations must extend the abstract class
57+ * <code>ChaincodeBase</code>. It is possible to implement chaincode by
58+ * extending <code>ChaincodeBase</code> directly however new projects should
59+ * implement {@link org.hyperledger.fabric.contract.ContractInterface} and use
60+ * the contract programming model instead.
5661 *
5762 * @see org.hyperledger.fabric.contract
5863 */
@@ -96,17 +101,23 @@ public abstract class ChaincodeBase implements Chaincode {
96101 private boolean tlsEnabled = false ;
97102 private String tlsClientKeyPath ;
98103 private String tlsClientCertPath ;
104+ private String tlsClientKeyFile ;
105+ private String tlsClientCertFile ;
99106 private String tlsClientRootCertPath ;
100107
101108 private String id ;
102109 private String localMspId = "" ;
110+ private String chaincodeServerAddress = "" ;
103111
112+ private static final String CHAINCODE_SERVER_ADDRESS = "CHAINCODE_SERVER_ADDRESS" ;
104113 private static final String CORE_CHAINCODE_ID_NAME = "CORE_CHAINCODE_ID_NAME" ;
105114 private static final String CORE_PEER_ADDRESS = "CORE_PEER_ADDRESS" ;
106115 private static final String CORE_PEER_TLS_ENABLED = "CORE_PEER_TLS_ENABLED" ;
107116 private static final String CORE_PEER_TLS_ROOTCERT_FILE = "CORE_PEER_TLS_ROOTCERT_FILE" ;
108117 private static final String ENV_TLS_CLIENT_KEY_PATH = "CORE_TLS_CLIENT_KEY_PATH" ;
109118 private static final String ENV_TLS_CLIENT_CERT_PATH = "CORE_TLS_CLIENT_CERT_PATH" ;
119+ private static final String ENV_TLS_CLIENT_KEY_FILE = "CORE_TLS_CLIENT_KEY_FILE" ;
120+ private static final String ENV_TLS_CLIENT_CERT_FILE = "CORE_TLS_CLIENT_CERT_FILE" ;
110121 private static final String CORE_PEER_LOCALMSPID = "CORE_PEER_LOCALMSPID" ;
111122 private static final String MAX_INBOUND_MESSAGE_SIZE = "MAX_INBOUND_MESSAGE_SIZE" ;
112123 private Properties props ;
@@ -120,8 +131,10 @@ private int getMaxInboundMessageSize() {
120131 if (this .props == null ) {
121132 throw new IllegalStateException ("Chaincode config not available" );
122133 }
123- final int maxMsgSize = Integer .parseInt (this .props .getProperty (MAX_INBOUND_MESSAGE_SIZE , DEFAULT_MAX_INBOUND_MESSAGE_SIZE ));
124- final String msgSizeInfo = String .format ("Maximum Inbound Message Size [%s] = %d" , MAX_INBOUND_MESSAGE_SIZE , maxMsgSize );
134+ final int maxMsgSize = Integer
135+ .parseInt (this .props .getProperty (MAX_INBOUND_MESSAGE_SIZE , DEFAULT_MAX_INBOUND_MESSAGE_SIZE ));
136+ final String msgSizeInfo = String .format ("Maximum Inbound Message Size [%s] = %d" , MAX_INBOUND_MESSAGE_SIZE ,
137+ maxMsgSize );
125138 LOGGER .info (msgSizeInfo );
126139 return maxMsgSize ;
127140 }
@@ -165,7 +178,6 @@ protected final void connectToPeer() throws IOException {
165178
166179 final InvocationTaskManager itm = InvocationTaskManager .getManager (this , chaincodeId );
167180
168-
169181 // This is a critical method - it is the one time that a
170182 // protobuf service is invoked. The single 'register' call
171183 // is made, and two streams are created.
@@ -200,7 +212,9 @@ public void onNext(final ChaincodeMessage chaincodeMessage) {
200212
201213 @ Override
202214 public void onError (final Throwable t ) {
203- LOGGER .severe (() -> "An error occured on the chaincode stream. Shutting down the chaincode stream." + Logging .formatError (t ));
215+ LOGGER .severe (
216+ () -> "An error occured on the chaincode stream. Shutting down the chaincode stream."
217+ + Logging .formatError (t ));
204218
205219 chaincodeSupportClient .shutdown (itm );
206220 }
@@ -220,11 +234,14 @@ public void onCompleted() {
220234
221235 /**
222236 * connect external chaincode to peer for chat.
237+ *
223238 * @param requestObserver reqeust from peer
224- * @return itm - The InnvocationTask Manager handles the message level communication with the peer.
239+ * @return itm - The InnvocationTask Manager handles the message level
240+ * communication with the peer.
225241 * @throws IOException validation fields exception
226242 */
227- protected StreamObserver <ChaincodeShim .ChaincodeMessage > connectToPeer (final StreamObserver <ChaincodeMessage > requestObserver ) throws IOException {
243+ protected StreamObserver <ChaincodeShim .ChaincodeMessage > connectToPeer (
244+ final StreamObserver <ChaincodeMessage > requestObserver ) throws IOException {
228245 validateOptions ();
229246 if (requestObserver == null ) {
230247 throw new IOException ("StreamObserver 'requestObserver' for chat with peer can't be null" );
@@ -254,7 +271,8 @@ public void onNext(final ChaincodeMessage chaincodeMessage) {
254271
255272 @ Override
256273 public void onError (final Throwable t ) {
257- LOGGER .severe (() -> "An error occured on the chaincode stream. Shutting down the chaincode stream." + Logging .formatError (t ));
274+ LOGGER .severe (() -> "An error occured on the chaincode stream. Shutting down the chaincode stream."
275+ + Logging .formatError (t ));
258276
259277 chaincodeSupportClient .shutdown (itm );
260278 }
@@ -310,33 +328,60 @@ private Level mapLevel(final String level) {
310328
311329 if (level != null ) {
312330 switch (level .toUpperCase ().trim ()) {
313- case "CRITICAL" :
314- case "ERROR" :
315- return Level .SEVERE ;
316- case "WARNING" :
317- case "WARN" :
318- return Level .WARNING ;
319- case "INFO" :
320- return Level .INFO ;
321- case "NOTICE" :
322- return Level .CONFIG ;
323- case "DEBUG" :
324- return Level .FINEST ;
325- default :
326- break ;
331+ case "CRITICAL" :
332+ case "ERROR" :
333+ return Level .SEVERE ;
334+ case "WARNING" :
335+ case "WARN" :
336+ return Level .WARNING ;
337+ case "INFO" :
338+ return Level .INFO ;
339+ case "NOTICE" :
340+ return Level .CONFIG ;
341+ case "DEBUG" :
342+ return Level .FINEST ;
343+ default :
344+ break ;
327345 }
328346 }
329347 return Level .INFO ;
330348 }
331349
350+
351+ private SocketAddress parseHostPort (final String hostAddrStr ) {
352+ String [] hostArr = hostAddrStr .split (":" );
353+ String h ;
354+ int p ;
355+
356+ if (hostArr .length == 2 ) {
357+ p = Integer .valueOf (hostArr [1 ].trim ());
358+ h = hostArr [0 ].trim ();
359+ } else {
360+ final String msg = String .format (
361+ "peer address argument should be in host:port format, current %s in wrong" , hostAddrStr );
362+ LOGGER .severe (msg );
363+ throw new IllegalArgumentException (msg );
364+ }
365+ return new InetSocketAddress (h , p );
366+ }
367+
368+ /**
369+ * Use the CHAINCODE_SERVER_ADDRESS as the key to swap mode.
370+ *
371+ * @return true if this should be run as `chaincode-as-a-service`
372+ */
373+ public boolean isServer () {
374+ return !chaincodeServerAddress .isEmpty ();
375+ }
376+
332377 /**
333378 * Validate init parameters from env chaincode base.
334379 */
335380 public void validateOptions () {
336381 if (this .id == null || this .id .isEmpty ()) {
337- throw new IllegalArgumentException (
338- format ( "The chaincode id must be specified using either the -i or --i command line options or the %s environment variable." ,
339- CORE_CHAINCODE_ID_NAME ));
382+ throw new IllegalArgumentException (format (
383+ "The chaincode id must be specified using either the -i or --i command line options or the %s environment variable." ,
384+ CORE_CHAINCODE_ID_NAME ));
340385 }
341386 if (this .tlsEnabled ) {
342387 if (tlsClientCertPath == null ) {
@@ -390,10 +435,7 @@ protected final void processCommandLineOptions(final String[] args) {
390435 LOGGER .info ("<<<<<<<<<<<<<CommandLine options>>>>>>>>>>>>" );
391436 LOGGER .info ("CORE_CHAINCODE_ID_NAME: " + this .id );
392437 LOGGER .info ("CORE_PEER_ADDRESS: " + this .host + ":" + this .port );
393- LOGGER .info ("CORE_PEER_TLS_ENABLED: " + this .tlsEnabled );
394- LOGGER .info ("CORE_PEER_TLS_ROOTCERT_FILE: " + this .tlsClientRootCertPath );
395- LOGGER .info ("CORE_TLS_CLIENT_KEY_PATH: " + this .tlsClientKeyPath );
396- LOGGER .info ("CORE_TLS_CLIENT_CERT_PATH: " + this .tlsClientCertPath );
438+
397439 }
398440
399441 /**
@@ -417,6 +459,10 @@ public final void processEnvironmentOptions() {
417459 }
418460 }
419461
462+ if (System .getenv ().containsKey (CHAINCODE_SERVER_ADDRESS )) {
463+ this .chaincodeServerAddress = System .getenv (CHAINCODE_SERVER_ADDRESS );
464+ }
465+
420466 if (System .getenv ().containsKey (CORE_PEER_LOCALMSPID )) {
421467 this .localMspId = System .getenv (CORE_PEER_LOCALMSPID );
422468 }
@@ -426,6 +472,9 @@ public final void processEnvironmentOptions() {
426472 this .tlsClientRootCertPath = System .getenv (CORE_PEER_TLS_ROOTCERT_FILE );
427473 this .tlsClientKeyPath = System .getenv (ENV_TLS_CLIENT_KEY_PATH );
428474 this .tlsClientCertPath = System .getenv (ENV_TLS_CLIENT_CERT_PATH );
475+
476+ this .tlsClientKeyFile = System .getenv (ENV_TLS_CLIENT_KEY_FILE );
477+ this .tlsClientCertFile = System .getenv (ENV_TLS_CLIENT_CERT_FILE );
429478 }
430479
431480 LOGGER .info ("<<<<<<<<<<<<<Environment options>>>>>>>>>>>>" );
@@ -435,7 +484,10 @@ public final void processEnvironmentOptions() {
435484 LOGGER .info ("CORE_PEER_TLS_ROOTCERT_FILE: " + this .tlsClientRootCertPath );
436485 LOGGER .info ("CORE_TLS_CLIENT_KEY_PATH: " + this .tlsClientKeyPath );
437486 LOGGER .info ("CORE_TLS_CLIENT_CERT_PATH: " + this .tlsClientCertPath );
487+ LOGGER .info ("CORE_TLS_CLIENT_KEY_FILE: " + this .tlsClientKeyFile );
488+ LOGGER .info ("CORE_TLS_CLIENT_CERT_FILE: " + this .tlsClientCertFile );
438489 LOGGER .info ("CORE_PEER_LOCALMSPID: " + this .localMspId );
490+ LOGGER .info ("CHAINCODE_SERVER_ADDRESS: " + this .chaincodeServerAddress );
439491 LOGGER .info ("LOGLEVEL: " + this .logLevel );
440492 }
441493
@@ -473,6 +525,26 @@ public Properties getChaincodeConfig() {
473525 return this .props ;
474526 }
475527
528+ /**
529+ * The properties for starting as chaincode-as-a-service.
530+ *
531+ * @return ChaincodeServerProperties populated
532+ */
533+ public final ChaincodeServerProperties getChaincodeServerConfig () {
534+ ChaincodeServerProperties chaincodeServerProperties = new ChaincodeServerProperties ();
535+
536+ chaincodeServerProperties .setServerAddress (parseHostPort (chaincodeServerAddress ));
537+
538+ if (tlsEnabled ) {
539+
540+ // set values on the server properties
541+ chaincodeServerProperties .setTlsEnabled (true );
542+ chaincodeServerProperties .setKeyFile (this .tlsClientCertFile );
543+ chaincodeServerProperties .setKeyCertChainFile (this .tlsClientCertFile );
544+ }
545+ return chaincodeServerProperties ;
546+ }
547+
476548 /**
477549 * create NettyChannel for host:port with tls if tlsEnabled.
478550 *
@@ -584,6 +656,7 @@ final String getTlsClientRootCertPath() {
584656
585657 /**
586658 * Chaincode name / Chaincode id.
659+ *
587660 * @return string
588661 */
589662 String getId () {
0 commit comments