@@ -19,7 +19,6 @@ const fs = require('fs-extra');
1919const HLFSecurityContext = require ( './hlfsecuritycontext' ) ;
2020const HLFUtil = require ( './hlfutil' ) ;
2121const HLFTxEventHandler = require ( './hlftxeventhandler' ) ;
22- const HLFQueryHandler = require ( './hlfqueryhandler' ) ;
2322const Logger = require ( 'composer-common' ) . Logger ;
2423const path = require ( 'path' ) ;
2524const temp = require ( 'temp' ) . track ( ) ;
@@ -44,6 +43,7 @@ const installDependencies = {
4443
4544const chaincodePathSection = 'businessnetwork' ;
4645
46+ let HLFQueryHandler ;
4747/**
4848 * Class representing a connection to a business network running on Hyperledger
4949 * Fabric, using the hfc module.
@@ -67,10 +67,18 @@ class HLFConnection extends Connection {
6767 /**
6868 * create a new Query Handler.
6969 * @param {HLFConnection } connection The connection to be used by the query handler.
70+ * @param {string } queryHandlerImpl The query handler to require
7071 * @return {HLFQueryManager } A new query manager.
7172 */
72- static createQueryHandler ( connection ) {
73- return new HLFQueryHandler ( connection ) ;
73+ static createQueryHandler ( connection , queryHandlerImpl ) {
74+ const method = 'createQueryHandler' ;
75+ if ( typeof queryHandlerImpl === 'string' ) {
76+ LOG . info ( method , `attemping to load query handler module ${ queryHandlerImpl } ` ) ;
77+ HLFQueryHandler = require ( queryHandlerImpl ) ;
78+ return new HLFQueryHandler ( connection ) ;
79+ } else {
80+ return new queryHandlerImpl ( connection ) ;
81+ }
7482 }
7583
7684 /**
@@ -128,7 +136,14 @@ class HLFConnection extends Connection {
128136 this . caClient = caClient ;
129137 this . initialized = false ;
130138 this . commitTimeout = connectOptions [ 'x-commitTimeout' ] ? connectOptions [ 'x-commitTimeout' ] * 1000 : 300 * 1000 ;
131- this . queryHandler = HLFConnection . createQueryHandler ( this ) ;
139+
140+ let queryHandlerImpl = './hlfqueryhandler' ;
141+ if ( process . env . COMPOSER_QUERY_HANDLER && process . env . COMPOSER_QUERY_HANDLER . length !== 0 ) {
142+ queryHandlerImpl = process . env . COMPOSER_QUERY_HANDLER ;
143+ } else if ( connectOptions . queryHandler && connectOptions . queryHandler . length !== 0 ) {
144+ queryHandlerImpl = connectOptions . queryHandler ;
145+ }
146+ this . queryHandler = HLFConnection . createQueryHandler ( this , queryHandlerImpl ) ;
132147 LOG . debug ( method , `commit timeout set to ${ this . commitTimeout } ` ) ;
133148
134149 // We create promisified versions of these APIs.
@@ -1307,6 +1322,83 @@ class HLFConnection extends Connection {
13071322 return txId ;
13081323 }
13091324
1325+ /**
1326+ * Send a query
1327+ * @param {Peer } peer The peer to query
1328+ * @param {TransactionID } txId the transaction id to use
1329+ * @param {string } functionName the function name of the query
1330+ * @param {array } args the arguments to ass
1331+ * @returns {Buffer } asynchronous response to query
1332+ */
1333+ async querySinglePeer ( peer , txId , functionName , args ) {
1334+ const method = 'querySinglePeer' ;
1335+ LOG . entry ( method , peer . getName ( ) , txId , functionName , args ) ;
1336+ const request = {
1337+ targets : [ peer ] ,
1338+ chaincodeId : this . businessNetworkIdentifier ,
1339+ txId : txId ,
1340+ fcn : functionName ,
1341+ args : args
1342+ } ;
1343+
1344+ const t0 = Date . now ( ) ;
1345+ let payloads = await this . queryByChaincode ( request ) ;
1346+ LOG . perf ( method , `Total duration for queryByChaincode to ${ functionName } : ` , txId , t0 ) ;
1347+ LOG . debug ( method , `Received ${ payloads . length } payloads(s) from querying the composer runtime chaincode` ) ;
1348+ if ( ! payloads . length ) {
1349+ LOG . error ( method , 'No payloads were returned from the query request:' + functionName ) ;
1350+ throw new Error ( 'No payloads were returned from the query request:' + functionName ) ;
1351+ }
1352+ const payload = payloads [ 0 ] ;
1353+
1354+ // if it has a code value is 14, means unavailable, so throw that error
1355+ // code 2 looks like it is a chaincode response that was an error.
1356+ if ( payload instanceof Error && payload . code && ( payload . code === 14 || payload . code === 1 || payload . code === 4 ) ) {
1357+ throw payload ;
1358+ }
1359+
1360+ LOG . exit ( method , payload ) ;
1361+ return payload ;
1362+
1363+ }
1364+
1365+ /**
1366+ * Perform a chaincode query and parse the responses.
1367+ * @param {object } request the proposal for a query
1368+ * @return {array } the responses
1369+ */
1370+ async queryByChaincode ( request ) {
1371+ const method = 'queryByChaincode' ;
1372+ LOG . entry ( method , request ) ;
1373+ try {
1374+ const results = await this . channel . sendTransactionProposal ( request ) ;
1375+ const responses = results [ 0 ] ;
1376+ if ( responses && Array . isArray ( responses ) ) {
1377+ let results = [ ] ;
1378+ for ( let i = 0 ; i < responses . length ; i ++ ) {
1379+ let response = responses [ i ] ;
1380+ if ( response instanceof Error ) {
1381+ results . push ( response ) ;
1382+ }
1383+ else if ( response . response && response . response . payload ) {
1384+ results . push ( response . response . payload ) ;
1385+ }
1386+ else {
1387+ results . push ( new Error ( response ) ) ;
1388+ }
1389+ }
1390+ LOG . exit ( method ) ;
1391+ return results ;
1392+ }
1393+ const err = new Error ( 'Payload results are missing from the chaincode query' ) ;
1394+ LOG . error ( method , err ) ;
1395+ throw err ;
1396+ } catch ( err ) {
1397+ LOG . error ( method , err ) ;
1398+ throw err ;
1399+ }
1400+ }
1401+
13101402}
13111403
13121404module . exports = HLFConnection ;
0 commit comments