diff --git a/packages/composer-connector-hlf/lib/hfcconnection.js b/packages/composer-connector-hlf/lib/hfcconnection.js index 859cd455f0..6066dd7e30 100644 --- a/packages/composer-connector-hlf/lib/hfcconnection.js +++ b/packages/composer-connector-hlf/lib/hfcconnection.js @@ -212,7 +212,7 @@ class HFCConnection extends Connection { }) .then(() => { return HFCUtil - .invokeChainCode(securityContext, 'undeploy', [businessNetworkIdentifier]); + .invokeChainCode(securityContext, 'undeployBusinessNetwork', []); }) .then(() => { try { diff --git a/packages/composer-connector-hlf/test/hfcconnection.js b/packages/composer-connector-hlf/test/hfcconnection.js index 01c2d6fb83..08a9ed5680 100644 --- a/packages/composer-connector-hlf/test/hfcconnection.js +++ b/packages/composer-connector-hlf/test/hfcconnection.js @@ -403,6 +403,18 @@ describe('HFCConnection', () => { }); }).should.throw(/Business network id must be specified/); }); + + it('should make the correct call to the runtime', () => { + connection = new HFCConnection(mockConnectionManager, 'testprofile', null, mockChain, connectOptions); + sandbox.stub(HFCUtil, 'invokeChainCode'); + + return connection.undeploy(mockSecurityContext, 'testnetwork') + .then(() => { + sinon.assert.calledOnce(HFCUtil.invokeChainCode); + sinon.assert.calledWith(HFCUtil.invokeChainCode, mockSecurityContext, 'undeployBusinessNetwork', []); + }); + + }); }); describe('#update', function() { diff --git a/packages/composer-runtime/lib/context.js b/packages/composer-runtime/lib/context.js index 1538093324..c6a4d96f75 100644 --- a/packages/composer-runtime/lib/context.js +++ b/packages/composer-runtime/lib/context.js @@ -81,15 +81,16 @@ class Context { return this.getDataService().getCollection('$sysdata') .then((collection) => { - // check if the network has been undeployed first. if is has throw exception. - if (collection.undeployed){ - throw new Error('Network has already been undeployed'); - } - LOG.debug(method, 'Getting business network archive from the $sysdata collection'); return collection.get('businessnetwork'); }) .then((object) => { + + // check if the network has been undeployed first. if is has throw exception. + if (object.undeployed){ + throw new Error('Network has already been undeployed'); + } + LOG.debug(method, 'Looking in cache for business network', object.hash); let businessNetworkDefinition = businessNetworkCache.get(object.hash); if (businessNetworkDefinition) { diff --git a/packages/composer-runtime/lib/engine.businessnetworks.js b/packages/composer-runtime/lib/engine.businessnetworks.js index e49ccaa580..487658ab35 100644 --- a/packages/composer-runtime/lib/engine.businessnetworks.js +++ b/packages/composer-runtime/lib/engine.businessnetworks.js @@ -62,30 +62,28 @@ class EngineBusinessNetworks { * @return {Promise} A promise that will be resolved when complete, or rejected * with an error. */ - undeploy(context, args){ - const method = 'undeploy'; + undeployBusinessNetwork(context, args){ + const method = 'undeployBusinessNetwork'; LOG.entry(method, context, args); - if (args.length !== 1) { + if (args.length !== 0) { LOG.error(method, 'Invalid arguments', args); - throw new Error(util.format('Invalid arguments "%j" to function "%s", expecting "%j"', args, 'undeploy', ['businessNetworkArchive'])); + throw new Error(util.format('Invalid arguments "%j" to function "%s", expecting "%j"', args, method, [])); } let dataService = context.getDataService(); + let sysdata; return dataService.getCollection('$sysdata') - .then((sysdata) => { - - // set flag in the sysdata to say that this has been undeployed - sysdata.undeployed=true; - // Validate the business network archive and store it. - return sysdata.get('businessnetwork'); - }) - .then((object)=> { - let businessNetworkArchive = Buffer.from(object.data, 'base64'); - return BusinessNetworkDefinition.fromArchive(businessNetworkArchive);}) - .then((businessNetworkDefinition) => { - // Reinitialize the context to reload the business network. - LOG.debug(method, businessNetworkDefinition.getIdentifier()+' has been undeployed'); - LOG.exit(method); - }); + .then((sysdata_) => { + sysdata = sysdata_; + // Validate the business network archive and store it. + return sysdata.get('businessnetwork'); + }) + .then((businessNetwork) => { + businessNetwork.undeployed = true; + return sysdata.update('businessnetwork', businessNetwork); + }) + .then(() => { + LOG.exit(method); + }); } diff --git a/packages/composer-runtime/test/engine.businessnetworks.js b/packages/composer-runtime/test/engine.businessnetworks.js index 4731b13126..791f31884d 100644 --- a/packages/composer-runtime/test/engine.businessnetworks.js +++ b/packages/composer-runtime/test/engine.businessnetworks.js @@ -78,6 +78,30 @@ describe('EngineBusinessNetworks', () => { }); + describe('#undeployBusinessNetwork', () => { + + it('should throw for invalid arguments', () => { + let result = engine.invoke(mockContext, 'undeployBusinessNetwork', ['no', 'args', 'supported']); + return result.should.be.rejectedWith(/Invalid arguments "\["no","args","supported"\]" to function "undeployBusinessNetwork", expecting "\[\]"/); + }); + + it('should set the undeploy flag on a business network', () => { + let businessNetwork = {data:'data', hash: 'hash'}; + let sysdata = sinon.createStubInstance(DataCollection); + mockDataService.getCollection.withArgs('$sysdata').resolves(sysdata); + sysdata.get.withArgs('businessnetwork').resolves(businessNetwork); + + return engine.invoke(mockContext, 'undeployBusinessNetwork', []) + .then(() => { + sinon.assert.calledOnce(sysdata.get); + sinon.assert.calledWith(sysdata.get, 'businessnetwork'); + businessNetwork.undeploy = true; + sinon.assert.calledOnce(sysdata.update); + sinon.assert.calledWith(sysdata.update, 'businessnetwork', businessNetwork); + }); + }); + }); + describe('#updateBusinessNetwork', () => { it('should throw for invalid arguments', () => {