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
26 changes: 26 additions & 0 deletions packages/composer-common/lib/businessnetworkmetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class BusinessNetworkMetadata {
throw new Error('package.json is required and must be an object');
}

if (!packageJson.name || !this._validName(packageJson.name)) {
throw new Error ('business network name can only contain lowercase alphanumerics, _ or -');
}

this.packageJson = packageJson;

if(readme && typeof(readme) !== 'string') {
Expand All @@ -58,6 +62,28 @@ class BusinessNetworkMetadata {
LOG.exit(method);
}

/**
* check to see if it is a valid name. for some reason regex is not working when this executes
* inside the chaincode runtime, which is why regex hasn't been used.
*
* @param {string} name the business network name to check
* @returns {boolean} true if valid, false otherwise
*
* @memberOf BusinessNetworkMetadata
* @private
*/
_validName(name) {
const validChars = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'0','1','2','3','4','5','6','7','8','9','-','_'];
for (let i = 0; i<name.length; i++){
const strChar = name.charAt(i);
if ( validChars.indexOf(strChar) === -1 ) {
return false;
}
}
return true;
}

/**
* Returns the README.md for this business network. This may be null if the business network does not have a README.md
* @return {String} the README.md file for the business network or null
Expand Down
22 changes: 20 additions & 2 deletions packages/composer-common/test/businessnetworkmetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,31 @@ describe('BusinessNetworkMetadata', () => {

it('should throw if readme not specified', () => {
(() => {
new BusinessNetworkMetadata({}, {});
const packageJson = {name: 'foo'};
new BusinessNetworkMetadata(packageJson, {});
}).should.throw(/README must be a string/);
});

it('should throw if business network connection name contains upper case', () => {
(() => {
const readme = 'TEST README';
const packageJson = {name: 'fOo'};
new BusinessNetworkMetadata(packageJson,readme);
}).should.throw(/business network name can only contain/);
});

it('should throw if business network connection name contains dots', () => {
(() => {
const readme = 'TEST README';
const packageJson = {name: 'foo.bar'};
new BusinessNetworkMetadata(packageJson,readme);
}).should.throw(/business network name can only contain/);
});


it('should store package.json and README', () => {
const readme = 'TEST README';
const packageJson = {name: 'Foo'};
const packageJson = {name: 'foo_bar-v1'};
let metadata = new BusinessNetworkMetadata(packageJson,readme);
metadata.getREADME().should.equal(readme);
metadata.getPackageJson().should.equal(packageJson);
Expand Down
2 changes: 1 addition & 1 deletion packages/composer-common/test/codegen/plantumlvisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('PlantUMLVisitor', function(){
const mozartScript = fs.readFileSync(path.resolve(__dirname, '../data/model/mozart.cto.js'), 'utf8');

// create and populate the ModelManager with a model file
const businessNetworkDefinition = new BusinessNetworkDefinition('com.ibm.concerto.mozart.DefraNetwork@1.0.0', 'DEFRA Animal Tracking Network');
const businessNetworkDefinition = new BusinessNetworkDefinition('com-ibm-concerto-mozart-defranetwork@1.0.0', 'DEFRA Animal Tracking Network');
businessNetworkDefinition.getModelManager().addModelFile(mozartModel,'mozart.cto');
const script = businessNetworkDefinition.getScriptManager().createScript('mozart.cto.js', 'JS', mozartScript);
businessNetworkDefinition.getScriptManager().addScript(script);
Expand Down
25 changes: 6 additions & 19 deletions packages/composer-connector-hlfv1/lib/hlfconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,6 @@ class HLFConnection extends Connection {
return new EventHub(clientContext);
}

/**
* generate a valid Ccid
*
* @static
* @param {string} input the name used to define the CCid
* @returns {string} a valid ccid
*
* @memberOf HLFConnection
*/
static generateCcid(input) {
return input.replace(/\./g, '-').replace(/[|&;$%@"<>()+,]/g, '').toLowerCase();
}

/**
* Constructor.
* @param {ConnectionManager} connectionManager The owning connection manager.
Expand Down Expand Up @@ -230,7 +217,7 @@ class HLFConnection extends Connection {
if (this.businessNetworkIdentifier) {

// register a chaincode event listener on the first peer only.
let ccid = HLFConnection.generateCcid(this.businessNetworkIdentifier);
let ccid = this.businessNetworkIdentifier;
LOG.debug(method, 'registerChaincodeEvent', ccid, 'composer');
let ccEvent = this.eventHubs[0].registerChaincodeEvent(ccid, 'composer', (event) => {
let evt = event.payload.toString('utf8');
Expand Down Expand Up @@ -358,7 +345,7 @@ class HLFConnection extends Connection {
const request = {
chaincodePath: chaincodePath,
chaincodeVersion: runtimePackageJSON.version,
chaincodeId: HLFConnection.generateCcid(businessNetwork.getName()),
chaincodeId: businessNetwork.getName(),
txId: txId,
targets: this.channel.getPeers()
};
Expand Down Expand Up @@ -432,7 +419,7 @@ class HLFConnection extends Connection {
const request = {
chaincodePath: chaincodePath,
chaincodeVersion: runtimePackageJSON.version,
chaincodeId: HLFConnection.generateCcid(businessNetwork.getName()),
chaincodeId: businessNetwork.getName(),
txId: finalTxId,
fcn: 'init',
args: [businessNetworkArchive.toString('base64')]
Expand Down Expand Up @@ -503,7 +490,7 @@ class HLFConnection extends Connection {
.then((queryResults) => {
LOG.debug(method, 'Queried instantiated chaincodes', queryResults);
let alreadyInstantiated = queryResults.chaincodes.some((chaincode) => {
return chaincode.path === 'composer' && chaincode.name === HLFConnection.generateCcid(businessNetwork.getName());
return chaincode.path === 'composer' && chaincode.name === businessNetwork.getName();
});
if (alreadyInstantiated) {
LOG.debug(method, 'chaincode already instantiated');
Expand Down Expand Up @@ -714,7 +701,7 @@ class HLFConnection extends Connection {

// Submit the query request.
const request = {
chaincodeId: HLFConnection.generateCcid(this.businessNetworkIdentifier),
chaincodeId: this.businessNetworkIdentifier,
chaincodeVersion: runtimePackageJSON.version,
txId: txId,
fcn: functionName,
Expand Down Expand Up @@ -778,7 +765,7 @@ class HLFConnection extends Connection {

// Submit the transaction to the endorsers.
const request = {
chaincodeId: HLFConnection.generateCcid(this.businessNetworkIdentifier),
chaincodeId: this.businessNetworkIdentifier,
chaincodeVersion: runtimePackageJSON.version,
txId: txId,
fcn: functionName,
Expand Down
45 changes: 18 additions & 27 deletions packages/composer-connector-hlfv1/test/hlfconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('HLFConnection', () => {
mockClient.newTransactionID.returns(mockTransactionID);
mockSecurityContext = sinon.createStubInstance(HLFSecurityContext);
mockBusinessNetwork = sinon.createStubInstance(BusinessNetworkDefinition);
mockBusinessNetwork.getName.returns('org.acme.biznet');
mockBusinessNetwork.getName.returns('org-acme-biznet');
mockBusinessNetwork.toArchive.resolves(Buffer.from('hello world'));
connectOptions = {
channel: 'testchainid',
Expand All @@ -77,22 +77,14 @@ describe('HLFConnection', () => {
mockEventHubDef = {
'eventURL': 'http://localhost:7053'
};
connection = new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', connectOptions, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
connection = new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', connectOptions, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
});

afterEach(() => {
sandbox.restore();
connectorPackageJSON.version = originalVersion;
});

describe('#generateCcid', () => {
it('should create a valid ccid', () => {
HLFConnection.generateCcid('my.domain.biznet').should.equal('my-domain-biznet');
HLFConnection.generateCcid('My.Domain.BIZnet').should.equal('my-domain-biznet');
});

});

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

it('should create a new user', () => {
Expand Down Expand Up @@ -125,38 +117,38 @@ describe('HLFConnection', () => {

it('should throw if connectOptions not specified', () => {
(() => {
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', null, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', null, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
}).should.throw(/connectOptions not specified/);
});

it('should throw if client not specified', () => {
(() => {
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', { type: 'hlfv1' }, null, mockChannel, [mockEventHubDef], mockCAClient);
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', { type: 'hlfv1' }, null, mockChannel, [mockEventHubDef], mockCAClient);
}).should.throw(/client not specified/);
});

it('should throw if channel not specified', () => {
(() => {
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', { type: 'hlfv1' }, mockClient, null, [mockEventHubDef], mockCAClient);
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', { type: 'hlfv1' }, mockClient, null, [mockEventHubDef], mockCAClient);
}).should.throw(/channel not specified/);
});

it('should throw if eventHubDefs not specified', () => {
(() => {
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', { type: 'hlfv1' }, mockClient, mockChannel, null, mockCAClient);
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', { type: 'hlfv1' }, mockClient, mockChannel, null, mockCAClient);
}).should.throw(/eventHubDefs not specified or not an array/);
});

it('should throw if eventHubDefs not an array', () => {
(() => {
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', { type: 'hlfv1' }, mockClient, mockChannel, mockEventHubDef, mockCAClient);
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', { type: 'hlfv1' }, mockClient, mockChannel, mockEventHubDef, mockCAClient);
}).should.throw(/eventHubDefs not specified or not an array/);
});


it('should throw if caClient not specified', () => {
(() => {
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', { type: 'hlfv1' }, mockClient, mockChannel, [mockEventHubDef], null);
new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', { type: 'hlfv1' }, mockClient, mockChannel, [mockEventHubDef], null);
}).should.throw(/caClient not specified/);
});
});
Expand Down Expand Up @@ -193,7 +185,6 @@ describe('HLFConnection', () => {
});

it('should subscribe to the eventHub and emit events', () => {
//sandbox.stub(Buffer, 'from').returns('"{"event":"event"}"');
connection._connectToEventHubs();
const events = {
payload: {
Expand Down Expand Up @@ -592,7 +583,7 @@ describe('HLFConnection', () => {
mspID: 'suchmsp',
timeout: 22
};
connection = new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', connectOptions, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
connection = new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', connectOptions, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
sandbox.stub(connection, '_validateResponses').returns();
sandbox.stub(connection, '_initializeChannel').resolves();
connection._connectToEventHubs();
Expand Down Expand Up @@ -891,7 +882,7 @@ describe('HLFConnection', () => {

it('should invoke the chaincode', () => {
sandbox.stub(connection, 'invokeChainCode').resolves();
return connection.undeploy(mockSecurityContext, 'org.acme.biznet')
return connection.undeploy(mockSecurityContext, 'org-acme-biznet')
.then(() => {
sinon.assert.calledOnce(connection.invokeChainCode);
sinon.assert.calledWith(connection.invokeChainCode, mockSecurityContext, 'undeployBusinessNetwork', []);
Expand All @@ -900,7 +891,7 @@ describe('HLFConnection', () => {

it('should handle errors invoking the chaincode', () => {
sandbox.stub(connection, 'invokeChainCode').rejects('such error');
return connection.undeploy(mockSecurityContext, 'org.acme.biznet')
return connection.undeploy(mockSecurityContext, 'org-acme-biznet')
.should.be.rejectedWith(/such error/);
});

Expand Down Expand Up @@ -1180,7 +1171,7 @@ describe('HLFConnection', () => {
mspID: 'suchmsp',
timeout: 38
};
connection = new HLFConnection(mockConnectionManager, 'hlfabric1', 'org.acme.biznet', connectOptions, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
connection = new HLFConnection(mockConnectionManager, 'hlfabric1', 'org-acme-biznet', connectOptions, mockClient, mockChannel, [mockEventHubDef], mockCAClient);
sandbox.stub(connection, '_validateResponses').returns();
sandbox.stub(connection, '_initializeChannel').resolves();
connection._connectToEventHubs();
Expand Down Expand Up @@ -1405,33 +1396,33 @@ describe('HLFConnection', () => {
it('should return an array of chaincode names for all instantiated chaincodes', () => {
mockChannel.queryInstantiatedChaincodes.resolves({
chaincodes: [{
name: 'org.acme.biznet1',
name: 'org-acme-biznet1',
version: '1.0.0',
path: 'composer'
}, {
name: 'org.acme.biznet2',
name: 'org-acme-biznet2',
version: '1.2.0',
path: 'composer'
}]
});
return connection.list(mockSecurityContext)
.should.eventually.be.deep.equal(['org.acme.biznet1', 'org.acme.biznet2']);
.should.eventually.be.deep.equal(['org-acme-biznet1', 'org-acme-biznet2']);
});

it('should filter out any non-composer instantiated chaincodes', () => {
mockChannel.queryInstantiatedChaincodes.resolves({
chaincodes: [{
name: 'org.acme.biznet1',
name: 'org-acme-biznet1',
version: '1.0.0',
path: 'composer'
}, {
name: 'org.acme.biznet2',
name: 'org-acme-biznet2',
version: '1.2.0',
path: 'dogecc'
}]
});
return connection.list(mockSecurityContext)
.should.eventually.be.deep.equal(['org.acme.biznet1']);
.should.eventually.be.deep.equal(['org-acme-biznet1']);
});

it('should handle any errors querying instantiated chaincodes', () => {
Expand Down
Loading