13
13
import java .io .File ;
14
14
import java .io .IOException ;
15
15
import java .io .InputStream ;
16
+ import java .net .InetSocketAddress ;
17
+ import java .net .SocketAddress ;
16
18
import java .nio .file .Files ;
17
19
import java .nio .file .Paths ;
18
20
import java .security .Security ;
51
53
* Abstract implementation of {@link Chaincode}.
52
54
*
53
55
* <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.
56
61
*
57
62
* @see org.hyperledger.fabric.contract
58
63
*/
@@ -96,17 +101,23 @@ public abstract class ChaincodeBase implements Chaincode {
96
101
private boolean tlsEnabled = false ;
97
102
private String tlsClientKeyPath ;
98
103
private String tlsClientCertPath ;
104
+ private String tlsClientKeyFile ;
105
+ private String tlsClientCertFile ;
99
106
private String tlsClientRootCertPath ;
100
107
101
108
private String id ;
102
109
private String localMspId = "" ;
110
+ private String chaincodeServerAddress = "" ;
103
111
112
+ private static final String CHAINCODE_SERVER_ADDRESS = "CHAINCODE_SERVER_ADDRESS" ;
104
113
private static final String CORE_CHAINCODE_ID_NAME = "CORE_CHAINCODE_ID_NAME" ;
105
114
private static final String CORE_PEER_ADDRESS = "CORE_PEER_ADDRESS" ;
106
115
private static final String CORE_PEER_TLS_ENABLED = "CORE_PEER_TLS_ENABLED" ;
107
116
private static final String CORE_PEER_TLS_ROOTCERT_FILE = "CORE_PEER_TLS_ROOTCERT_FILE" ;
108
117
private static final String ENV_TLS_CLIENT_KEY_PATH = "CORE_TLS_CLIENT_KEY_PATH" ;
109
118
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" ;
110
121
private static final String CORE_PEER_LOCALMSPID = "CORE_PEER_LOCALMSPID" ;
111
122
private static final String MAX_INBOUND_MESSAGE_SIZE = "MAX_INBOUND_MESSAGE_SIZE" ;
112
123
private Properties props ;
@@ -120,8 +131,10 @@ private int getMaxInboundMessageSize() {
120
131
if (this .props == null ) {
121
132
throw new IllegalStateException ("Chaincode config not available" );
122
133
}
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 );
125
138
LOGGER .info (msgSizeInfo );
126
139
return maxMsgSize ;
127
140
}
@@ -165,7 +178,6 @@ protected final void connectToPeer() throws IOException {
165
178
166
179
final InvocationTaskManager itm = InvocationTaskManager .getManager (this , chaincodeId );
167
180
168
-
169
181
// This is a critical method - it is the one time that a
170
182
// protobuf service is invoked. The single 'register' call
171
183
// is made, and two streams are created.
@@ -200,7 +212,9 @@ public void onNext(final ChaincodeMessage chaincodeMessage) {
200
212
201
213
@ Override
202
214
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 ));
204
218
205
219
chaincodeSupportClient .shutdown (itm );
206
220
}
@@ -220,11 +234,14 @@ public void onCompleted() {
220
234
221
235
/**
222
236
* connect external chaincode to peer for chat.
237
+ *
223
238
* @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.
225
241
* @throws IOException validation fields exception
226
242
*/
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 {
228
245
validateOptions ();
229
246
if (requestObserver == null ) {
230
247
throw new IOException ("StreamObserver 'requestObserver' for chat with peer can't be null" );
@@ -254,7 +271,8 @@ public void onNext(final ChaincodeMessage chaincodeMessage) {
254
271
255
272
@ Override
256
273
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 ));
258
276
259
277
chaincodeSupportClient .shutdown (itm );
260
278
}
@@ -310,33 +328,60 @@ private Level mapLevel(final String level) {
310
328
311
329
if (level != null ) {
312
330
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 ;
327
345
}
328
346
}
329
347
return Level .INFO ;
330
348
}
331
349
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
+
332
377
/**
333
378
* Validate init parameters from env chaincode base.
334
379
*/
335
380
public void validateOptions () {
336
381
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 ));
340
385
}
341
386
if (this .tlsEnabled ) {
342
387
if (tlsClientCertPath == null ) {
@@ -390,10 +435,7 @@ protected final void processCommandLineOptions(final String[] args) {
390
435
LOGGER .info ("<<<<<<<<<<<<<CommandLine options>>>>>>>>>>>>" );
391
436
LOGGER .info ("CORE_CHAINCODE_ID_NAME: " + this .id );
392
437
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
+
397
439
}
398
440
399
441
/**
@@ -417,6 +459,10 @@ public final void processEnvironmentOptions() {
417
459
}
418
460
}
419
461
462
+ if (System .getenv ().containsKey (CHAINCODE_SERVER_ADDRESS )) {
463
+ this .chaincodeServerAddress = System .getenv (CHAINCODE_SERVER_ADDRESS );
464
+ }
465
+
420
466
if (System .getenv ().containsKey (CORE_PEER_LOCALMSPID )) {
421
467
this .localMspId = System .getenv (CORE_PEER_LOCALMSPID );
422
468
}
@@ -426,6 +472,9 @@ public final void processEnvironmentOptions() {
426
472
this .tlsClientRootCertPath = System .getenv (CORE_PEER_TLS_ROOTCERT_FILE );
427
473
this .tlsClientKeyPath = System .getenv (ENV_TLS_CLIENT_KEY_PATH );
428
474
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 );
429
478
}
430
479
431
480
LOGGER .info ("<<<<<<<<<<<<<Environment options>>>>>>>>>>>>" );
@@ -435,7 +484,10 @@ public final void processEnvironmentOptions() {
435
484
LOGGER .info ("CORE_PEER_TLS_ROOTCERT_FILE: " + this .tlsClientRootCertPath );
436
485
LOGGER .info ("CORE_TLS_CLIENT_KEY_PATH: " + this .tlsClientKeyPath );
437
486
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 );
438
489
LOGGER .info ("CORE_PEER_LOCALMSPID: " + this .localMspId );
490
+ LOGGER .info ("CHAINCODE_SERVER_ADDRESS: " + this .chaincodeServerAddress );
439
491
LOGGER .info ("LOGLEVEL: " + this .logLevel );
440
492
}
441
493
@@ -473,6 +525,26 @@ public Properties getChaincodeConfig() {
473
525
return this .props ;
474
526
}
475
527
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
+
476
548
/**
477
549
* create NettyChannel for host:port with tls if tlsEnabled.
478
550
*
@@ -584,6 +656,7 @@ final String getTlsClientRootCertPath() {
584
656
585
657
/**
586
658
* Chaincode name / Chaincode id.
659
+ *
587
660
* @return string
588
661
*/
589
662
String getId () {
0 commit comments