Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/composer-admin/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class AdminConnection {
+ Promise getProfile(string)
+ Promise getAllProfiles()
+ Promise disconnect()
+ Promise install(BusinessNetworkIdentifier,Object)
+ Promise start(BusinessNetworkDefinition,Object)
+ Promise deploy(BusinessNetworkDefinition,Object)
+ Promise undeploy(string)
+ Promise update(BusinessNetworkDefinition)
Expand Down
3 changes: 3 additions & 0 deletions packages/composer-admin/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#
# Note that the latest public API is documented using JSDocs and is available in api.txt.
#
Version 0.10.0 {3af411e8da53bb013ab9718ed5980c20} 2017-07-17
- added install and start method.

Version 0.9.1 {8b6c392e59b8ad38ea271315231ca0e5} 2017-06-30
- added getLogLevel & setLogLevel methods. added deployOptions to deploy method.

Expand Down
52 changes: 52 additions & 0 deletions packages/composer-admin/lib/adminconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,58 @@ class AdminConnection {
});
}

/**
* Installs the Hyperledger Composer runtime to the Hyperledger Fabric in preparation
* for the business network to be started. The connection mustbe connected for this method to succeed.
* You must pass the name of the business network that is defined in your archive that this
* runtime will be started with.
* @example
* // Install the Hyperledger Composer runtime
* var adminConnection = new AdminConnection();
* var businessNetworkDefinition = BusinessNetworkDefinition.fromArchive(myArchive);
* return adminConnection.install(businessNetworkDefinition.getName())
* .then(function(){
* // Business network definition installed
* })
* .catch(function(error){
* // Add optional error handling here.
* });
* @param {BusinessNetworkIdentifier} businessNetworkIdentifier - The name of business network which will be used to start this runtime.
* @param {Object} installOptions connector specific install options
* @return {Promise} A promise that will be fufilled when the business network has been
* deployed.
*/
install(businessNetworkIdentifier, installOptions) {
Util.securityCheck(this.securityContext);
return this.connection.install(this.securityContext, businessNetworkIdentifier, installOptions);
}

/**
* Starts a business network within the runtime previously installed to the Hyperledger Fabric with
* the same name as the business network to be started. The connection must be connected for this
* method to succeed.
* @example
* // Start a Business Network Definition
* var adminConnection = new AdminConnection();
* var businessNetworkDefinition = BusinessNetworkDefinition.fromArchive(myArchive);
* return adminConnection.start(businessNetworkDefinition)
* .then(function(){
* // Business network definition is started
* })
* .catch(function(error){
* // Add optional error handling here.
* });
* @param {BusinessNetworkDefinition} businessNetworkDefinition - The business network to start
* @param {Object} startOptions connector specific start options
* @return {Promise} A promise that will be fufilled when the business network has been
* deployed.
*/
start(businessNetworkDefinition, startOptions) {
Util.securityCheck(this.securityContext);
return this.connection.start(this.securityContext, businessNetworkDefinition, startOptions);
}


/**
* Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must
* be connected for this method to succeed.
Expand Down
67 changes: 67 additions & 0 deletions packages/composer-admin/test/adminconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ describe('AdminConnection', () => {
mockConnection.disconnect.resolves();
mockConnection.login.resolves(mockSecurityContext);
mockConnection.deploy.resolves();
mockConnection.install.resolves();
mockConnection.start.resolves();
mockConnection.ping.resolves();
mockConnection.queryChainCode.resolves();
mockConnection.invokeChainCode.resolves();
Expand Down Expand Up @@ -200,6 +202,59 @@ describe('AdminConnection', () => {
});
});

describe('#install', () => {

it('should be able to install a business network definition', () => {
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;
let businessNetworkDefinition = new BusinessNetworkDefinition('name@1.0.0');
return adminConnection.install(businessNetworkDefinition)
.then(() => {
sinon.assert.calledOnce(mockConnection.install);
sinon.assert.calledWith(mockConnection.install, mockSecurityContext, businessNetworkDefinition);
});
});

it('should be able to install a business network definition with install options', () => {
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;
let businessNetworkDefinition = new BusinessNetworkDefinition('name@1.0.0');
return adminConnection.install(businessNetworkDefinition, {opt: 1})
.then(() => {
sinon.assert.calledOnce(mockConnection.install);
sinon.assert.calledWith(mockConnection.install, mockSecurityContext, businessNetworkDefinition, {opt: 1});
});
});

});

describe('#start', () => {

it('should be able to start a business network definition', () => {
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;
let businessNetworkDefinition = new BusinessNetworkDefinition('name@1.0.0');
return adminConnection.start(businessNetworkDefinition)
.then(() => {
sinon.assert.calledOnce(mockConnection.start);
sinon.assert.calledWith(mockConnection.start, mockSecurityContext, businessNetworkDefinition);
});
});

it('should be able to start a business network definition with start options', () => {
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;
let businessNetworkDefinition = new BusinessNetworkDefinition('name@1.0.0');
return adminConnection.start(businessNetworkDefinition, {opt: 1})
.then(() => {
sinon.assert.calledOnce(mockConnection.start);
sinon.assert.calledWith(mockConnection.start, mockSecurityContext, businessNetworkDefinition, {opt: 1});
});
});

});


describe('#deploy', () => {

it('should be able to deploy a business network definition', () => {
Expand All @@ -212,6 +267,18 @@ describe('AdminConnection', () => {
sinon.assert.calledWith(mockConnection.deploy, mockSecurityContext, businessNetworkDefinition);
});
});

it('should be able to deploy a business network definition with deployOptions', () => {
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;
let businessNetworkDefinition = new BusinessNetworkDefinition('name@1.0.0');
return adminConnection.deploy(businessNetworkDefinition, {opt: 1})
.then(() => {
sinon.assert.calledOnce(mockConnection.deploy);
sinon.assert.calledWith(mockConnection.deploy, mockSecurityContext, businessNetworkDefinition, {opt: 1});
});
});

});

describe('#undeploy', () => {
Expand Down
124 changes: 124 additions & 0 deletions packages/composer-cli/lib/cmds/network/lib/start.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const Admin = require('composer-admin');
const BusinessNetworkDefinition = Admin.BusinessNetworkDefinition;
const cmdUtil = require('../../utils/cmdutils');
const fs = require('fs');

const ora = require('ora');
const chalk = require('chalk');
const LogLevel = require('../../network/lib/loglevel');


/**
* <p>
* Composer deploy command
* </p>
* <p><a href="diagrams/Deploy.svg"><img src="diagrams/deploy.svg" style="width:100%;"/></a></p>
* @private
*/
class Start {

/**
* Command process for deploy command
* @param {string} argv argument list from composer command
* @param {boolean} updateOption true if the network is to be updated
* @return {Promise} promise when command complete
*/
static handler(argv, updateOption) {

let updateBusinessNetwork = (updateOption === true)
? true
: false;
let businessNetworkDefinition;

let adminConnection;
let businessNetworkName;
let spinner;
let loglevel;

if (argv.loglevel) {
// validate log level as yargs cannot at this time
// https://github.com/yargs/yargs/issues/849
loglevel = argv.loglevel.toUpperCase();
if (!LogLevel.validLogLevel(loglevel)) {
return Promise.reject(new Error('loglevel unspecified or not one of (INFO|WARNING|ERROR|DEBUG)'));
}
}

return (() => {
console.log(chalk.blue.bold('Starting business network from archive: ')+argv.archiveFile);
let archiveFileContents = null;
// Read archive file contents
archiveFileContents = Start.getArchiveFileContents(argv.archiveFile);
return BusinessNetworkDefinition.fromArchive(archiveFileContents);
})()
.then ((result) => {
businessNetworkDefinition = result;
businessNetworkName = businessNetworkDefinition.getIdentifier();
console.log(chalk.blue.bold('Business network definition:'));
console.log(chalk.blue('\tIdentifier: ')+businessNetworkName);
console.log(chalk.blue('\tDescription: ')+businessNetworkDefinition.getDescription());
console.log();
adminConnection = cmdUtil.createAdminConnection();
return adminConnection.connect(argv.connectionProfileName, argv.startId, argv.startSecret, updateBusinessNetwork ? businessNetworkDefinition.getName() : null);
})
.then((result) => {
if (updateBusinessNetwork === false) {
spinner = ora('Starting business network definition. This may take a minute...').start();
let startOptions = cmdUtil.parseOptions(argv);
if (loglevel) {
startOptions.logLevel = loglevel;
}
return adminConnection.start(businessNetworkDefinition, startOptions);
} else {
spinner = ora('Updating business network definition. This may take a few seconds...').start();
return adminConnection.update(businessNetworkDefinition);
}
}).then((result) => {
spinner.succeed();
console.log();

return result;
}).catch((error) => {

if (spinner) {
spinner.fail();
}

console.log();

throw error;
});
}

/**
* Get contents from archive file
* @param {string} archiveFile connection profile name
* @return {String} archiveFileContents archive file contents
*/
static getArchiveFileContents(archiveFile) {
let archiveFileContents;
if (fs.existsSync(archiveFile)) {
archiveFileContents = fs.readFileSync(archiveFile);
} else {
throw new Error('Archive file '+archiveFile+' does not exist.');
}
return archiveFileContents;
}
}
module.exports = Start;
42 changes: 42 additions & 0 deletions packages/composer-cli/lib/cmds/network/startCommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const Start = require ('./lib/start.js');

module.exports.command = 'start [options]';
module.exports.describe = 'Starts a business network';
module.exports.builder = {
archiveFile: {alias: 'a', required: true, describe: 'The business network archive file name', type: 'string' },
connectionProfileName: {alias: 'p', optional: true, describe: 'The connection profile name', type: 'string' },
loglevel: { alias: 'l', required: false, describe: 'The initial loglevel to set (INFO|WARNING|ERROR|DEBUG)', type: 'string' },
option: { alias: 'o', required: false, describe: 'Options that are specific specific to connection. Multiple options are specified by repeating this option', type: 'string' },
optionsFile: { alias: 'O', required: false, describe: 'A file containing options that are specific to connection', type: 'string' },
startId: { alias: 'i', required: true, describe: 'The id of the user permitted to start a network', type: 'string' },
startSecret: { alias: 's', required: false, describe: 'The secret of the user permitted to start a network, if required', type: 'string' }
};

module.exports.handler = (argv) => {
argv.thePromise = Start.handler(argv)
.then(() => {
return;
})
.catch((error) => {
throw error;

});

return argv.thePromise;
};
25 changes: 25 additions & 0 deletions packages/composer-cli/lib/cmds/runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

exports.command = 'runtime <subcommand>';
exports.desc = 'Composer runtime command';
exports.builder = function (yargs) {
// apply commands in subdirectories
return yargs.commandDir('runtime');
};
exports.handler = function (argv) {

};
Loading