diff --git a/libraries/fabric-shim/lib/handler.js b/libraries/fabric-shim/lib/handler.js index eac09843..3c882b25 100644 --- a/libraries/fabric-shim/lib/handler.js +++ b/libraries/fabric-shim/lib/handler.js @@ -35,6 +35,7 @@ const MSG_TYPE = { INIT: peer.ChaincodeMessage.Type.INIT, TRANSACTION: peer.ChaincodeMessage.Type.TRANSACTION, COMPLETED: peer.ChaincodeMessage.Type.COMPLETED, + KEEPALIVE: peer.ChaincodeMessage.Type.KEEPALIVE, }; /* @@ -295,6 +296,12 @@ class ChaincodeMessageHandler { stream.on('data', (msgpb) => { const msg = mapFromChaincodeMessage(msgpb); logger.debug(util.format('Received chat message from peer: %s, state: %s, type: %s', msg.txid, state, msg.type)); + + if (msg.type === MSG_TYPE.KEEPALIVE) { + stream.write(msgpb); + return; + } + if (state === STATES.Ready) { const type = msg.type; diff --git a/libraries/fabric-shim/test/unit/handler.js b/libraries/fabric-shim/test/unit/handler.js index a8c0526c..80780c0e 100644 --- a/libraries/fabric-shim/test/unit/handler.js +++ b/libraries/fabric-shim/test/unit/handler.js @@ -783,6 +783,41 @@ describe('Handler', () => { expect(handleTransactionSpy.firstCall.args).to.deep.equal([mapFromChaincodeMessage(readyMsg)]); }); + it ('should echo KEEPALIVE when in state ready and MSG_TYPE equals KEEPALIVE', () => { + const processStub = sinon.stub(process, 'exit'); + + eventReg.data(registeredMsg); + eventReg.data(establishedMsg); + + const keepaliveMsg = mapToChaincodeMessage({ + type: MSG_TYPE.KEEPALIVE + }); + + eventReg.data(keepaliveMsg); + + expect(mockStream.write.calledTwice).to.be.true; + expect(mockStream.write.secondCall.args).to.deep.equal([keepaliveMsg]); + expect(mockNewErrorMsg.notCalled).to.be.true; + expect(handleMsgResponseSpy.notCalled).to.be.true; + expect(handleInitSpy.notCalled).to.be.true; + expect(handleTransactionSpy.notCalled).to.be.true; + expect(processStub.notCalled).to.be.true; + + processStub.restore(); + }); + + it ('should echo KEEPALIVE when in state created and MSG_TYPE equals KEEPALIVE', () => { + const keepaliveMsg = mapToChaincodeMessage({ + type: MSG_TYPE.KEEPALIVE + }); + + eventReg.data(keepaliveMsg); + + expect(mockStream.write.calledTwice).to.be.true; + expect(mockStream.write.secondCall.args).to.deep.equal([keepaliveMsg]); + expect(mockNewErrorMsg.notCalled).to.be.true; + }); + it ('should end the process with value 1', () => { const processStub = sinon.stub(process, 'exit');