Skip to content

Commit

Permalink
FAB-985 Implement official SDK API design
Browse files Browse the repository at this point in the history
FAB-985 Stub out functions still to be implemented
and move existing functions to classes as described
by the documentation link in the issue.

- New Client class is added as main API entry and allows an
application to have more than one instance
- Chain class is modified to become the main class for submitting
proposals and transactions
- Member is deleted and replaced by new class User

Patch 3: further refactoring and restoring "endorser-tests.js"
to work again
Patch 4: restored "headless-tests.js"
Patch 5: restored "orderer-tests.js", "orderer-chain-tests.js",
"chain-fabriccop-tests.js" and "end-to-end.js"
Patch 6: merged with latest in master

Change-Id: Icd03dd0bcb5c913276aa4879593ad66e6e824bc6
Signed-off-by: cdaughtr <cdaughtr@us.ibm.com>
Signed-off-by: Jim Zhang <jzhang@us.ibm.com>
  • Loading branch information
jimthematrix committed Dec 14, 2016
1 parent fecedd7 commit 04a9d05
Show file tree
Hide file tree
Showing 21 changed files with 1,763 additions and 1,621 deletions.
8 changes: 5 additions & 3 deletions build/tasks/doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ gulp.task('doc', function () {
'hfc/lib/impl/FileKeyValueStore.js',
'hfc/lib/impl/CryptoSuite_ECDSA_AES.js',
'hfc/lib/impl/ecdsa/key.js',
'hfc/lib/impl/FabricCOPImpl.js',
'hfc/lib/Chain.js',
'hfc/lib/Member.js',
'hfc/lib/Peer.js',
'hfc/lib/X509Certificate.js'
'hfc/lib/User.js',
'hfc/lib/Client.js',
'hfc/lib/X509Certificate.js',
'hfc-cop/index.js',
'hfc-cop/lib/FabricCOPImpl.js'
], {read: false})
.pipe(jsdoc())
.pipe(gulp.dest('./docs/gen'));
Expand Down
2 changes: 1 addition & 1 deletion build/tasks/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ gulp.task('test', ['pre-test'], function() {
'test/unit/chain-fabriccop-tests.js',
'test/unit/endorser-tests.js',
'test/unit/orderer-tests.js',
'test/unit/orderer-member-tests.js',
'test/unit/orderer-chain-tests.js',
'test/unit/end-to-end.js',
'test/unit/headless-tests.js'
])
Expand Down
7 changes: 4 additions & 3 deletions build/tasks/watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ gulp.task('watch', function () {
.pipe(gulp.dest('hfc-cop/'));

watch([
'hfc/lib/**/*',
'hfc/index.js',
'hfc/config/**/*',
'hfc-cop/lib/**/*',
'hfc-cop/config/**/*'
'hfc/lib/**/*',
'hfc-cop/index.js',
'hfc-cop/config/**/*',
'hfc-cop/lib/**/*'
], { ignoreInitial: false, base: './' })
.pipe(debug())
.pipe(gulp.dest('node_modules'));
Expand Down
24 changes: 24 additions & 0 deletions hfc-cop/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright 2016 IBM All Rights Reserved.
*
* 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.
*/

/**
* This is the pluggable module for the "hfc-cop" (Hyperledger Fabric Client Membership Services
* aka "COP") package. COP is not an acronym. The name was selected because:
* - it provides police-like security functionality for Hyperledger Fabric, and
* - it is shorter and easier to say and write “COP” rather than “Membership Services"
*
* @module hfc-cop
*/
1 change: 0 additions & 1 deletion hfc-cop/lib/FabricCOPImpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ var logger = utils.getLogger('FabricCOPImpl.js');

/**
* This is an implementation of the member service client which communicates with the Fabric COP server.
*
* @class
*/
var FabricCOPServices = class {
Expand Down
204 changes: 1 addition & 203 deletions hfc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,206 +21,4 @@
* @module hfc
*/

var util = require('util');
var Chain = require('./lib/Chain.js');
var Config = require('./lib/Config.js');
var Peer = require('./lib/Peer.js');
var utils = require('./lib/utils.js');

var _chains = {};

/**
* Create a new chain. If it already exists, throws an Error.
* @param name {string} Name of the chain. It can be any name and has value only for the client.
*
* @returns [Chain]{@link module:api.Chain} a new instance of the Chain class
*/
module.exports.newChain = function(name) {
var chain = _chains[name];

if (chain)
throw new Error(util.format('Chain %s already exists', name));

chain = new Chain(name);

_chains[name] = chain;
return chain;
};

/**
* Get a chain. If it doesn't yet exist and 'create' is true, create it.
* @param {string} chainName The name of the chain to get or create.
* @param {boolean} create If the chain doesn't already exist, specifies whether to create it.
* @returns {Chain} Returns the chain, or null if it doesn't exist and create is false.
*/
module.exports.getChain = function(chainName, create) {
var chain = _chains[chainName];

if (!chain && create) {
chain = this.newChain(chainName);
}

return chain;
};

/**
* Constructs and returns a Peer given its endpoint configuration settings.
*
* @param {string} url The URL with format of "grpcs://host:port".
* @param {Object} opts The options for the connection to the peer.
* @returns {Peer} Returns the new peer.
*/
module.exports.getPeer = function(url, opts) {
var peer = new Peer(url, opts);

return peer;
};


/**
* Obtains an instance of the [KeyValueStore]{@link module:api.KeyValueStore} class. By default
* it returns the built-in implementation, which is based on files ([FileKeyValueStore]{@link module:api.FileKeyValueStore}).
* This can be overriden with an environment variable KEY_VALUE_STORE, the value of which is the
* full path of a CommonJS module for the alternative implementation.
*
* @param {Object} options is whatever the implementation requires for initializing the instance. For the built-in
* file-based implementation, this requires a single property "path" to the top-level folder for the store
* @returns [KeyValueStore]{@link module:api.KeyValueStore} an instance of the KeyValueStore implementation
*/
module.exports.newKeyValueStore = function(options) {
return utils.newKeyValueStore(options);
};

/**
* Configures a logger for the entire HFC SDK to use and override the default logger. Unless this method is called,
* HFC uses a default logger (based on winston). When using the built-in "winston" based logger, use the environment
* variable HFC_LOGGING to pass in configurations in the following format:
*
* {
* 'error': 'error.log', // 'error' logs are printed to file 'error.log' relative of the current working dir for node.js
* 'debug': '/tmp/myapp/debug.log', // 'debug' and anything more critical ('info', 'warn', 'error') can also be an absolute path
* 'info': 'console' // 'console' is a keyword for logging to console
* }
*
* @param {Object} logger a logger instance that defines the following methods: debug(), info(), warn(), error() with
* string interpolation methods like [util.format]{@link https://nodejs.org/api/util.html#util_util_format_format}.
*/
module.exports.setLogger = function(logger) {
var err = '';

if (typeof logger.debug !== 'function') {
err += 'debug() ';
}

if (typeof logger.info !== 'function') {
err += 'info() ';
}

if (typeof logger.warn !== 'function') {
err += 'warn() ';
}

if (typeof logger.error !== 'function' ) {
err += 'error()';
}

if (err !== '') {
throw new Error('The "logger" parameter must be an object that implements the following methods, which are missing: ' + err);
}

if (global.hfc) {
global.hfc.logger = logger;
} else {
global.hfc = {
logger: logger
};
}
};

/**
* Adds a file to the top of the list of configuration setting files that are
* part of the hierarchical configuration.
* These files will override the default settings and be overriden by environment,
* command line arguments, and settings programmatically set into configuration settings.
*
* hierarchy search order:
* 1. memory - all settings added with utils.setConfigSetting(name,value)
* 2. Command-line arguments
* 3. Environment variables (names will be change from AAA-BBB to aaa-bbb)
* 4. Custom Files - all files added with the addConfigFile(path)
* will be ordered by when added, were last one added will override previously added files
* 5. The file located at 'config/default.json' with default settings
*
* @param {String} path - The path to the file to be added to the top of list of configuration files
*/
module.exports.addConfigFile = function(path) {

utils.addConfigFile(path);
};

/**
* Adds a setting to override all settings that are
* part of the hierarchical configuration.
*
* hierarchy search order:
* 1. memory - settings added with this call
* 2. Command-line arguments
* 3. Environment variables (names will be change from AAA-BBB to aaa-bbb)
* 4. Custom Files - all files added with the addConfigFile(path)
* will be ordered by when added, were last one added will override previously added files
* 5. The file located at 'config/default.json' with default settings
*
* @param {String} name - The name of a setting
* @param {Object} value - The value of a setting
*/
module.exports.setConfigSetting = function(name, value) {

utils.setConfigSetting(name, value);
};

/**
* Retrieves a setting from the hierarchical configuration and if not found
* will return the provided default value.
*
* hierarchy search order:
* 1. memory - settings added with utils.setConfigSetting(name,value)
* 2. Command-line arguments
* 3. Environment variables (names will be change from AAA-BBB to aaa-bbb)
* 4. Custom Files - all files added with the addConfigFile(path)
* will be ordered by when added, were last one added will override previously added files
* 5. The file located at 'config/default.json' with default settings
*
* @param {String} name - The name of a setting
* @param {Object} default_value - The value of a setting if not found in the hierarchical configuration
*/
module.exports.getConfigSetting = function(name, default_value) {

return utils.getConfigSetting(name, default_value);
};

/**
* Builds an unique transaction ID based on the values in
* the request object.
*
* @param {Object} request - An object with the values to be used
* to build an unique transaction ID.
* @returns {String} An unique transaction ID
*/
module.exports.buildTransactionID = function(request) {

return utils.buildTransactionID(request);
};

/**
* Gets a random number for a one time use
*
* @param {int} length - Optional value to control the length of the number.
* The configuration setting 'nonce-size' will be used if not
* passed in.
* @return {int} Random number of the specified length
*/
module.exports.getNonce = function(length) {

return utils.buildTransactionID(length);
};

module.exports = require('./lib/Client.js');
Loading

0 comments on commit 04a9d05

Please sign in to comment.