├── .gitignore ├── README.md ├── add-flight.js ├── add-resources.js ├── admin-connection.js ├── bn-connection-util.js ├── bn-connection.1.js ├── bn-connection.js ├── bn-factory-submit-txn.js ├── bn-test-permissions.js ├── bndef-test.js ├── chai-demo-assertions.js ├── chai-demo-bdd.js ├── client-query.js ├── get-registries.js ├── manage-cards.js ├── mocha-demo.js ├── mocha-ut-harness-template.js ├── my-test.js ├── package.json ├── subscribe-event-ws.js ├── subscribe-event.js ├── temp.js ├── test-bn-util.js ├── test-ut-harness.js ├── test.js ├── update-bna.js ├── ut-harness.js └── util ├── aircrafts.data.json ├── deleteAllFlights.js ├── generateFights.js └── populate-acme-airline.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | temp 3 | composer-logs 4 | test 5 | package-lock.json 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This is part of a course on Hyperledger Fabric 2 | # http://ACloudFan.com 3 | 4 | # NOTE: December 21, 2018 5 | 6 | # 0.20.3 introduced changes that led to issues for some students 7 | # All issues stand resolved at this time. 8 | 9 | # Code has been tested with 0.20.5 10 | # Please update your composer components to v0.20.5 11 | 12 | How to use this? 13 | Most of the files may be executed against a local fabric insallation. 14 | Some samples are coded to work with embedded runtime. 15 | Lectures in the course refer to the samples and describe how to launch the samples 16 | 17 | 0. Install > npm install 18 | 1. Launch your local fabric runtime 19 | 2. Deploy the App against which you would like to test the API (airlinev7 by default) 20 | 1. > composer network start -a .\airlinev7@0.0.1.bna -c PeerAdmin@hlfv1 -A admin -S adminpw 21 | 2. > composer network start -a .\airlinev7@0.0.1.bna -c PeerAdmin@hlfv1 -A admin -S adminpw 22 | 3. > composer card delete admin@airlinev7 23 | 4. > composer card import -f ./admin@airlinev7.card 24 | 3. Samples are using airlinev7. If you would like to use some other you need to change the code 25 | 4. On terminal prompt > node code-sample-file.js 26 | -------------------------------------------------------------------------------- /add-flight.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Last Tested: Dec 21, 2018 7 | * Composer: 0.20.5 8 | * 9 | * Exercise: 10 | * Create a new flight resource instance and add it to the Flight Registry 11 | */ 12 | 13 | 14 | // Parameter is a AssetRegistry 15 | function addFlight(registry){ 16 | const bnDef = bnUtil.connection.getBusinessNetwork(); 17 | const factory = bnDef.getFactory(); 18 | let flightResource = factory.newResource(aircraftNamespace,aircraftType,'AE201-05-05-2020'); 19 | flightResource.setPropertyValue('flightNumber','AE101'); 20 | flightResource.route = factory.newConcept(aircraftNamespace,'Route'); 21 | flightResource.route.setPropertyValue('origin', 'EWR'); 22 | flightResource.route.setPropertyValue('destination' , 'ATL'); 23 | flightResource.route.setPropertyValue('schedule' , new Date('2018-10-15T21:44Z')); 24 | 25 | return registry.add(flightResource).then(()=>{ 26 | console.log('Successfully created the flight!!!'); 27 | bnUtil.disconnect(); 28 | }).catch((error)=>{ 29 | console.log(error); 30 | bnUtil.disconnect(); 31 | }); 32 | } -------------------------------------------------------------------------------- /add-resources.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Last Update: Dec 21, 2018 7 | * Tested with: 0.20.5 8 | * 9 | * Sample shows how to use asset registry for adding new instances 10 | * of resources. Code creates 2 instances of the Aircraft asset and 11 | * adds to the AssetRegistry by invoking the addAll() function. 12 | * 13 | * Please note that if the Aircraft with ID = CRAFT01 | CRAFT02 already 14 | * exist then the call to addAll() will fail. 15 | * 16 | * Execution environment 17 | * ===================== 18 | * 1. Fabric runtime is up 19 | * 2. aircraftv7 deployed 20 | * 3. No asset in the flight registry for CRAFT01, CRAFT02 21 | * 22 | * Demo Steps 23 | * ========== 24 | * 1. Connect using the bn-connection-util 25 | * 2. Get the AssetRegistry from connection 26 | * 3. Create 2 instances of Aircraft resource using the factory & initialize 27 | * 4. Invoke registry.addAll([Array of Aircraft resource instances]) 28 | */ 29 | 30 | const aircraftNamespace = 'org.acme.airline.aircraft'; 31 | const aircraftType = 'Aircraft'; 32 | 33 | // 1. Connect 34 | const bnUtil = require('./bn-connection-util'); 35 | bnUtil.connect(main); 36 | 37 | function main(error){ 38 | // Check for the connection error 39 | if(error){ 40 | console.log(error); 41 | process.exit(1); 42 | } 43 | 44 | // 2. Get the aircraft AssetRegistry 45 | return bnUtil.connection.getAssetRegistry(aircraftNamespace+'.'+aircraftType).then((registry)=>{ 46 | console.log('1. Received Registry: ', registry.id); 47 | 48 | // Utility method for adding the aircrafts 49 | addAircrafts(registry); 50 | 51 | }).catch((error)=>{ 52 | console.log(error); 53 | // bnUtil.disconnect(); 54 | }); 55 | } 56 | 57 | /** 58 | * Creates two resources instances CRAFT01 & CRAFT02 59 | * @param {*} registry This is of type AssetRegistry 60 | */ 61 | function addAircrafts(registry){ 62 | // 3. This Array will hold the instances of aircraft resource 63 | let aircrafts = []; 64 | const bnDef = bnUtil.connection.getBusinessNetwork(); 65 | const factory = bnDef.getFactory(); 66 | // Instance#1 67 | let aircraftResource = factory.newResource(aircraftNamespace,aircraftType,'CRAFT01'); 68 | aircraftResource.setPropertyValue('ownershipType','LEASED'); 69 | aircraftResource.setPropertyValue('firstClassSeats',10); 70 | aircraftResource.setPropertyValue('businessClassSeats',10); 71 | aircraftResource.setPropertyValue('economyClassSeats',50); 72 | // Push instance to the aircrafts array 73 | aircrafts.push(aircraftResource); 74 | 75 | // Instance#2 76 | aircraftResource = factory.newResource(aircraftNamespace,aircraftType,'CRAFT02'); 77 | // You may use direct assignment instead of using the setPropertyValue() 78 | aircraftResource.ownershipType='OWNED'; 79 | aircraftResource.firstClassSeats=15 80 | aircraftResource.businessClassSeats=20; 81 | aircraftResource.economyClassSeats=100; 82 | // Push instance to the aircrafts array 83 | aircrafts.push(aircraftResource); 84 | 85 | // 4. Add the Aircraft resource to the registry 86 | return registry.addAll(aircrafts).then(()=>{ 87 | console.log('Added the Resources successfully!!!'); 88 | bnUtil.disconnect(); 89 | }).catch((error)=>{ 90 | console.log(error); 91 | bnUtil.disconnect(); 92 | }); 93 | } 94 | 95 | -------------------------------------------------------------------------------- /admin-connection.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Last Updated: Dec 21, 2018 7 | * Composer 0.20.5 : Does not require a FileSystemCardStore to be created 8 | * 9 | * https://hyperledger.github.io/composer/latest//api/admin-adminconnection 10 | * 11 | * Demonstrates the use of the admin connection class 12 | * 1. Create an instance of the AdminConnection object 13 | * 2. Connect as the PeerAdmin 14 | * 3. List the deployed Business Network Apps 15 | * 4. Disconnect 16 | * 5. Connect as the Network Admin for airlinev7 17 | * 6. Ping airlinev7 18 | * 7. Disconnect 19 | */ 20 | 21 | // Need the card store instance 22 | const AdminConnection = require('composer-admin').AdminConnection; 23 | 24 | // Used as the card for all calls 25 | const cardNameForPeerAdmin = "PeerAdmin@hlfv1"; 26 | const cardNameForNetworkAdmin = "admin@airlinev7"; 27 | const appToBePinged = "airlinev7"; 28 | 29 | // 1. Create Admin Connection object for the fabric 30 | var walletType = { type: 'composer-wallet-filesystem' } 31 | var adminConnection = new AdminConnection(walletType); 32 | 33 | // 2. Initiate a connection as PeerAdmin 34 | return adminConnection.connect(cardNameForPeerAdmin).then(function(){ 35 | 36 | console.log("Admin Connected Successfully!!!"); 37 | // Display the name and version of the network app 38 | listBusinessNetwork(); 39 | }).catch((error)=>{ 40 | console.log(error); 41 | }); 42 | 43 | 44 | // Extracts information about the network 45 | function listBusinessNetwork(){ 46 | // 3. List the network apps 47 | adminConnection.list().then((networks)=>{ 48 | console.log("1. Successfully retrieved the deployed Networks: ",networks); 49 | 50 | networks.forEach((businessNetwork) => { 51 | console.log('Business Network deployed in Runtime', businessNetwork); 52 | }); 53 | // 4. Disconnect 54 | return adminConnection.disconnect().then(function(){ 55 | reconnectAsNetworkAdmin(); 56 | }); 57 | 58 | 59 | }).catch((error)=>{ 60 | console.log("Error=",error); 61 | }); 62 | } 63 | 64 | // Ping the network 65 | function reconnectAsNetworkAdmin(){ 66 | 67 | // 5. Reconnect with the card for network admin 68 | return adminConnection.connect(cardNameForNetworkAdmin).then(function(error){ 69 | 70 | console.log("2. Network Admin Connected Successfully!!!"); 71 | // 6. Ping the BNA 72 | 73 | adminConnection.ping(appToBePinged).then(function(response){ 74 | console.log("Ping response from "+appToBePinged+" :",response); 75 | // 7. Disconnect 76 | adminConnection.disconnect(); 77 | }).catch((error)=>{ 78 | console.log("Error=",error); 79 | }); 80 | 81 | }); 82 | 83 | 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /bn-connection-util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Last Update: Dec 21, 2018 7 | * Tested with 0.20.5 8 | * 9 | * The modules exposes these functions: 10 | * 11 | * 1. connect - takes a callback function as an argument 12 | * If Success : execute callback() 13 | * Else : execute callback(error) 14 | * 2. disconnect 15 | * 3. ping - takes a callback(response, error) as an argument 16 | * invokes the callback. 17 | * 18 | * Purpose of this utility: 19 | * Boilerplate code to keep the other sample files CLEAN :) 20 | * You may change the constants in this code to connect to 21 | * your apps instead of the default airlinev7 22 | */ 23 | module.exports = { 24 | // Properties used for creating instance of the BN connection 25 | cardStore : require('composer-common').FileSystemCardStore, 26 | BusinessNetworkConnection : require('composer-client').BusinessNetworkConnection, 27 | // Used for connect() 28 | cardName : "admin@airlinev7", 29 | 30 | // Holds the Business Network Connection 31 | connection: {}, 32 | 33 | // 1. This is the function that is called by the app 34 | connect : function(callback) { 35 | 36 | // Create instance of file system card store 37 | 38 | // Composer 0.19.0 Change 39 | //const cardStore = new this.cardStore(); 40 | //this.connection = new this.BusinessNetworkConnection({ cardStore: cardStore }); 41 | var cardType = { type: 'composer-wallet-filesystem' } 42 | this.connection = new this.BusinessNetworkConnection(cardType); 43 | 44 | // Invoke connect 45 | return this.connection.connect(this.cardName).then(function(){ 46 | callback(); 47 | }).catch((error)=>{ 48 | callback(error); 49 | }); 50 | }, 51 | 52 | // 2. Disconnects the bn connection 53 | disconnect : function(callback) { 54 | this.connection.disconnect(); 55 | }, 56 | 57 | // 3. Pings the network 58 | ping : function(callback){ 59 | return this.connection.ping().then((response)=>{ 60 | callback(response); 61 | }).catch((error)=>{ 62 | callback({}, error); 63 | }); 64 | } 65 | } 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /bn-connection.1.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * DO NOT USE THIS FILE. 7 | * Dec 21, 2018 8 | * 9 | * Demonstrates the use of the business network connection 10 | * 11 | * Pre-Reqs 12 | * 1. The local fabric is up 13 | * 2. Deployed the application to fabric 14 | * 3. Card imported to the card storage on file system 15 | */ 16 | 17 | // Need the card store instance 18 | const FileSystemCardStore = require('composer-common').FileSystemCardStore; 19 | const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; 20 | // Used as the card for all calls 21 | var cardName = "admin@airlinev7"; 22 | const registryId = "org.acme.airline.aircraft.Aircraft"; 23 | 24 | // 1. Create instance of file system card store 25 | const cardStore = new FileSystemCardStore(); 26 | // 2. Connection object for the fabric 27 | const cardStoreObj = { cardStore: cardStore }; 28 | const bnConnection = new BusinessNetworkConnection(cardStoreObj); 29 | 30 | // 3. Initiate a connection 31 | return bnConnection.connect(cardName).then(function(){ 32 | console.log("Connected Successfully!!!"); 33 | // 4. Display the name and version of the network app 34 | getBusinessNetwork(); 35 | // 5. Ping the network 36 | ping(); 37 | 38 | // 6. Get all assets in a registry 39 | getAssets(); 40 | 41 | }).catch((error)=>{ 42 | console.log(error); 43 | }); 44 | 45 | 46 | // Extracts information about the network 47 | function getBusinessNetwork(){ 48 | // Returns an object of type BusinessNetworkDefinition 49 | let businessNetworkDefinition = bnConnection.getBusinessNetwork(); 50 | // Dump package.json to the console 51 | console.log("Connected to: ",businessNetworkDefinition.metadata.packageJson.name, 52 | " version ",businessNetworkDefinition.metadata.packageJson.version); 53 | } 54 | 55 | // Ping the network app 56 | function ping(){ 57 | bnConnection.ping().then(function(response){ 58 | console.log("Ping Response:"); 59 | console.log(response); 60 | }); 61 | } 62 | 63 | // Get all the Asset from a registry Registry 64 | // 1. Get an instance of the AssetRegistry 65 | // 2. Get all he objects in the asset registry 66 | function getAssets(){ 67 | 68 | return bnConnection.getAssetRegistry(registryId).then(function(registry){ 69 | console.log("Received the Registry Instance: ", registryId) 70 | 71 | // This would get a collection of assets 72 | return registry.getAll().then(function(resourceCollection){ 73 | console.log("Received count=",resourceCollection.length) 74 | }); 75 | 76 | }).catch(function(error){ 77 | console.log(error); 78 | }); 79 | } 80 | 81 | // function update -------------------------------------------------------------------------------- /bn-connection.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Last aupdate: Dec 21, 2018 7 | * 0.20.5 Changes in the use of Card Store & Constructor of 8 | * BusinessNetworkConnection() 9 | * 10 | * Demonstrates the use of the business network connection 11 | * 12 | * Pre-Reqs 13 | * 1. The local fabric is up 14 | * 2. Deployed the application to fabric 15 | * 3. Card imported to the card storage on file system 16 | */ 17 | 18 | // Need the card store instance 19 | // 0.20.5 Does not need Card Store object - commented line below 20 | // const FileSystemCardStore = require('composer-common').FileSystemCardStore; 21 | 22 | const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; 23 | // Used as the card for all calls 24 | var cardName = "admin@airlinev7"; 25 | const registryId = "org.acme.airline.aircraft.Aircraft"; 26 | 27 | // v0.20.5 does not require the card store 28 | // Commented lines below + constructor doesn't require cardStoreObj 29 | // 1. Create instance of file system card store 30 | // const cardStore = new FileSystemCardStore(); 31 | // 2. Connection object for the fabric 32 | // const cardStoreObj = { cardStore: cardStore }; 33 | 34 | const bnConnection = new BusinessNetworkConnection();//cardStoreObj); 35 | 36 | // 3. Initiate a connection 37 | return bnConnection.connect(cardName).then(function(){ 38 | console.log("Connected Successfully!!!"); 39 | // 4. Display the name and version of the network app 40 | getBusinessNetwork(); 41 | // 5. Ping the network 42 | ping(); 43 | 44 | // 6. Get all assets in a registry 45 | getAssets(); 46 | 47 | }).catch((error)=>{ 48 | console.log(error); 49 | }); 50 | 51 | 52 | // Extracts information about the network 53 | function getBusinessNetwork(){ 54 | // Returns an object of type BusinessNetworkDefinition 55 | let businessNetworkDefinition = bnConnection.getBusinessNetwork(); 56 | // Dump package.json to the console 57 | console.log("Connected to: ",businessNetworkDefinition.metadata.packageJson.name, 58 | " version ",businessNetworkDefinition.metadata.packageJson.version); 59 | } 60 | 61 | // Ping the network app 62 | function ping(){ 63 | bnConnection.ping().then(function(response){ 64 | console.log("Ping Response:"); 65 | console.log(response); 66 | }); 67 | } 68 | 69 | // Get all the Asset from a registry Registry 70 | // 1. Get an instance of the AssetRegistry 71 | // 2. Get all he objects in the asset registry 72 | function getAssets(){ 73 | 74 | return bnConnection.getAssetRegistry(registryId).then(function(registry){ 75 | console.log("Received the Registry Instance: ", registryId) 76 | 77 | // This would get a collection of assets 78 | return registry.getAll().then(function(resourceCollection){ 79 | console.log("Received count=",resourceCollection.length) 80 | }); 81 | 82 | }).catch(function(error){ 83 | console.log(error); 84 | }); 85 | } 86 | 87 | // function update -------------------------------------------------------------------------------- /bn-factory-submit-txn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Composer 0.20.5 7 | * Last Updated: Dec 21, 2018 8 | * 9 | * Demostrates the use of factory received in the BN connection using 10 | * the getFactory( ) method to submit a transaction 11 | * 12 | * Pre-Req 13 | * 1. Start the fabric 14 | * 2. Deploy & start airlinev7 15 | * 3. Start the REST Server 16 | * 17 | * composer-rest-server -c admin@airlinev7 -n never -u true -w true 18 | * 19 | * 4. Make sure there is no Flight resource with id="AE101-05-12-2019" 20 | * Delete it if you find one - Remember the code for CreateFlight 21 | * Transaction has the flightId hardcoded :-) 22 | * 23 | * Demo Steps 24 | * 1. Use the bn-connection-util to create the connection to airlinev7 25 | * 2. Get the Busines Network Definition from Runtime 26 | * 3. Get the factory from the Business Network definition 27 | * 4. Create a new Transaction instance 28 | * 5. Set the property values in the transaction object 29 | * 6. Submit the transaction 30 | */ 31 | 32 | 33 | 34 | // Constant values - change as per your needs 35 | const namespace = "org.acme.airline.flight"; 36 | const transactionType = "CreateFlight"; 37 | 38 | // 1. Connect to airlinev7 39 | const bnUtil = require('./bn-connection-util'); 40 | bnUtil.connect(main); 41 | 42 | function main(error){ 43 | 44 | // Check for error 45 | if(error){ 46 | console.log(error); 47 | process.exit(1); 48 | } 49 | 50 | // 2. Get the Business Network Definition 51 | let bnDef = bnUtil.connection.getBusinessNetwork(); 52 | console.log("2. Received Definition from Runtime: ", 53 | bnDef.getName()," ",bnDef.getVersion()); 54 | 55 | // 3. Get the factory 56 | let factory = bnDef.getFactory(); 57 | 58 | // 4. Lets create a new Resource of type = Transaction 59 | // Here is the sample data 60 | // { 61 | // "$class": "org.acme.airline.flight.CreateFlight", 62 | // "flightNumber": "AE101-06-06-2019", 63 | // "origin": "MSP", 64 | // "destination": "SEA", 65 | // "schedule": "2019-06-06T18:49:58.273Z" 66 | // } 67 | 68 | // 4. Create an instance of transaction 69 | let options = { 70 | generate: false, 71 | includeOptionalFields: false 72 | } 73 | let flightId = "AE101-05-06-2019"; 74 | let transaction = factory.newTransaction(namespace,transactionType,flightId,options); 75 | 76 | // 5. Set up the properties of the transaction object 77 | transaction.setPropertyValue('flightNumber','AE101'); 78 | transaction.setPropertyValue('origin', 'EWR'); 79 | transaction.setPropertyValue('destination' , 'ATL'); 80 | transaction.setPropertyValue('schedule' , new Date('2019-10-15T21:44Z')); 81 | 82 | // 6. Submit the transaction 83 | return bnUtil.connection.submitTransaction(transaction).then(()=>{ 84 | console.log("6. Transaction Submitted/Processed Successfully!!") 85 | 86 | bnUtil.disconnect(); 87 | 88 | }).catch((error)=>{ 89 | console.log(error); 90 | 91 | bnUtil.disconnect(); 92 | }); 93 | } 94 | 95 | 96 | 97 | 98 | /** 99 | * Test Data for adding flight in registry 100 | { 101 | "$class": "org.acme.airline.flight.Flight", 102 | "flightId": "AE101-05-05-2019", 103 | "flightNumber": "AE101", 104 | "route": { 105 | "$class": "org.acme.airline.flight.Route", 106 | "origin": "ATL", 107 | "destination": "EWR", 108 | "schedule": "2019-12-17T18:49:58.288Z", 109 | "id": "string" 110 | } 111 | } 112 | * Adding flight using the createFlight transaction 113 | { 114 | "$class": "org.acme.airline.flight.CreateFlight", 115 | "flightNumber": "AE101-06-06-2019", 116 | "origin": "MSP", 117 | "destination": "SEA", 118 | "schedule": "2019-06-06T18:49:58.273Z" 119 | } 120 | */ -------------------------------------------------------------------------------- /bn-test-permissions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Demostrates the permissions setup. This 7 | * 8 | * Pre-Req 9 | * 1. Start the fabric 10 | * 2. Deploy & start airlinev9 11 | * 3. Add the user william Smith as per instructions 12 | * in the lecture on "ACL (2 of 2) Conditional Rules" 13 | * 4. Run the test by invoking this code 14 | * Usage: node bn-test-permissions 15 | * 16 | * PS: Keep in mind duplicate flight ID not allowed so change the -dd with every call 17 | */ 18 | 19 | // Constant values - change as per your needs 20 | const namespace = "org.acme.airline.flight"; 21 | const transactionType = "CreateFlight"; 22 | 23 | // 1. Connect to airlinev7 24 | const bnUtil = require('./bn-connection-util'); 25 | 26 | if(process.argv.length < 4){ 27 | console.log("Usage: node bn-test-permissions ") 28 | process.exit(1); 29 | } 30 | 31 | bnUtil.cardName = process.argv[2]; //'wills@airlinev9' 32 | bnUtil.connect(main); 33 | 34 | function main(error){ 35 | 36 | // Check for error 37 | if(error){ 38 | console.log(error); 39 | process.exit(1); 40 | } 41 | 42 | executeTransaction(); 43 | executeCreateOnFlightRegistry(); 44 | } 45 | 46 | function executeCreateOnFlightRegistry(){ 47 | const bnDef = bnUtil.connection.getBusinessNetwork(); 48 | const factory = bnDef.getFactory(); 49 | let flightResource = factory.newResource(namespace,'Flight','AE201-05-05-2020'); 50 | flightResource.setPropertyValue('flightNumber','AE101'); 51 | flightResource.route = factory.newConcept(namespace,'Route'); 52 | flightResource.route.setPropertyValue('origin', 'EWR'); 53 | flightResource.route.setPropertyValue('destination' , 'ATL'); 54 | flightResource.route.setPropertyValue('schedule' , new Date('2018-10-15T21:44Z')); 55 | 56 | bnUtil.connection.getRegistry(namespace+'.'+'Flight').then((registry)=>{ 57 | return registry.add(flightResource) 58 | }).then(()=>{ 59 | console.log('Successfully created the flight in Flight Registry!!!'); 60 | }).catch((error)=>{ 61 | console.log('Error invoking create on Flight Registry!!!'); 62 | }); 63 | } 64 | 65 | // Executes the CreateFlight Transaction 66 | function executeTransaction(){ 67 | 68 | // 2. Get the Business Network Definition 69 | let bnDef = bnUtil.connection.getBusinessNetwork(); 70 | 71 | // 3. Get the factory 72 | let factory = bnDef.getFactory(); 73 | 74 | // 4. Create an instance of transaction 75 | let options = { 76 | generate: false, 77 | includeOptionalFields: false 78 | } 79 | let flightId = "AE101-06-07-2018"; 80 | let transaction = factory.newTransaction(namespace,transactionType,flightId,options); 81 | 82 | // 5. Set up the properties of the transaction object 83 | transaction.setPropertyValue('flightNumber','AE103'); 84 | transaction.setPropertyValue('origin', 'EWR'); 85 | transaction.setPropertyValue('destination' , 'ATL'); 86 | transaction.setPropertyValue('schedule' , new Date(process.argv[3])); //'2018-11-15T21:44Z')); 87 | 88 | // 6. Submit the transaction 89 | return bnUtil.connection.submitTransaction(transaction).then(()=>{ 90 | console.log("Transaction 'CreateFlight' Submitted/Processed Successfully!!") 91 | 92 | bnUtil.disconnect(); 93 | 94 | }).catch((error)=>{ 95 | console.log(error); 96 | 97 | bnUtil.disconnect(); 98 | }); 99 | } 100 | 101 | 102 | 103 | 104 | /** 105 | * Test Data for adding flight in registry 106 | { 107 | "$class": "org.acme.airline.flight.Flight", 108 | "flightId": "AE101-05-05-2018", 109 | "flightNumber": "AE101", 110 | "route": { 111 | "$class": "org.acme.airline.flight.Route", 112 | "origin": "ATL", 113 | "destination": "EWR", 114 | "schedule": "2017-12-17T18:49:58.288Z", 115 | "id": "string" 116 | } 117 | } 118 | * Adding flight using the createFlight transaction 119 | { 120 | "$class": "org.acme.airline.flight.CreateFlight", 121 | "flightNumber": "AE101-06-06-2018", 122 | "origin": "MSP", 123 | "destination": "SEA", 124 | "schedule": "2018-06-06T18:49:58.273Z" 125 | } 126 | */ -------------------------------------------------------------------------------- /bndef-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BusinessNetworkDefinition 3 | * https://hyperledger.github.io/composer/latest/api/common-businessnetworkdefinition 4 | * 5 | * Last Updated: Dec 21, 2018 6 | * 7 | * Shows how to create an archive from a Directory 8 | * 9 | * Expects a folder temp with the tes-bna project setup 10 | * 11 | */ 12 | const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; 13 | const fs = require('fs'); 14 | 15 | var bnaDirectory = "./temp/test-bna"; 16 | 17 | BusinessNetworkDefinition.fromDirectory(bnaDirectory).then(function(definition){ 18 | console.log(definition); 19 | return definition.toArchive(); 20 | }).then((buffer)=>{ 21 | console.log("Received zip buffer") 22 | fs.writeFile("./temp/test.zip",buffer,(err)=>{ 23 | console.log(err) 24 | }) 25 | }); -------------------------------------------------------------------------------- /chai-demo-assertions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * Last Updated: Dec 21, 2018 6 | * 7 | * This demonstrates the use of Chai Assertion Library 8 | * http://chaijs.com/ 9 | * 10 | * Test: 11 | * mocha test chai-demo-assertions.js 12 | * 13 | */ 14 | 15 | var assert = require('chai').assert; 16 | 17 | // This statement is for Mocha test suite 18 | describe('Suite-1',()=>{ 19 | 20 | 21 | it('Test case # 1 *Assertion* style',()=>{ 22 | // Test case passes if expression evaluates to true 23 | assert(true); 24 | 25 | // .equal(actual, expected, [message]) 26 | assert.equal(true, true, 'otherwise problem'); 27 | 28 | // .exists(value, [message]) 29 | assert.exists(true, 'otherwise problem'); 30 | 31 | // .operator(val1, operator, val2, [message]) 32 | assert.operator(10, ">", 5, 'otherwise problem'); 33 | 34 | // Check the documentation here for complete list 35 | // http://chaijs.com/api/assert/ 36 | }); 37 | 38 | }); 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /chai-demo-bdd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * This demonstrates the use of Chain Assertion Library 6 | * http://chaijs.com/ 7 | * 8 | * Pre-Rquisite: Please review the mocha-demo lecture 9 | */ 10 | 11 | // BDD style: 12 | var expect = require('chai').expect; 13 | // Or 14 | var should = require('chai').should; 15 | 16 | // This statement is for Mocha test suite 17 | describe('Suite-1',()=>{ 18 | 19 | 20 | it('Test case # 1 *BDD* style',()=>{ 21 | 22 | // Test case passes if expression evaluates to true 23 | expect(true); 24 | 25 | // equality 26 | expect(true).to.equal(true); 27 | 28 | // exist = defines i.e., not null 29 | expect('object').to.exist; 30 | 31 | // substring string check 32 | expect('foobar').to.have.string('bar'); 33 | }); 34 | 35 | // Check the documentation here for complete list 36 | // http://chaijs.com/api/bdd/ 37 | }); -------------------------------------------------------------------------------- /client-query.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Tested with Composer 0.20.5 7 | * 8 | * Pre-Requisites 9 | * 1. Launch Fabric - Deploy Aircraft v8 10 | * 2. Poupulate the flight data ... use utility or REST Server 11 | * 12 | * Demostrates the use Client module : query & buildQuery 13 | * 1. Create the Client Connection 14 | * 2. Execute a Named Query using Client Module : query() 15 | * 3. Create a Dynamic Query using Client Module : buildQuery() 16 | * 4. Execute the Query 17 | */ 18 | 19 | const bnUtil = require('./bn-connection-util'); 20 | 21 | // #1 Connect to the airlinev8 22 | bnUtil.cardName='admin@airlinev8'; 23 | bnUtil.connect(main); 24 | 25 | function main(error){ 26 | // for clarity sake - ignored the error 27 | 28 | // #2 Execute the named query : AllFlights 29 | 30 | return bnUtil.connection.query('AllFlights').then((results)=>{ 31 | 32 | console.log('Received flight count:', results.length) 33 | 34 | var statement = 'SELECT org.acme.airline.aircraft.Aircraft WHERE (aircraftId == _$id)'; 35 | 36 | // #3 Build the query object 37 | return bnUtil.connection.buildQuery(statement); 38 | 39 | }).then((qry)=>{ 40 | 41 | // #4 Execute the query 42 | return bnUtil.connection.query(qry,{id:'CRAFT01'}); 43 | }).then((result)=>{ 44 | console.log('Received aircraft count:', result.length); 45 | if(result.length > 0) console.log(result[0].aircraftId); 46 | bnUtil.connection.disconnect(); 47 | }).catch((error)=>{ 48 | console.log(error); 49 | bnUtil.connection.disconnect(); 50 | }); 51 | } -------------------------------------------------------------------------------- /get-registries.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Tested with Composer 0.20.5 7 | * 8 | * Demostrates the getter functions for the registries 9 | * 1. Use the bn-connection-util to connect 10 | * 2. Get & Print the Asset Registries 11 | * 3. Get & Print the Participant Registries 12 | * 4. Get & Print the Transaction Registries 13 | * 5. Get & Print the Historian Registry 14 | * 6. Get & Print the Identity Registriy 15 | */ 16 | const bnUtil = require('./bn-connection-util'); 17 | 18 | // This creates the business network connection object 19 | // and calls connect() on it. Calls the callback method 20 | // 'main' with error 21 | bnUtil.connect(main); 22 | 23 | // This gets invoked after the promise for connect is 24 | // resolved. Error has value if there was an error in connect() 25 | function main(error){ 26 | // Check for the connection error 27 | if(error){ 28 | console.log(error); 29 | process.exit(1); 30 | } 31 | 32 | // This is where you would code the app specific stuff 33 | // Connection is available bnUtil.connection 34 | // to disconnect use bnUtil.disconnect() 35 | 36 | // 2. Get All asset registries...arg true = include system registry 37 | bnUtil.connection.getAllAssetRegistries(false).then((registries)=>{ 38 | console.log("Registries"); 39 | console.log("=========="); 40 | printRegistry(registries); 41 | // 3. Get all the participant registries 42 | return bnUtil.connection.getAllParticipantRegistries(false); 43 | }).then((registries)=>{ 44 | printRegistry(registries); 45 | 46 | // 4. Get all the transaction Registries 47 | return bnUtil.connection.getAllTransactionRegistries(); 48 | }).then((registries)=>{ 49 | printRegistry(registries); 50 | 51 | // 5. Get the Historian Registry 52 | return bnUtil.connection.getHistorian(); 53 | 54 | }).then((registry)=>{ 55 | console.log("Historian Registry: ", registry.registryType, " ", registry.id); 56 | 57 | // 6. Get the Identity Registry 58 | return bnUtil.connection.getIdentityRegistry(); 59 | 60 | }).then((registry)=>{ 61 | console.log("Identity Registry: ", registry.registryType, " ", registry.id); 62 | 63 | bnUtil.connection.disconnect(); 64 | }).catch((error)=>{ 65 | console.log(error); 66 | bnUtil.connection.disconnect(); 67 | }); 68 | } 69 | 70 | // Utility function to print information about the registry 71 | function printRegistry(registryArray){ 72 | registryArray.forEach((registry)=>{ 73 | console.log(registry.registryType, " ", registry.id); 74 | }); 75 | } 76 | -------------------------------------------------------------------------------- /manage-cards.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Part of a Hyperledger Fabric Course : http://ACloudFan.com 5 | * 6 | * Composer 0.19.0 7 | * 8 | * https://hyperledger.github.io/composer/latest//business-network/cloud-wallets 9 | * https://github.com/hyperledger/composer/blob/master/packages/composer-common/lib/cardstore/networkcardstoremanager.js 10 | * 11 | * 1. Get the instance of the NetworkCardStoreManager 12 | * 2. Create instance of BusinessNetworkCardStore for filesystem based wallet 13 | * 3. BusinessNetworkCardStore : Get all cards on file system & print the names on console 14 | * 4. BusinessNetworkCardStore :Get the first card by name 15 | */ 16 | 17 | // 1. Get the instance of the NetworkCardStoreManager 18 | const NetworkCardStoreManager= require('composer-common').NetworkCardStoreManager; 19 | 20 | // 2. Get instance of BusinessNetworkCardStore for filesystem based wallet 21 | var walletType = { type: 'composer-wallet-filesystem' } 22 | const cardStore = NetworkCardStoreManager.getCardStore( walletType ); 23 | 24 | // 3. Gets all the card 25 | return cardStore.getAll().then(function(cardMap){ 26 | // Print all card names 27 | console.log(cardMap.keys()); 28 | 29 | // 4. Get the name of the first card & then retrieve it 30 | let firstCard = cardMap.keys().next().value 31 | // Get the firstCard - returns a promise so check .then() 32 | return cardStore.get(firstCard); 33 | 34 | }).then(function(idCard){ 35 | 36 | // get the user and business name 37 | console.log("Pulled First Card from file system: ", idCard.getUserName(),' @ ', idCard.getBusinessNetworkName()) 38 | 39 | // get the connection profile 40 | console.log("Connection Profile Name: ",idCard.getConnectionProfile().name) 41 | 42 | }).catch((error)=>{ 43 | console.log(error) 44 | }); 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /mocha-demo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * This demonstrates the use of Mocha Test Framework 6 | * https://mochajs.org/ 7 | * 8 | * By default all executions are asynchrnonous but using the done in callback one can 9 | * change the behavior of the before/beforeEach/after to synchronous 10 | */ 11 | 12 | 13 | /** 14 | * Suite of tests 15 | */ 16 | describe('Enclosing Suite', () => { 17 | 18 | /** 19 | * This is invoked before any test is executed 20 | */ 21 | 22 | // ASynchronous 23 | before(() => { 24 | // This gets executed asynchronously before every test suite 25 | console.log("before() the test cases are executed"); 26 | }); 27 | 28 | /** 29 | * This is invoked before any test is executed 30 | */ 31 | beforeEach(() => { 32 | console.log("\tbeforeEach() executed"); 33 | }); 34 | 35 | // Test suite-1 36 | describe('Suite-1', () => { 37 | 38 | // Test case # 1 39 | it('Test Case# 1', () => { 40 | 41 | }); 42 | 43 | // Test case # 2 44 | it('Test Case# 2', () => { 45 | 46 | }); 47 | }); 48 | 49 | // Test suite-2 50 | describe('Suite-2', () => { 51 | it('Test Case# 1', () => { 52 | 53 | }); 54 | }); 55 | 56 | /** 57 | * This is invoked at the end of all the test execution 58 | */ 59 | after(() => { 60 | console.log("after() executed"); 61 | }); 62 | 63 | }); -------------------------------------------------------------------------------- /mocha-ut-harness-template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * Use this as a template for your own unit test cases 6 | */ 7 | var assert = require('chai').assert; 8 | 9 | 10 | const utHarness = require('./ut-harness'); 11 | 12 | // This points to the model project folder 13 | var modelFolder = 'C:/Users/Rajeev/Documents/Course/Hyperledger-Course/workspace/HLF-Course-Domain-Model/airlinev7'; 14 | 15 | var adminConnection = {} 16 | var businessNetworkConnection = {} 17 | var bnDefinition = {} 18 | 19 | 20 | // Synchronous call so that connections can be established 21 | before((done) => { 22 | utHarness.debug = false; 23 | utHarness.initialize(modelFolder, (adminCon, bnCon, definition) => { 24 | adminConnection = adminCon; 25 | businessNetworkConnection = bnCon; 26 | bnDefinition = definition; 27 | done(); 28 | }); 29 | }) 30 | 31 | 32 | // Test Suite # 1 33 | describe('Give information on the test case', () => { 34 | 35 | // Synchronous 36 | beforeEach((done) => { 37 | // Move the initialize here if you would like to 38 | // initialize runtime everytime before each test 39 | // case 40 | done() 41 | }); 42 | 43 | // Test Case # 1 44 | it('should have more that 1 registry', () => { 45 | // Your test code goes here 46 | 47 | // expression in assert 48 | assert(true) 49 | }); 50 | 51 | // Test Case # 2 52 | it('should have more that 2 registry', () => { 53 | // Your test code goes here 54 | 55 | // expression in assert 56 | assert(true) 57 | }); 58 | }); 59 | 60 | 61 | -------------------------------------------------------------------------------- /my-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * This is the sample test case used in the lecture 6 | * "Unit Testing of Network Apps" 7 | */ 8 | var assert = require('chai').assert; 9 | 10 | // You need to change this to your specific directory 11 | const utHarness = require('C:/Users/Rajeev/Documents/Course/Hyperledger-Course/workspace/wip/HLF-API/ut-harness.js'); 12 | 13 | // This points to the model project folder 14 | var modelFolder = __dirname+'/..'; 15 | 16 | var adminConnection = {} 17 | var businessNetworkConnection = {} 18 | var bnDefinition = {} 19 | 20 | 21 | 22 | // Synchronous call so that connections can be established 23 | before((done) => { 24 | utHarness.debug = false; 25 | utHarness.initialize(modelFolder, (adminCon, bnCon, definition) => { 26 | adminConnection = adminCon; 27 | businessNetworkConnection = bnCon; 28 | bnDefinition = definition; 29 | done(); 30 | }); 31 | }) 32 | 33 | const nameSpace = 'org.example.biznet'; 34 | const resourceName = 'SampleAsset'; 35 | 36 | // Test Suite # 1 37 | describe('Sample Asset # Add & Check', () => { 38 | 39 | // Test Case # 1 40 | // 1. Add an Asset of type "SampleAsset" with value="10" 41 | // 2. Get the asset instance that was added 42 | // 3. Assert Equal >> Value in received asset should be "10" 43 | it('should have 1 asset instance with value=10', () => { 44 | let registry ={} 45 | // Add the asset 46 | // Get the asset registry using the BN Connection 47 | return businessNetworkConnection.getAssetRegistry(nameSpace+'.'+resourceName).then((reg)=>{ 48 | registry = reg; 49 | // Get the factory using the BN Definition 50 | const factory = bnDefinition.getFactory(); 51 | // Create the instance 52 | let sampleAsset = factory.newResource(nameSpace,resourceName,'SA-1'); 53 | sampleAsset.value='10'; 54 | // Add to registry 55 | return registry.add(sampleAsset); 56 | }).then((asset)=>{ 57 | 58 | // Get the asset now 59 | return registry.get('SA-1'); 60 | }).then((asset)=>{ 61 | 62 | // Assert 63 | assert.equal(asset.value,"10","Value not equal or undefined"); 64 | }).catch((error)=>{ 65 | console.log(error); 66 | }); 67 | }); 68 | 69 | 70 | }); 71 | 72 | 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hlf-course-api", 3 | "version": "1.0.0", 4 | "description": "This is part of a course on Hyperledger Fabric http://ACloudFan.com", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/acloudfan/HLF-Fabric-API.git" 12 | }, 13 | "author": "raj@acloudfan.com", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/acloudfan/HLF-Fabric-API/issues" 17 | }, 18 | "homepage": "https://github.com/acloudfan/HLF-Fabric-API#readme", 19 | "dependencies": { 20 | "chai": "^4.2.0", 21 | "composer-admin": "^0.20.5", 22 | "composer-cli": "^0.20.5", 23 | "composer-client": "^0.20.5", 24 | "composer-connector-embedded": "^0.20.5", 25 | "fs": "0.0.1-security", 26 | "grpc": "^1.17.0", 27 | "mocha": "^5.2.0", 28 | "websocket": "^1.0.28" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /subscribe-event-ws.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * Tested with Composer 0.20.5 6 | * 7 | * Pre-Requisites 8 | * 1. Launch Fabric - Deploy Aircraft v8 9 | * 2. Launch REST Server 10 | * 11 | * Uses the NPM library for websockets 12 | * https://www.npmjs.com/package/websocket 13 | * 14 | * Demonstrates how applications can subscribe to the events 15 | * published by the REST server 16 | * 17 | * 1. Setup the websocket library (npm install websocket --save) ... already done 18 | * 2. Create a websocket client object 19 | * 20 | */ 21 | var counter=0; 22 | 23 | // #1 Need to use the websocket library 24 | var WebSocketClient = require('websocket').client; 25 | 26 | // #2 Create a WS Client 27 | var client = new WebSocketClient(); 28 | 29 | // #3 Setup the WS connection failure listener 30 | client.on('connectFailed', function(error) { 31 | console.log('Connect Error: ' + error.toString()); 32 | }); 33 | 34 | // #4 Setup the on connection listener 35 | client.on('connect', (connection)=>{ 36 | console.log("Connected to REST-Server over WS protocol!!!"); 37 | 38 | // #5 Subscribe to messages received on WS 39 | connection.on('message',(msg)=>{ 40 | var event = JSON.parse(msg.utf8Data); 41 | 42 | // #6 Filter the events 43 | switch(event.$class){ 44 | case 'org.acme.airline.flight.FlightCreated': 45 | counter++; 46 | console.log('Event#', counter); 47 | 48 | processFlightCreatedEvent(event); 49 | break; 50 | default: 51 | console.log("Ignored event: ", event.$class); 52 | } 53 | }) 54 | }) 55 | 56 | // #7 Call connect with URL to the REST Server 57 | client.connect('ws://localhost:3000'); 58 | 59 | 60 | 61 | // #8 Gets called every time an event is receieved 62 | function processFlightCreatedEvent(event){ 63 | console.log('Received event:') 64 | // Pretty printing the received JSON string 65 | console.log(JSON.stringify(event,null,4)); 66 | console.log(); 67 | } -------------------------------------------------------------------------------- /subscribe-event.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * Tested with Composer 0.20.5 6 | * 7 | * Pre-Requisites 8 | * 1. Launch Fabric - Deploy Aircraft v8 9 | * 2. Launch REST Server 10 | * 11 | * Demonstrates event subscription on HL fabric. 12 | * 1. Create the business network connection 13 | * 2. Subscribe to event stream - as of Jan 2017, criteria based subscription is not available 14 | * https://hyperledger.github.io/composer/applications/subscribing-to-events.html 15 | * 3. Filter event 16 | * 4. If Receieved event = FlightCreated then process it otherwise ignore 17 | * 18 | * To Test: 19 | * 1. In REST server interface, initiate the CreateFlight transaction 20 | **/ 21 | 22 | const bnUtil = require('./bn-connection-util'); 23 | 24 | // #1 Connect to the airlinev8 25 | bnUtil.cardName='admin@airlinev8'; 26 | bnUtil.connect(main); 27 | 28 | var counter = 0; 29 | function main(error){ 30 | 31 | console.log("Event subscription started for: FlightCreated event!!"); 32 | console.log("Received:") 33 | // #2 Subscribe to event 34 | bnUtil.connection.on('event',(event)=>{ 35 | var namespace = event.$namespace; 36 | var eventtype = event.$type; 37 | 38 | var fqn = namespace+'.'+eventtype; 39 | 40 | // #3 Filter the events 41 | switch(fqn){ 42 | case 'org.acme.airline.flight.FlightCreated': 43 | // #3 Process the event 44 | counter++; 45 | console.log('Event#',counter); 46 | processFlightCreatedEvent(fqn, event); 47 | break; 48 | default: 49 | console.log("Ignored event: ", fqn); 50 | } 51 | }); 52 | } 53 | 54 | /** 55 | * This is the event processing function that can be coded to carry out any action 56 | * that the subscriber intends to take. E.g., when the flight is scheduled the travel 57 | * agent will open it up on their site for ticket sale. 58 | * @param {*} fqn 59 | * @param {*} event 60 | */ 61 | function processFlightCreatedEvent(fqn, event){ 62 | // For demo purpose the information is getting printed on the console 63 | console.log(fqn, ' ', event.flightId, ' ', event.timestamp, ' ', event.eventId); 64 | console.log(); 65 | } -------------------------------------------------------------------------------- /temp.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Write the unit tests for your transction processor functions here 4 | */ 5 | 6 | const participantRegistry 7 | 8 | const asset_of_type_B 9 | 10 | const asset_A_Registry 11 | 12 | asset_A_Registry.add(asset_of_type_A) 13 | 14 | asset_A_Registry.add(asset_of_type_B) 15 | 16 | const asset_B_Registry 17 | 18 | var asset_a_instance_1 19 | 20 | var asset_a_instance_2 21 | 22 | var createFlightTransaction = Factory.newTransaction( ); 23 | 24 | createFlightTransaction.setPropertyValue('property_name', 'property_value') 25 | 26 | const AdminConnection = require('composer-admin').AdminConnection; 27 | const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; 28 | const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; 29 | const IdCard = require('composer-common').IdCard; 30 | const MemoryCardStore = require('composer-common').MemoryCardStore; 31 | 32 | 33 | 34 | const namespace = 'org.example.biznet'; 35 | const assetType = 'SampleAsset'; 36 | 37 | 38 | // In-memory card store for testing so cards are not persisted to the file system 39 | const cardStore = new MemoryCardStore(); 40 | let adminConnection; 41 | let businessNetworkConnection; 42 | 43 | 44 | // Embedded connection used for local testing 45 | const connectionProfile = { 46 | name: 'embedded', 47 | type: 'embedded' 48 | }; 49 | // Embedded connection does not need real credentials 50 | const credentials = { 51 | certificate: 'FAKE CERTIFICATE', 52 | privateKey: 'FAKE PRIVATE KEY' 53 | }; 54 | 55 | // PeerAdmin identity used with the admin connection to deploy business networks 56 | const deployerMetadata = { 57 | version: 1, 58 | userName: 'PeerAdmin', 59 | roles: [ 'PeerAdmin', 'ChannelAdmin' ] 60 | }; 61 | const deployerCard = new IdCard(deployerMetadata, connectionProfile); 62 | deployerCard.setCredentials(credentials); 63 | 64 | const deployerCardName = 'PeerAdmin'; 65 | adminConnection = new AdminConnection({ cardStore: cardStore }); 66 | 67 | return adminConnection.importCard(deployerCardName, deployerCard).then(() => { 68 | return adminConnection.connect(deployerCardName); 69 | }); 70 | -------------------------------------------------------------------------------- /test-bn-util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Last Updated: Dec 21, 2018 7 | * Composer 0.20.5 8 | * 9 | * This is for testing the bn-connection-util.js 10 | * 11 | * Shows how to use the bn-connection-util in your 12 | */ 13 | const bnUtil = require('./bn-connection-util'); 14 | 15 | // This creates the business network connection object 16 | // and calls connect() on it. Calls the callback method 17 | // 'main' with error 18 | bnUtil.connect(main); 19 | 20 | // Callback function passed to the BN Connection utility 21 | // Error has value if there was an error in connect() 22 | function main(error){ 23 | // 1. Check for the connection error 24 | if(error){ 25 | console.log(error); 26 | process.exit(1); 27 | } 28 | 29 | console.log("1. Successfully Connected !!!"); 30 | 31 | // 2. Lets ping 32 | bnUtil.ping((response, error)=>{ 33 | if(error){ 34 | console.log(error); 35 | } else { 36 | console.log("2. Received Ping Response:"); 37 | console.log(response); 38 | } 39 | 40 | // 3. Disconnect 41 | bnUtil.disconnect(); 42 | 43 | console.log("3. Disconnected"); 44 | }); 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /test-ut-harness.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * Tested with Composer 0.20.5 6 | * 7 | * This is for testing the UT test harness itself :-) 8 | * 9 | * 1. utHarness = require('./ut-harness'); 10 | * 2. Call the initialize function on the ut-harness 11 | * A) Folder for the model project 12 | * B) Callback function receives the: 13 | * adminConnection, 14 | * businessNetworkConnection, 15 | * businessNetworkDefinition 16 | * 3. The unit test code is written in the callback function 17 | */ 18 | const utHarness = require('./ut-harness'); 19 | 20 | var modelFolder = 'C:/Users/Rajeev/Documents/Course/Hyperledger-Course/workspace/HLF-Course-Domain-Model/airlinev7'; 21 | //var modelFolder = ''; 22 | 23 | 24 | // Set this to false for suppressing the UTH messages 25 | utHarness.debug=true; 26 | utHarness.initialize(modelFolder, (adminCon, bnCon, definition)=>{ 27 | 28 | // Get the registry names 29 | console.log("BNA =",definition.getName(),'@',definition.getVersion()); 30 | 31 | // Lets geth the registries 32 | return bnCon.getAllAssetRegistries(false).then((registries)=>{ 33 | registries.forEach((registry)=>{ 34 | console.log(registry.id) 35 | }); 36 | 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | // Tested with v0.20.5 2 | 3 | const BusinessNetworkCardStore = require('composer-common').BusinessNetworkCardStore; 4 | 5 | const cardStore = require('composer-common').NetworkCardStoreManager.getCardStore( { type: 'composer-wallet-inmemory' } ); 6 | 7 | console.log(cardStore) 8 | 9 | //https://hyperledger.github.io/composer/latest//business-network/cloud-wallets 10 | -------------------------------------------------------------------------------- /update-bna.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Part of a course on Hyperledger Fabric: 4 | * http://ACloudFan.com 5 | * 6 | * Composer 0.19.0 : Update not valid anymore 7 | * 8 | * https://hyperledger.github.io/composer/latest//api/common-businessnetworkdefinition 9 | * https://hyperledger.github.io/composer/latest//api/admin-adminconnection 10 | * 11 | * Demonstrates the use of admin connection to update an app 12 | * 13 | **** Runtime has already been installed 14 | **** airlinev7@0.0.1.bna deployed and currently active 15 | * 16 | * 1. Create the Admin Connection instance 17 | * 2. Connect 18 | * 3. Create the Business Network Definition Object 19 | * 4. Update the airlinev7 model in runtime 20 | * 5. Disconnect 21 | */ 22 | const AdminConnection = require('composer-admin').AdminConnection; 23 | const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; 24 | 25 | const cardNameForPeerAdmin = "PeerAdmin@hlfv1"; 26 | const appName = "airlinev7"; 27 | // This where I have the archive file for v2.0 of airlinev7 28 | // CHANGE THIS DIRECTORY FOR YOUR Model Project 29 | const bnaDirectory = "/AIRLINE v7 Poroject Folder/"; 30 | 31 | // 1. Create the AdminConnection instance 32 | // Composer 0.19.0 change 33 | var walletType = { type: 'composer-wallet-filesystem' } 34 | const adminConnection = new AdminConnection(walletType); 35 | 36 | // 2. Connect using the card for the Network Admin 37 | return adminConnection.connect(cardNameForPeerAdmin).then(function(){ 38 | console.log("Admin Connection Successful!!!"); 39 | 40 | // Upgrade the BNA version 41 | upgradeApp(); 42 | }).catch(function(error){ 43 | console.log(error); 44 | }); 45 | 46 | /** 47 | * Deploys a network app using the admin connection 48 | */ 49 | function upgradeApp(){ 50 | // 3. Create a Business Network Definition object from directory 51 | var bnaDef = {} 52 | BusinessNetworkDefinition.fromDirectory(bnaDirectory).then(function(definition){ 53 | bnaDef = definition; 54 | console.log("Successfully created the definition!!! ",bnaDef.getName()) 55 | 56 | // Install the new version of the BNA 57 | return adminConnection.install(bnaDef); 58 | 59 | }).then(()=>{ 60 | 61 | // 4. Update the application 62 | // If you do not have the app installed, you will get an error 63 | console.log("Install successful") 64 | return adminConnection.upgrade(appName, '0.0.2'); 65 | 66 | }).then(()=>{ 67 | 68 | console.log('App updated successfully!! ', bnaDef.getName(),' ',bnaDef.getVersion()); 69 | 70 | // 5. Disconnect 71 | adminConnection.disconnect(); 72 | 73 | }).catch(function(error){ 74 | console.log(error); 75 | }); 76 | 77 | } 78 | 79 | -------------------------------------------------------------------------------- /ut-harness.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Part of a course on Hyperledger Fabric: 3 | * http://ACloudFan.com 4 | * 5 | * Composer 0.20.5 6 | * 7 | * Takes a model project folder as input. 8 | * 9 | * 1. Setup the Peer Admin IDCard 10 | * 2. Setup the MemoryCardStore 11 | * 3. Create the admin and business network connection 12 | * 4. Use adminConnection to import the PeerAdmin card 13 | * 5. Connect the adminConnection to embedded runtime 14 | * 6. Create the business network definition fromDirectory 15 | * 7. Install the business network definition 16 | * 8. Start the airlinev7 17 | * 9. Import the network admin ID Card 18 | * 10. Invoke the connect on businessNetwork connection object 19 | * 11. Invoke Callback(....) 20 | * 21 | * Callback 22 | * ======== 23 | * Callback receives the adminConnection, businessNetworkConnection 24 | * and the businessNetworkDefinition 25 | * 26 | * Developer may use these to code the test cases, without worrying 27 | * about the boiler plate code for all of the tasks carried out in this 28 | * test harness. 29 | */ 30 | 31 | module.exports = { 32 | // Removed MemoryCardStore & Added NetworkCardStore 0.19.0 33 | // MemoryCardStore: require('composer-common').MemoryCardStore, 34 | NetworkCardStore: require('composer-common').NetworkCardStoreManager, 35 | IdCard: require('composer-common').IdCard, 36 | AdminConnection: require('composer-admin').AdminConnection, 37 | BusinessNetworkDefinition: require('composer-common').BusinessNetworkDefinition, 38 | BusinessNetworkConnection: require('composer-client').BusinessNetworkConnection, 39 | CertificateUtil: require('composer-common').CertificateUtil, 40 | 41 | info: 'UT-Harness-NOT-Initialized!!!', 42 | debug: false, 43 | 44 | // Objects created for testing 45 | adminConnection: {}, 46 | businessNetworkDefinition: {}, 47 | businessNetworkConnection: {}, 48 | 49 | initialize: function (folder, callback) { 50 | // 1 Setup the PeerAdmin Card to be used by the admin connection 51 | idCard = this.setupPeerAdminCard(); 52 | 53 | // Changed for Composer 0.19.0 54 | // 2. Set up the card store 55 | // let cardStoreObj = { cardStore: new this.MemoryCardStore() }; 56 | // 3. Create the business & the admin Connection 57 | // this.adminConnection = new this.AdminConnection(cardStoreObj); 58 | // this.businessNetworkConnection = new this.BusinessNetworkConnection(cardStoreObj); 59 | const cardStore = require('composer-common').NetworkCardStoreManager.getCardStore( { type: 'composer-wallet-inmemory' } ); 60 | this.adminConnection = new this.AdminConnection({ cardStore: cardStore }); 61 | this.businessNetworkConnection = new this.BusinessNetworkConnection({ cardStore: cardStore });//cardType); 62 | 63 | // 4. Import the PeerAdmin Card to the Memory card store 64 | const peerAdminCardName = "PeerAdmin" 65 | return this.adminConnection.importCard(peerAdminCardName, idCard).then(() => { 66 | 67 | this.log("PeerAdmin Card imported Successfully!!"); 68 | 69 | // 5. Connect to the embedded runtime with PeerAdmin Card 70 | return this.adminConnection.connect(peerAdminCardName); 71 | 72 | }).then(() => { 73 | 74 | // Admin connection successfull 75 | this.log("Admin Connection Successful!!") 76 | 77 | // 6. Create the Business Network Def from directory 78 | return this.BusinessNetworkDefinition.fromDirectory(folder) 79 | }).then(definition => { 80 | this.businessNetworkDefinition = definition; 81 | this.info = definition.metadata.packageJson.name + '@' + definition.metadata.packageJson.version; 82 | 83 | // Changed 0.19.0 install takes bnDefinition now 84 | // 7. Install the Composer runtime for the new business network 85 | return this.adminConnection.install(this.businessNetworkDefinition);//.getName()); 86 | }).then(() => { 87 | this.log("Runtime Install Successful!!"); 88 | 89 | const startOptions = { 90 | networkAdmins: [ 91 | { 92 | userName: 'admin', 93 | enrollmentSecret: 'adminpw' 94 | } 95 | ] 96 | }; 97 | // Changed 0.19.0 - start now needs a name & version 98 | // 8. Start runtime - will receive admin card on resolution 99 | return this.adminConnection.start(this.businessNetworkDefinition.getName(),this.businessNetworkDefinition.getVersion(), startOptions); 100 | }).then((networkAdminCardMap) => { 101 | this.log("Start Successful - network admin card received!!"); 102 | this.networkAdminCardName = `admin@${this.businessNetworkDefinition.getName()}`; 103 | 104 | // 9. Import the network admin card 105 | return this.adminConnection.importCard(this.networkAdminCardName, networkAdminCardMap.get('admin')); 106 | }).then(() => { 107 | 108 | this.log("Imported the Network Admin Card!!! =" + this.networkAdminCardName); 109 | 110 | // 10. Connect the business network 111 | return this.businessNetworkConnection.connect(this.networkAdminCardName); 112 | 113 | }).then(() => { 114 | 115 | this.log("Business connection successful!!!"); 116 | 117 | // 13. Invoke the callback function 118 | callback(this.adminConnection, this.businessNetworkConnection, this.businessNetworkDefinition); 119 | 120 | }).catch((error) => { 121 | this.log("Errored!!", error) 122 | }); 123 | }, 124 | 125 | 126 | // This prints message to console if the debug=true 127 | log: function (msg, error) { 128 | if (this.debug) { 129 | console.log('UTH: ', msg); 130 | } 131 | if (error) console.log('UT Harness Error: ', error); 132 | }, 133 | 134 | disconnect: function(){ 135 | this.businessNetworkConnection.disconnect(); 136 | this.adminConnection.disconnect(); 137 | }, 138 | 139 | /** 140 | * Sets up the Card store and the Network idCard 141 | */ 142 | setupPeerAdminCard: function () { 143 | 144 | // Changed for 0.19.0 145 | // 1.1 Create the connection profile object 146 | // Type=embedded is the key here 147 | // const connectionProfile = { 148 | // name: 'embedded', 149 | // type: 'embedded' 150 | // } 151 | const connectionProfile = { 152 | name: 'embedded', 153 | 'x-type': 'embedded' 154 | }; 155 | 156 | // 1.2 Metadata 157 | const metaData = { 158 | version: 1, 159 | userName: 'PeerAdmin', 160 | roles: ['PeerAdmin', 'ChannelAdmin'] 161 | } 162 | 163 | // Changed 0.19.0 164 | // 1.3 Just to satisfy the IDCard 165 | // const credentials = { 166 | // certificate: "DOES NOT MATTER what you put here as", 167 | // privateKey: "embedded runtime does not use these :)" 168 | // } 169 | // Generate certificates for use with the embedded connection 170 | const credentials = this.CertificateUtil.generate({ commonName: 'admin' }); 171 | 172 | // 2. Create the IDCard 173 | idCard = new this.IdCard(metaData, connectionProfile); 174 | 175 | // 3. Set the credentials 176 | idCard.setCredentials(credentials) 177 | 178 | // 4. Create the admin object 179 | return idCard; 180 | } 181 | 182 | 183 | } -------------------------------------------------------------------------------- /util/aircrafts.data.json: -------------------------------------------------------------------------------- 1 | [ 2 | 3 | { 4 | "aircraftId" : "CRAFT01", 5 | "ownershipType" : "LEASED", 6 | "firstClassSeats" : 10, 7 | "businessClassSeats" : 10, 8 | "economyClassSeats" : 50 9 | }, 10 | { 11 | "aircraftId" : "CRAFT02", 12 | "ownershipType" : "OWNED", 13 | "firstClassSeats" : 15, 14 | "businessClassSeats" : 15, 15 | "economyClassSeats" : 150 16 | }, 17 | { 18 | "aircraftId" : "CRAFT03", 19 | "ownershipType" : "LEASED", 20 | "firstClassSeats" : 5, 21 | "businessClassSeats" : 5, 22 | "economyClassSeats" : 65 23 | } 24 | 25 | ] -------------------------------------------------------------------------------- /util/deleteAllFlights.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tested with Composer 0.20.5 3 | * 4 | * Utility method for cleaning up the flights 5 | */ 6 | const bnUtil = require('../bn-connection-util'); 7 | const flightNamespace = 'org.acme.airline.flight'; 8 | const resourceName = 'Flight'; 9 | 10 | bnUtil.cardName='admin@airlinev8'; 11 | if(process.argv.length < 3){ 12 | console.log("Usage: node populate-acme-airline ") 13 | console.log("Populating Network using a card: ",bnUtil.cardName); 14 | } else { 15 | bnUtil.cardName = process.argv[2]; 16 | console.log("Populating Network using a card: ",bnUtil.cardName); 17 | } 18 | bnUtil.connect(main); 19 | 20 | 21 | 22 | function main(){ 23 | var registry = {} 24 | 25 | return bnUtil.connection.getAssetRegistry(flightNamespace+'.'+resourceName).then((reg)=>{ 26 | registry = reg; 27 | 28 | console.log('Received Registry: ', registry.id); 29 | 30 | return registry.getAll(); 31 | }).then((flights)=>{ 32 | console.log('Retrieved flights : ', flights.length); 33 | // Utility method for adding the aircrafts 34 | return registry.removeAll(flights) 35 | 36 | }).then(()=>{ 37 | 38 | console.log("Removed all flights !!"); 39 | bnUtil.disconnect(); 40 | 41 | }).catch((error)=>{ 42 | 43 | console.log(error); 44 | bnUtil.disconnect(); 45 | }); 46 | } -------------------------------------------------------------------------------- /util/generateFights.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tested with Composer 0.20.5 3 | * 4 | * This generates a flight schedule for 6 weeks for 3 flights 5 | * AE101, AE102, AE103 6 | * AE101 EWR -> SEA 11:00 AM 7 | * AE102 SEA -> ATL 2:30 PM 8 | * AE103 ATL -> EWR 6:15 PM 9 | */ 10 | const bnUtil = require('../bn-connection-util'); 11 | const flightNamespace = 'org.acme.airline.flight'; 12 | const transactionType = 'CreateFlight'; 13 | 14 | // Change this for populating other versions 15 | bnUtil.cardName='admin@airlinev8'; 16 | if(process.argv.length < 3){ 17 | console.log("Usage: node populate-acme-airline ") 18 | console.log("Populating Network using a card: ",bnUtil.cardName); 19 | } else { 20 | bnUtil.cardName = process.argv[2]; 21 | console.log("Populating Network using a card: ",bnUtil.cardName); 22 | } 23 | bnUtil.connect(main); 24 | 25 | 26 | 27 | function main(error){ 28 | if(error){ 29 | console.log(error) 30 | process.exit(1) 31 | } 32 | createFlights('AE101','EWR','SEA',new Date(), 3, 11,00); 33 | let nextDay = new Date(new Date().getTime()+24*60*60*1000); 34 | createFlights('AE102','SEA','ATL', nextDay, 3, 14,30); 35 | nextDay = new Date(nextDay.getTime()+2*24*60*60*1000); 36 | createFlights('AE103','ATL','EWR', nextDay, 3, 18,15); 37 | } 38 | 39 | 40 | // Creates the flight instances 41 | // To keep things simple, flight will be scheduled at the start of hour 1:30 not allowed 42 | // departureTime = 0-23 0=12 AM, 1=1 AM .... 13=1 PM, 23=11:00 PM 43 | function createFlights(number, origin, destination, startDate, frequency, departureTimeHour, departureTimeMinute){ 44 | 45 | var x = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()); 46 | x = new Date(x.getTime()+departureTimeHour*60*60*1000+departureTimeMinute*60*1000); // + ); 47 | 48 | let flights = []; 49 | const bnDef = bnUtil.connection.getBusinessNetwork(); 50 | const factory = bnDef.getFactory(); 51 | 52 | var ctr = 0 ; 53 | const iterations = 4; 54 | for(var i=0; i < iterations; i++){ 55 | // Flight scheduled every 3rd day starting from today 56 | let sched = new Date(x.getTime()+(i+1)*frequency*24*60*60*1000); 57 | 58 | let transaction = factory.newTransaction(flightNamespace,transactionType); 59 | transaction.setPropertyValue('flightNumber',number); 60 | transaction.setPropertyValue('origin', origin); 61 | transaction.setPropertyValue('destination' , destination); 62 | transaction.setPropertyValue('schedule' , sched); 63 | //flights.push(transaction); 64 | bnUtil.connection.submitTransaction(transaction).then(()=>{ 65 | console.log('Added Flight : ',number,ctr); 66 | ctr++; 67 | }).catch((error)=>{ 68 | console.log(error); 69 | bnUtil.connection.disconnect(); 70 | }) 71 | } 72 | } -------------------------------------------------------------------------------- /util/populate-acme-airline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Populates the airline Registries with data 3 | * 4 | * Tested with Composer 0.20.5 5 | */ 6 | 7 | const bnUtil = require('../bn-connection-util'); 8 | 9 | const aircraftNamespace = 'org.acme.airline.aircraft'; 10 | const aircraftType = 'Aircraft'; 11 | const flightNamespace = 'org.acme.airline.flight'; 12 | const transactionType = 'CreateFlight'; 13 | 14 | // This creates the business network connection object 15 | // and calls connect() on it. Calls the callback method 16 | // 'main' with error 17 | bnUtil.cardName='admin@airlinev8'; 18 | if(process.argv.length < 3){ 19 | console.log("Usage: node populate-acme-airline ") 20 | console.log("Populating Network using a card: ",bnUtil.cardName); 21 | } else { 22 | bnUtil.cardName = process.argv[2]; 23 | console.log("Populating Network using a card: ",bnUtil.cardName); 24 | } 25 | bnUtil.connect(main); 26 | 27 | // Callback function passed to the BN Connection utility 28 | // Error has value if there was an error in connect() 29 | function main(error){ 30 | 31 | if(error){ 32 | console.log(error); 33 | process.exit(1); 34 | } 35 | 36 | // create an array of aircraft instances 37 | let registry = {}; 38 | let aircrafts = createAircraftInstances(); 39 | return bnUtil.connection.getAssetRegistry(aircraftNamespace+'.'+aircraftType).then((reg)=>{ 40 | registry = reg; 41 | 42 | // Add aircraft instances 43 | return registry.addAll(aircrafts); 44 | 45 | }).then(()=>{ 46 | 47 | submitCreateFlightTransactions(); 48 | 49 | }).catch((error)=>{ 50 | console.log(error); 51 | // bnUtil.disconnect(); 52 | }); 53 | 54 | } 55 | 56 | /** 57 | * Create the flights 58 | */ 59 | function submitCreateFlightTransactions(){ 60 | // Create the flight tra 61 | let flights = createFlightTransactions(); 62 | 63 | flights.forEach((txn)=>{ 64 | return bnUtil.connection.submitTransaction(txn).then(()=>{ 65 | console.log("Added flight : ", txn.flightNumber, txn.origin, txn.destination, txn.schedule) 66 | }); 67 | }); 68 | } 69 | 70 | /** 71 | * Returns an array of aircraft instances 72 | */ 73 | function createAircraftInstances(){ 74 | // 3. This Array will hold the instances of aircraft resource 75 | let aircrafts = []; 76 | const bnDef = bnUtil.connection.getBusinessNetwork(); 77 | const factory = bnDef.getFactory(); 78 | // Instance#1 79 | let aircraftResource = factory.newResource(aircraftNamespace,aircraftType,'CRAFT01'); 80 | aircraftResource.setPropertyValue('ownershipType','LEASED'); 81 | aircraftResource.setPropertyValue('firstClassSeats',10); 82 | aircraftResource.setPropertyValue('businessClassSeats',10); 83 | aircraftResource.setPropertyValue('economyClassSeats',50); 84 | // Push instance to the aircrafts array 85 | aircrafts.push(aircraftResource); 86 | 87 | // Instance#2 88 | aircraftResource = factory.newResource(aircraftNamespace,aircraftType,'CRAFT02'); 89 | // You may use direct assignment instead of using the setPropertyValue() 90 | aircraftResource.ownershipType='OWNED'; 91 | aircraftResource.firstClassSeats=15 92 | aircraftResource.businessClassSeats=20; 93 | aircraftResource.economyClassSeats=100; 94 | // Push instance to the aircrafts array 95 | aircrafts.push(aircraftResource); 96 | 97 | 98 | // Instance#3 99 | aircraftResource = factory.newResource(aircraftNamespace,aircraftType,'CRAFT03'); 100 | // You may use direct assignment instead of using the setPropertyValue() 101 | aircraftResource.ownershipType='OWNED'; 102 | aircraftResource.firstClassSeats=16 103 | aircraftResource.businessClassSeats=10; 104 | aircraftResource.economyClassSeats=80; 105 | // Push instance to the aircrafts array 106 | aircrafts.push(aircraftResource); 107 | 108 | return aircrafts; 109 | } 110 | 111 | function createFlightTransactions(){ 112 | let flights = []; 113 | const bnDef = bnUtil.connection.getBusinessNetwork(); 114 | const factory = bnDef.getFactory(); 115 | 116 | // Transaction instance#1 117 | let transaction = factory.newTransaction(flightNamespace,transactionType); 118 | transaction.setPropertyValue('flightNumber','AE101'); 119 | transaction.setPropertyValue('origin', 'EWR'); 120 | transaction.setPropertyValue('destination' , 'SEA'); 121 | transaction.setPropertyValue('schedule' , new Date('2018-10-15T21:44Z')); 122 | flights.push(transaction); 123 | 124 | // Transaction instance#2 125 | transaction = factory.newTransaction(flightNamespace,transactionType); 126 | transaction.setPropertyValue('flightNumber','AE102'); 127 | transaction.setPropertyValue('origin', 'ATL'); 128 | transaction.setPropertyValue('destination' , 'EWR'); 129 | transaction.setPropertyValue('schedule' , new Date('2018-11-16T21:44Z')); 130 | flights.push(transaction) 131 | 132 | // Transaction instance#2 133 | transaction = factory.newTransaction(flightNamespace,transactionType); 134 | transaction.setPropertyValue('flightNumber','AE103'); 135 | transaction.setPropertyValue('origin', 'SEA'); 136 | transaction.setPropertyValue('destination' , 'JFK'); 137 | transaction.setPropertyValue('schedule' , new Date('2018-12-17T21:44Z')); 138 | flights.push(transaction) 139 | 140 | return flights; 141 | } --------------------------------------------------------------------------------