Skip to content

Commit

Permalink
FABN-856 submitTransaction API
Browse files Browse the repository at this point in the history
Add proper support for mutual TLS
Improve javadoc

Change-Id: I210abfbbd8dbd94d59393af739f3085d719ad623
Signed-off-by: Dave Kelsey <d_kelsey@uk.ibm.com>
  • Loading branch information
Dave Kelsey committed Aug 23, 2018
1 parent 39ceca3 commit 5ef917f
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 27 deletions.
13 changes: 8 additions & 5 deletions fabric-network/lib/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class Channel {

/**
* Channel constructor for internal use only
* @param network
* @param channel
* @param {Network} network The owning network instance
* @param {Channel} channel The fabric-client channel instance
* @private
*/
constructor(network, channel) {
Expand Down Expand Up @@ -107,6 +107,11 @@ class Channel {
}
}

/**
* Initialize this channel instance
* @private
* @memberof Channel
*/
async _initialize() {
logger.debug('in initialize');

Expand Down Expand Up @@ -140,16 +145,14 @@ class Channel {
*/
getContract(chaincodeId) {
logger.debug('in getContract');

// check initialized flag
// Create the new Contract
let contract = this.contracts.get(chaincodeId);
if (!contract) {
contract = new Contract(
this.channel,
chaincodeId,
this.network
);
this.contracts.set(chaincodeId, contract);
}
return contract;
}
Expand Down
40 changes: 27 additions & 13 deletions fabric-network/lib/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,28 @@ class Network {

// default options
this.options = {
commitTimeout: 300 * 1000,
commitTimeout: 300 * 1000
};
}

/**
* @typedef {Object} NetworkOptions
* @property {Wallet} wallet The identity wallet implementation for use with this network instance
* @property {string} identity The identity in the wallet for all interactions on this network instance
* @property {string} [clientTlsIdentity] the identity in the wallet to use as the client TLS identity
* @property {number} [commitTimeout = 300000] The timout period in milliseconds to wait for commit notification to complete
*/

/**
* Initialize the network with a connection profile
*
* @param {*} ccp
* @param {*} options
* @param {Client | string} config The configuration for this network which can come from a common connection
* profile or an existing fabric-client Client instance
* @see see {Client}
* @param {NetworkOptions} options specific options for creating this network instance
* @memberof Network
*/
async initialize(ccp, options) {
async initialize(config, options) {
logger.debug('in initialize');

if (!options || !options.wallet) {
Expand All @@ -58,27 +68,32 @@ class Network {

Network._mergeOptions(this.options, options);

if (!(ccp instanceof Client)) {
if (!(config instanceof Client)) {
// still use a ccp for the discovery peer and ca information
logger.debug('initialize: loading client from ccp');
this.client = Client.loadFromConfig(ccp);
this.client = Client.loadFromConfig(config);
} else {
// initialize from an existing Client object instance
logger.debug('initialize: using existing client object');
this.client = ccp;
this.client = config;
}

// setup an initial identity for the network
if (options.identity) {
logger.debug('initialize: setting identity');
this.currentIdentity = await options.wallet.setUserContext(this.client, options.identity);
}

if (options.clientTlsIdentity) {
const tlsIdentity = await options.wallet.export(options.clientTlsIdentity);
this.client.setTlsClientCertAndKey(tlsIdentity.certificate, tlsIdentity.privateKey);
}
}

/**
* Get the current identity
*
* @returns
* @returns {User} a fabric-client User instance of the current identity used by this network
* @memberof Network
*/
getCurrentIdentity() {
Expand All @@ -89,7 +104,7 @@ class Network {
/**
* Get the underlying Client object instance
*
* @returns
* @returns {Client} the underlying fabric-client Client instance
* @memberof Network
*/
getClient() {
Expand All @@ -99,8 +114,8 @@ class Network {

/**
* Returns the set of options associated with the network connection
* @returns {{commitTimeout: number}|*}
* @memberOf Network
* @returns {NetworkOptions} the network options
* @memberof Network
*/
getOptions() {
logger.debug('in getOptions');
Expand All @@ -124,7 +139,7 @@ class Network {
* Returns an object representing the channel
* @param channelName
* @returns {Promise<Channel>}
* @memberOf Network
* @memberof Network
*/
async getChannel(channelName) {
logger.debug('in getChannel');
Expand All @@ -141,5 +156,4 @@ class Network {
}
}


module.exports = Network;
18 changes: 17 additions & 1 deletion fabric-network/test/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ describe('Network', () => {
network.currentIdentity.should.equal('foo');
});

it('should initialize the network with identity and set client tls crypto material', async () => {
mockWallet.export.withArgs('tlsId').resolves({certificate: 'acert', privateKey: 'akey'});

const options = {
wallet: mockWallet,
identity: 'admin',
clientTlsIdentity: 'tlsId'
};
await network.initialize('ccp', options);
network.client.should.equal(mockClient);
network.currentIdentity.should.equal('foo');
sinon.assert.calledOnce(mockClient.setTlsClientCertAndKey);
sinon.assert.calledWith(mockClient.setTlsClientCertAndKey, 'acert', 'akey');
});


it('should initialize from an existing client object', async () => {
const options = {
wallet: mockWallet,
Expand Down Expand Up @@ -287,4 +303,4 @@ describe('Network', () => {
});
});

});
});
20 changes: 12 additions & 8 deletions test/integration/network-e2e/invoke.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,18 @@ test('\n\n***** Network End-to-end flow: invoke transaction to move money using
t.fail('Failed to import User1@org1.example.com into wallet');
}

const tlsInfo = await e2eUtils.tlsEnroll('org1');
await inMemoryWallet.import('tlsId', X509WalletMixin.createIdentity('org1', tlsInfo.certificate, tlsInfo.key));

const network = new Network();

const ccp = fs.readFileSync(fixtures + '/network.json');
await network.initialize(JSON.parse(ccp.toString()), {
wallet: inMemoryWallet,
identity: 'User1@org1.example.com'
identity: 'User1@org1.example.com',
clientTlsIdentity: 'tlsId'
});

const tlsInfo = await e2eUtils.tlsEnroll('org1');
network.getClient().setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key);

t.pass('Initialized the network');

const channel = await network.getChannel(channelName);
Expand Down Expand Up @@ -103,18 +104,21 @@ test('\n\n***** Network End-to-end flow: invoke transaction to move money using
await fileSystemWallet.import(identityLabel, X509WalletMixin.createIdentity('Org1MSP', cert, key));
const exists = await fileSystemWallet.exists(identityLabel);
t.ok(exists, 'Successfully imported User1@org1.example.com into wallet');
const tlsInfo = await e2eUtils.tlsEnroll('org1');

await fileSystemWallet.import('tlsId', X509WalletMixin.createIdentity('org1', tlsInfo.certificate, tlsInfo.key));



const network = new Network();

const ccp = fs.readFileSync(fixtures + '/network.json');
await network.initialize(JSON.parse(ccp.toString()), {
wallet: fileSystemWallet,
identity: identityLabel
identity: identityLabel,
clientTlsIdentity: 'tlsId'
});

const tlsInfo = await e2eUtils.tlsEnroll('org1');
network.getClient().setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key);

t.pass('Initialized the network');

const channel = await network.getChannel(channelName);
Expand Down

0 comments on commit 5ef917f

Please sign in to comment.