/* * 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 Util = require('composer-common').Util; const ConnectionProfileManager = require('composer-common').ConnectionProfileManager; const FSConnectionProfileStore = require('composer-common').FSConnectionProfileStore; const fs = require('fs'); /** * This class creates an administration connection to a Fabric Composer runtime. The * connection can then be used to: * <ul> * <li>Deploy BusinessNetworkDefinitions</li> * <li>Undeploy BusinessNetworkDefinitions</li> * <li>Update BusinessNetworkDefinitions</li> * <li>Send a ping message to the runtime to ensure it is running and * correctly configured.</li> * <li>Store a connection profile document in the connection profile store</li> * </ul> * * @class * @memberof module:composer-admin */ class AdminConnection { /** * Create an instance of the AdminConnection class. * @param {Object} [options] - an optional set of options to configure the instance. * @param {Object} [options.fs] - specify an fs implementation to use. */ constructor(options) { options = options || {}; this.connectionProfileStore = new FSConnectionProfileStore(options.fs || fs); this.connectionProfileManager = new ConnectionProfileManager(this.connectionProfileStore); this.connection = null; this.securityContext = null; } /** * Connects and logs in to the Hyperledger Fabric using a named connection * profile. The connection profile must exist in the profile store. * @example * // Connect to Hyperledger Fabric * var adminConnection = new AdminConnection(); * adminConnection.connect('testprofile', 'WebAppAdmin', 'DJY27pEnl16d') * .then(function(){ * // Connected. * }) * .catch(function(error){ * // Add optional error handling here. * }); * @param {string} connectionProfile - The name of the connection profile * @param {string} enrollmentID the enrollment ID of the user * @param {string} enrollmentSecret the enrollment secret of the user * @param {string} businessNetworkIdentifier the id of the network (for update) or null * @return {Promise} A promise that indicates the connection is complete */ connect(connectionProfile, enrollmentID, enrollmentSecret, businessNetworkIdentifier) { return this.connectionProfileManager.connect(connectionProfile, businessNetworkIdentifier) .then((connection) => { this.connection = connection; return connection.login(enrollmentID, enrollmentSecret); }) .then((securityContext) => { this.securityContext = securityContext; return Promise.resolve('connected'); }); } /** * Stores a connection profile into the profile store being used by this * AdminConnection. * @example * // Create a connection profile * var adminConnection = new AdminConnection(); * var adminOptions = { * type: 'hlf', * keyValStore: '/tmp/keyValStore', * membershipServicesURL: 'grpc://membersrvc:7054', * peerURL: 'grpc://vp0:7051', * eventHubURL: 'grpc://vp0:7053' * }; * return adminConnection.createProfile('testprofile', adminOptions) * .then(function(){ * // Created profile * }) * .catch(function(error){ * // Add optional error handling here. * }); * @param {string} connectionProfile - The name of the connection profile * @param {Object} data - The connection profile data * @return {Promise} A promise that indicates that the connection profile is deployed */ createProfile(connectionProfile, data) { return this.connectionProfileManager.getConnectionProfileStore().save(connectionProfile, data); } /** * Deletes the specified connection profile from the profile store being used by this * AdminConnection. * @example * // Delete a connection profile * var adminConnection = new AdminConnection(); * return adminConnection.deleteProfile('testprofile') * .then(function(){ * // Deleted profile * }) * .catch(function(error){ * // Add optional error handling here. * }); * @param {string} connectionProfile - The name of the connection profile * @return {Promise} A promise that indicates that the connection profile is deployed */ deleteProfile(connectionProfile) { return this.connectionProfileManager.getConnectionProfileStore().delete(connectionProfile); } /** * Retrieve the specified connection profile from the profile store being * used by this AdminConnection. * @example * // Retrieve the connection profile. * const adminConnection = new AdminConnection(); * return adminConnection.getProfile('testprofile') * .then((profile) => { * // Retrieved profile * console.log(profile); * }); * @param {string} connectionProfile - The name of the connection profile * @return {Promise} A promise that is resolved with the connection profile data. */ getProfile(connectionProfile) { return this.connectionProfileManager.getConnectionProfileStore().load(connectionProfile); } /** * Retrieve all connection profiles from the profile store being used by this * AdminConnection. * @example * // Retrieve all the connection profiles. * const adminConnection = new AdminConnection(); * return adminConnection.getAllProfiles() * .then((profiles) => { * // Retrieved profiles * for (let profile in profiles) { * console.log(profile, profiles[profile]); * } * }); * @return {Promise} A promise that is resolved with the connection profile data. */ getAllProfiles() { return this.connectionProfileManager.getConnectionProfileStore().loadAll(); } /** * Disconnects this connection. * @example * // Disconnect from a Business Network * var adminConnection = new AdminConnection(); * return adminConnection.disconnect() * .then(function(){ * // Disconnected. * }) * .catch(function(error){ * // Add optional error handling here. * }); * @return {Promise} A promise that will be resolved when the connection is * terminated. */ disconnect() { if (!this.connection) { return Promise.resolve(); } return this.connection.disconnect() .then(() => { this.connection = null; this.securityContext = null; }); } /** * Deploys a new BusinessNetworkDefinition to the fabric. The connection must * be connected for this method to succeed. * @example * // Deploy a Business Network Definition * var adminConnection = new AdminConnection(); * var businessNetworkDefinition = BusinessNetworkDefinition.fromArchive(myArchive); * return adminConnection.deploy(businessNetworkDefinition) * .then(function(){ * // Business network definition deployed * }) * .catch(function(error){ * // Add optional error handling here. * }); * @param {BusinessNetworkDefinition} businessNetworkDefinition - The business network to deploy * @return {Promise} A promise that will be fufilled when the business network has been * deployed. */ deploy(businessNetworkDefinition) { Util.securityCheck(this.securityContext); return this.connection.deploy(this.securityContext, true, businessNetworkDefinition); } /** * Undeploys a BusinessNetworkDefinition from the fabric. The business network will no * longer be able to process transactions. * @example * // Undeploy a Business Network Definition * var adminConnection = new AdminConnection(); * return adminConnection.undeploy('identifier') * .then(function(){ * // Undeployed Business Network Definition * }) * .catch(function(error){ * // Add optional error handling here. * }) * @param {string} businessNetworkIdentifier - The identifier of the network to undeploy * @return {Promise} A promise that will be fufilled when the business network has been * undeployed. */ undeploy(businessNetworkIdentifier) { Util.securityCheck(this.securityContext); return this.connection.undeploy(this.securityContext, businessNetworkIdentifier); } /** * Updates an existing BusinessNetworkDefinition on the fabric. The BusinessNetworkDefinition * must have been previously deployed. * @example * // Updates a Business Network Definition * var adminConnection = new AdminConnection(); * var businessNetworkDefinition = BusinessNetworkDefinition.fromArchive(myArchive); * return adminConnection.update(businessNetworkDefinition) * .then(function(){ * // Business network definition updated * }) * .catch(function(error){ * // Add optional error handling here. * }); * @param {BusinessNetworkDefinition} businessNetworkDefinition - The new BusinessNetworkDefinition * @return {Promise} A promise that will be fufilled when the business network has been * updated. */ update(businessNetworkDefinition) { Util.securityCheck(this.securityContext); return this.connection.update(this.securityContext, businessNetworkDefinition); } /** * Test the connection to the runtime and verify that the version of the * runtime is compatible with this level of the node.js module. * @example * // Test the connection to the runtime * var adminConnection = new AdminConnection(); * return adminConnection.ping() * .then(function(){ * // Connection has been tested * }) * .catch(function(error){ * // Add optional error handling here. * }); * @return {Promise} A promise that will be fufilled when the connection has * been tested. The promise will be rejected if the version is incompatible. */ ping() { Util.securityCheck(this.securityContext); return this.connection.ping(this.securityContext); } /** * List all of the deployed business networks. The connection must * be connected for this method to succeed. * @example * // List all of the deployed business networks. * var adminConnection = new AdminConnection(); * return adminConnection.list() * .then((businessNetworks) => { * // Connection has been tested * return businessNetworks.forEach((businessNetwork) => { * console.log('Deployed business network', businessNetwork); * }); * }) * .catch(function(error){ * // Add optional error handling here. * }); * @return {Promise} A promise that will be resolved with an array of * business network identifiers, or rejected with an error. */ list() { Util.securityCheck(this.securityContext); return this.connection.list(this.securityContext); } } module.exports = AdminConnection;