Skip to content

Commit

Permalink
Enable empty network generation (hyperledger-archives#3926)
Browse files Browse the repository at this point in the history
* enable empty network generation

Signed-off-by: Nick Lincoln <[email protected]>

* enable empty network generation

Signed-off-by: Nick Lincoln <[email protected]>
  • Loading branch information
nklincoln authored and bestbeforetoday committed Apr 30, 2018
1 parent 93f42d2 commit 9b9aa54
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# 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
Expand All @@ -21,14 +21,15 @@ Feature: Developer tutorial

Scenario: Step One: Creating a business network structure
When I run the yo command from the tutorial:
| command | identifiedBy:create-network |
| --appname | identifiedBy:network-name |
| --applicense | identifiedBy:license |
| --ns | identifiedBy:namespace |
| command | identifiedBy:create-network |
| --appname | identifiedBy:network-name |
| --applicense | identifiedBy:license |
| --ns | identifiedBy:namespace |
| --appdescription | King conga\'s special network |
| --appauthor | King Conga |
| --appemail | king@conga-email |

| --appauthor | King Conga |
| --appemail | king@conga-email |
| --empty | identifiedBy:empty |

Then I have the following files
| ../tutorial-network/.eslintrc.yml |
| ../tutorial-network/README.md |
Expand All @@ -55,7 +56,7 @@ Feature: Developer tutorial
"""
When I run the cli command from the tutorial:
| command | identifiedBy:archive-create |

Then I have the following files
| ../tutorial-network/tutorial-network@0.0.1.bna |

Expand Down Expand Up @@ -113,4 +114,3 @@ Feature: Developer tutorial
When I kill task named REST-SERVER
When I kill task named NPM


Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# 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
Expand All @@ -18,7 +18,25 @@ Feature: Business Network Generator
Background:
Given I have admin business cards available

Scenario: Using the Composer generator, I can generate a template network
@generateOne
Scenario: Using the Composer generator, I can generate an empty template network
When I run the following expected pass CLI command
| command | yo hyperledger-composer:businessnetwork |
| --appname | my-empty-bus-net |
| --appdescription | a description for my business network |
| --appauthor | Captain Conga |
| --appemail | conga@congaverse.com |
| --applicense | Apache2.0 |
| --ns | conga.busnet |
| --empty | yes |
Then Folder ../my-empty-bus-net should only contain the following files
| .eslintrc.yml |
| README.md |
| package.json |
| permissions.acl |
| models/conga.busnet.cto |

Scenario: Using the Composer generator, I can generate a populated template network
When I run the following expected pass CLI command
| command | yo hyperledger-composer:businessnetwork |
| --appname | my-bus-net |
Expand All @@ -27,16 +45,17 @@ Feature: Business Network Generator
| --appemail | conga@congaverse.com |
| --applicense | Apache2.0 |
| --ns | conga.busnet |
Then I have the following files
| ../my-bus-net/.eslintrc.yml |
| ../my-bus-net/README.md |
| ../my-bus-net/package.json |
| ../my-bus-net/permissions.acl |
| ../my-bus-net/models/conga.busnet.cto |
| ../my-bus-net/lib/logic.js |
| ../my-bus-net/test/logic.js |
| ../my-bus-net/features/sample.feature |
| ../my-bus-net/features/support/index.js |
| --empty | no |
Then Folder ../my-bus-net should only contain the following files
| .eslintrc.yml |
| README.md |
| package.json |
| permissions.acl |
| models/conga.busnet.cto |
| lib/logic.js |
| test/logic.js |
| features/sample.feature |
| features/support/index.js |

Scenario: Using the Composer generator, I can install the business network packages
When I run the following expected pass CLI command
Expand Down
4 changes: 4 additions & 0 deletions packages/composer-tests-integration/lib/clisteps.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ module.exports = function () {
return this.composer.checkExists(type, table);
});

this.Given(/^Folder (.+?) should only contain the following files/, function (folder, table) {
return this.composer.checkExistsStrict(folder, table);
});

this.Given(/^I have saved the secret in file to (.+?)$/, function(alias, cardFile) {
return this.composer.extractSecret(alias, cardFile);
});
Expand Down
61 changes: 61 additions & 0 deletions packages/composer-tests-integration/lib/composer.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,26 @@ class Composer {
}
}

/**
* Get all files recursively in a directoy
* @param {String} dir directory to search
* @param {String[]} fileList file list to append
* @returns {String[]} list of files in directory
*/
getFilesInDirectory(dir, fileList){
fileList = fileList || [];
let files = fs.readdirSync(dir);
files.forEach((file) => {
let name = dir + '/' + file;
if (fs.statSync(name).isDirectory()){
this.getFilesInDirectory(name, fileList);
} else {
fileList.push(name);
}
});
return fileList;
}

/**
* Check that the provided list of items (files or folders) exist
* @param {String} type - type (folder or file) that is being considered
Expand All @@ -234,6 +254,47 @@ class Composer {
}
}

/**
* Check that the provided list of items exist in the passed folder
* @param {String} folder - folder to be inspected
* @param {DataTable} table - DataTable listing the items expected to exist
* @return {Promise} - Pomise that will be resolved or rejected with an error
*/
checkExistsStrict(folder, table) {
const passedFiles = table.raw();

// Make sure all paths are accounted for
const expectedFiles = [];
for (let file of passedFiles) {
expectedFiles.push(path.resolve(__dirname,folder,file.toString()));
}

// get all files
const allFiles = this.getFilesInDirectory(path.resolve(__dirname,folder));

// Check for missing items
let missingFiles =[];
for (let file of expectedFiles){
if(allFiles.indexOf(file) === -1){
missingFiles.push(file);
}
}
if (missingFiles.length !== 0) {
return Promise.reject('The following item(s) should exist: ' + missingFiles.toString());
}

// Check for superfluous items
let unexpectedFiles =[];
for (let file of allFiles){
if(expectedFiles.indexOf(file) === -1){
unexpectedFiles.push(file);
}
}
if (unexpectedFiles.length !== 0) {
return Promise.reject('The following item(s) should not exist: ' + unexpectedFiles.toString());
}
}

/**
* Prepare CLI Command to run
* @param {Boolean} pass - Boolean pass/fail case expected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ rm -rf ${HOME}/.composer/client-data/ange*
rm -rf ${HOME}/.composer/cards/charlie*
rm -rf ${HOME}/.composer/client-data/charlie*
rm -rf ./tmp/* # temp folder for BNA files that are generated
rm -rf ./my-bus-net # business network created from generator
rm -rf ./my-empty-bus-net # a business network created from generator
rm -rf ./my-bus-net # a business network created from generator
rm -rf ./tutorial-network # business network created from generator in dev tut
rm -f ./networkadmin.card
rm -f ./composer-report-*
Expand Down Expand Up @@ -201,6 +202,7 @@ for INTEST in $(echo ${INTEST} | tr "," " "); do
rm -rf ${HOME}/.composer/cards/ange*
rm -rf ${HOME}/.composer/client-data/ange*
rm -rf ./tmp/*
rm -rf ./my-empty-bus-net
rm -rf ./my-bus-net
rm -rf ./tutorial-network
rm -rf ./networkadmin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ The easiest way to get started is to use the Yeoman generator to create a skelet

4. Select <code-block type="arguments" sub-type="yo" identifier="namespace" > `org.example.mynetwork` </code-block> as the namespace.

5. Select <code-block type="arguments" sub-type="yo" identifier="empty" > `No` </code-block> when asked whether to generate an empty network or not.

## Step Two: Defining a business network

A business network is made up of assets, participants, transactions, access control rules, and optionally events and queries. In the skeleton business network created in the previous steps, there is a model (`.cto`) file which will contain the class definitions for all assets, participants, and transactions in the business network. The skeleton business network also contains an access control (`permissions.acl`) document with basic access control rules, a script (`logic.js`) file containing transaction processor functions, and a `package.json` file containing business network metadata.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ module.exports = yeoman.Base.extend({
default: 'org.example.biznet',
store: true,
validate: Util.validateNamespace
},
{
type: 'list',
name: 'empty',
message: 'Do you want to generate an empty template network?',
default: 'false',
store: true,
choices: [{
name: 'Yes: generate an empty template network',
value: 'yes'
},
{
name: 'No: generate a populated sample network',
value: 'no'
}
]
}
];

Expand All @@ -81,6 +97,7 @@ module.exports = yeoman.Base.extend({
this.appdescription = answers.appdescription;
this.appauthor = answers.appauthor;
this.applicense = answers.applicense;
this.empty = answers.empty;
});
},

Expand All @@ -90,15 +107,24 @@ module.exports = yeoman.Base.extend({

writing: function() {
let model = this._generateTemplateModel();
this.fs.copyTpl(this.templatePath('**!(models|lib|test)*'), this.destinationPath(), model);
this.fs.copyTpl(this.templatePath('models/namespace.cto'), this.destinationPath('models/'+this.namespace+'.cto'), model);
this.fs.copyTpl(this.templatePath('permissions.acl'), this.destinationPath('permissions.acl'), model);
this.fs.move(this.destinationPath('_dot_eslintrc.yml'), this.destinationPath('.eslintrc.yml'), model);
/* istanbul ignore else */
if (!this.ismodel) {
this.fs.copyTpl(this.templatePath('./features'), this.destinationPath('./features'), model);
this.fs.copyTpl(this.templatePath('./test'), this.destinationPath('./test'), model);
this.fs.copyTpl(this.templatePath('./lib'), this.destinationPath('./lib'), model);
if (this.empty && this.empty.toLocaleLowerCase().localeCompare('yes') === 0) {
this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), model);
this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), model);
this.fs.copyTpl(this.templatePath('models/empty_namespace.cto'), this.destinationPath('models/'+this.namespace+'.cto'), model);
this.fs.copyTpl(this.templatePath('empty_permissions.acl'), this.destinationPath('permissions.acl'), model);
this.fs.copyTpl(this.templatePath('_dot_eslintrc.yml'), this.destinationPath('.eslintrc.yml'), model);
} else {
this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), model);
this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), model);
this.fs.copyTpl(this.templatePath('models/namespace.cto'), this.destinationPath('models/'+this.namespace+'.cto'), model);
this.fs.copyTpl(this.templatePath('permissions.acl'), this.destinationPath('permissions.acl'), model);
this.fs.copyTpl(this.templatePath('_dot_eslintrc.yml'), this.destinationPath('.eslintrc.yml'), model);
/* istanbul ignore else */
if (!this.ismodel) {
this.fs.copyTpl(this.templatePath('./features'), this.destinationPath('./features'), model);
this.fs.copyTpl(this.templatePath('./test'), this.destinationPath('./test'), model);
this.fs.copyTpl(this.templatePath('./lib'), this.destinationPath('./lib'), model);
}
}
},

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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.
*/

rule NetworkAdminUser {
description: "Grant business network administrators full access to user resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "**"
action: ALLOW
}

rule NetworkAdminSystem {
description: "Grant business network administrators full access to system resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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.
*/

/**
* Write your model definitions here
*/

namespace <%= namespace %>
Loading

0 comments on commit 9b9aa54

Please sign in to comment.