diff --git a/.eslintrc.yml b/.eslintrc.yml
new file mode 100644
index 0000000..dc12061
--- /dev/null
+++ b/.eslintrc.yml
@@ -0,0 +1,50 @@
+env:
+ es6: true
+ node: true
+ mocha: true
+ jquery: true
+extends: 'eslint:recommended'
+parserOptions:
+ ecmaVersion: 6
+ sourceType:
+ - script
+rules:
+ indent:
+ - error
+ - 4
+ linebreak-style:
+ - error
+ - unix
+ quotes:
+ - error
+ - single
+ semi:
+ - error
+ - always
+ no-unused-vars:
+ - error
+ - args: none
+ no-console: off
+ no-case-declarations: off
+ curly: error
+ eqeqeq: error
+ no-throw-literal: error
+ strict: error
+ no-var: error
+ dot-notation: error
+ no-tabs: error
+ no-trailing-spaces: error
+ no-use-before-define: error
+ no-useless-call: error
+ no-with: error
+ operator-linebreak: error
+ require-jsdoc:
+ - error
+ - require:
+ ClassDeclaration: true
+ MethodDefinition: true
+ FunctionDeclaration: true
+ valid-jsdoc:
+ - error
+ - requireReturn: false
+ yoda: error
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..f5eee4d
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,14 @@
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text eol=lf
+
+# Explicitly declare text files you want to always be normalized and converted
+# to native line endings on checkout.
+*.js text
+*.css text
+*.html text
+*.json text
+*.sh text
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index bcdbc6f..a5167bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,11 +39,10 @@ jspm_packages
# OSX files
.DS_Store
+# env.json
Chapter00
package-lock.json
-*.key
-*.ppt
-*.pptx
+
composer-logs
*.bna
# Logs
diff --git a/Chapter03/createArchive.sh b/Chapter03/createArchive.sh
index f7640c6..cb2371a 100755
--- a/Chapter03/createArchive.sh
+++ b/Chapter03/createArchive.sh
@@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent
showStep "creating archive"
cd ./network
-composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
\ No newline at end of file
+composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
+#
+# new create command from tutorial is following:
+# composer archive create -t dir -n .
+#
\ No newline at end of file
diff --git a/Chapter03/create_composer_docs.sh b/Chapter03/create_composer_docs.sh
new file mode 100755
index 0000000..35e56da
--- /dev/null
+++ b/Chapter03/create_composer_docs.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+. ../common_OSX.sh
+
+CHAPTER_DIR=""
+DIR=""
+REPO_DIR=""
+ADMIN_DIR="node_modules/composer-admin"
+CLIENT_DIR="node_modules/composer-client"
+CLI_DIR="node_modules/composer-cli"
+COMMON_DIR="node_modules/composer-common"
+HLFV1_DIR="node_modules/composer-connector-hlfv1"
+RUNTIME_DIR="node_modules/composer-runtime"
+declare -a elements=("${ADMIN_DIR}" "$CLIENT_DIR" "${COMMON_DIR}" "${HLFV1_DIR}" "${RUNTIME_DIR}")
+declare -a folders=('Admin' 'Client' 'Common' 'hlfv1' 'Runtime')
+
+
+# get current folder
+showStep "getting current directory path"
+getCurrent
+CHAPTER_DIR=$DIR
+showStep "Chapter dir is: ${CHAPTER_DIR}"
+for i in "${elements[@]}"
+do
+# switch to folder
+ showStep "Changing to ${i}"
+ cd "${i}"
+ pwd
+# generate docs
+ showStep "Generating Documentation"
+ if [ ! -e "jsdoc.json" ]; then
+ cp jsdoc.conf jsdoc.json
+ fi
+ jsdoc --pedantic --recurse -c jsdoc.json
+ cd ../../
+done
+
+# get current folder -1
+ showStep "getting repo root folder"
+ cd ../
+ pwd
+ getCurrent
+ REPO_DIR=$DIR
+ showStep "repo dir is: ${REPO_DIR}"
+
+# remove old folders
+ showStep "Removing old documentation folders"
+ cd Composer_Docs
+ pwd
+ for i in "${folders[@]}"
+ do
+ # switch to folder
+ showStep "removing old docs in ${i}"
+ rm -rf "${i}"
+ mkdir "${i}"
+ done
+# copy new content
+ showStep "copying new content from node_modules in ${CHAPTER_DIR} to Composer_Docs in ${pwd}"
+ pwd
+ count=${#elements[@]}
+ for i in `seq 1 $count`
+ do
+ showStep "cp -R ${CHAPTER_DIR}/${elements[$i-1]}/out/ ${folders[$i-1]}"
+ cp -R ${CHAPTER_DIR}/${elements[$i-1]}/out/ ${folders[$i-1]}
+ done
+# display message on how to access documentation
+ showStep "Hyperledger Composer API documentation has been generated for your current version of Composer.
+ You can access this information by navigating to the ${GREEN}Composer_Docs${RESET} folder in your repo
+ and opening the ${GREEN}index.html${RESET} file located there in your favorite browser"
\ No newline at end of file
diff --git a/Chapter03/deployNetwork.sh b/Chapter03/deployNetwork.sh
index 9c13a36..d9042c9 100755
--- a/Chapter03/deployNetwork.sh
+++ b/Chapter03/deployNetwork.sh
@@ -80,12 +80,38 @@ showStep "deploying network"
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString
#
-# what the documentation implies is required
+# what the v0.14 documentation implies is required
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
#
-# what really works
-composer identity request -p hlfv1 -i admin -s adminpw
-composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# what really works for v0.14
+# composer identity request -p hlfv1 -i admin -s adminpw
+# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# cd network/dist
+# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+#
+# documentation for v0.15
+#
cd network/dist
-composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+showStep "installing PeerAdmin card"
+composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME
+showStep "starting network"
+# change in documentation
+# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card
+# corrected to:
+composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card
+showStep "importing networkadmin card"
+if composer card list -n admin@$NETWORK_NAME > /dev/null; then
+ composer card delete -n admin@$NETWORK_NAME
+fi
+composer card import --file networkadmin.card
+showStep "pinging admin@$NETWORK_NAME card"
+composer network ping --card admin@$NETWORK_NAME
+#
+# creating card for test program
+# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin
+# composer card import --file defaultProfile@hlfv1.card
+# showStep "pinging defaultProfile@hlfv1 card"
+# composer network ping --card defaultProfile@hlfv1
+#
+
diff --git a/Chapter03/favicon.ico b/Chapter03/favicon.ico
index 4126853..fc9e25d 100755
Binary files a/Chapter03/favicon.ico and b/Chapter03/favicon.ico differ
diff --git a/Chapter03/network/package.json b/Chapter03/network/package.json
index be89bc0..5ef56b0 100644
--- a/Chapter03/network/package.json
+++ b/Chapter03/network/package.json
@@ -36,11 +36,11 @@
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-admin": "^0.14.0",
- "composer-cli": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
+ "composer-admin": "^0.16.0",
+ "composer-cli": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
diff --git a/Chapter03/network/test/sample.js b/Chapter03/network/test/sample.js
index 0ea5df1..8b40e13 100644
--- a/Chapter03/network/test/sample.js
+++ b/Chapter03/network/test/sample.js
@@ -14,18 +14,12 @@
'use strict';
-const AdminConnection = require('composer-admin').AdminConnection;
-const BrowserFS = require('browserfs/dist/node/index');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
-const path = require('path');
require('chai').should();
const network = 'zerotoblockchain-network';
-const adminID = 'admin';
-const adminPW = 'adminpw';
-const bfs_fs = BrowserFS.BFSRequire('fs');
+const _timeout = 90000;
const NS = 'org.acme.Z2BTestNetwork';
const orderNo = '12345';
const buyerID = 'billybob@email.com';
@@ -36,7 +30,28 @@ const financeCoID = 'GlobalFinancier';
const dispute = 'ordered products received but defective';
const resolve = 'defective products will be refunded';
const backorder = 'order received, products on backorder. Will be shipped in 2 weeks.';
+let shipper;
+let provider;
+let financeCo;
let orderAmount = 0;
+let orderStatus = {
+ 'Created': {'code': 1, 'text': 'Order Created'},
+ 'Bought': {'code': 2, 'text': 'Order Purchased'},
+ 'Cancelled': {'code': 3, 'text': 'Order Cancelled'},
+ 'Ordered': {'code': 4, 'text': 'Order Submitted to Provider'},
+ 'ShipRequest': {'code': 5, 'text': 'Shipping Requested'},
+ 'Delivered': {'code': 6, 'text': 'Order Delivered'},
+ 'Delivering': {'code': 15, 'text': 'Order being Delivered'},
+ 'Backordered': {'code': 7, 'text': 'Order Backordered'},
+ 'Dispute': {'code': 8, 'text': 'Order Disputed'},
+ 'Resolve': {'code': 9, 'text': 'Order Dispute Resolved'},
+ 'PayRequest': {'code': 10, 'text': 'Payment Requested'},
+ 'Authorize': {'code': 11, 'text': 'Payment Approved'},
+ 'Paid': {'code': 14, 'text': 'Payment Processed'},
+ 'Refund': {'code': 12, 'text': 'Order Refund Requested'},
+ 'Refunded': {'code': 13, 'text': 'Order Refunded'}
+};
+
/**
* create an empty order
@@ -49,23 +64,25 @@ function createOrderTemplate (_inbound)
_inbound.orderNumber = '';
_inbound.amount = 0;
_inbound.items = [];
- _inbound.status = 'Order Created';
+ _inbound.status = JSON.stringify(orderStatus.Created);
_inbound.created = new Date().toISOString();
+ _inbound.cancelled = '';
_inbound.ordered = '';
_inbound.bought = '';
_inbound.dateBackordered = '';
_inbound.requestShipment = '';
_inbound.delivered = '';
+ _inbound.delivering = '';
_inbound.disputeOpened = '';
_inbound.disputeResolved = '';
_inbound.orderRefunded = '';
_inbound.paymentRequested = '';
+ _inbound.approved = '';
_inbound.paid = '';
_inbound.dispute = '';
_inbound.resolve = '';
_inbound.backorder = '';
_inbound.refund = '';
- _inbound.vendors = [];
return(_inbound);
}
/**
@@ -87,52 +104,19 @@ function addItems (_inbound)
orderAmount= _inbound.amount;
return (_inbound);
}
-/**
- * find a vendor in an array
- * @param {vendor_type} _string - type of vendor to find (e.g. 'supplier', 'shipper', etc.)
- * @param {vendor_array} _vendorArray - vendor array from order
- * @returns {$identifier} - returns the identifier if found else -1
- * @utility
- */
-function getVendor(_string, _vendorArray)
-{
- for (let each in _vendorArray)
- {for (let _prop in JSON.parse(_vendorArray[each]))
- {if (_prop === _string){return (JSON.parse(_vendorArray[each])[_string]);}}}
- return(-1);
-}
-
-describe('Finance Network', () => {
- // let adminConnection;
+describe('Finance Network', function () {
+ this.timeout(_timeout);
let businessNetworkConnection;
-
- before(() => {
- BrowserFS.initialize(new BrowserFS.FileSystem.InMemory());
- const adminConnection = new AdminConnection({ fs: bfs_fs });
- return adminConnection.createProfile('defaultProfile', {
- type: 'embedded'
- })
- .then(() => {
- return adminConnection.connect('defaultProfile', adminID, adminPW);
- })
- .then(() => {
- return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..'));
- })
- .then((businessNetworkDefinition) => {
- return adminConnection.deploy(businessNetworkDefinition);
- })
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs });
- return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW);
- });
+ before(function () {
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect('admin@zerotoblockchain-network');
});
describe('#createOrder', () => {
it('should be able to create an order', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
-
// create the buyer
const buyer = factory.newResource(NS, 'Buyer', buyerID);
buyer.companyName = 'billybob computing';
@@ -141,6 +125,18 @@ describe('Finance Network', () => {
const seller = factory.newResource(NS, 'Seller', sellerID);
seller.companyName = 'Simon PC Hardware, Inc';
+ // create the provider
+ provider = factory.newResource(NS, 'Provider', providerID);
+ provider.companyName = 'Ginsu Knife Specialists';
+
+ // create the shipper
+ shipper = factory.newResource(NS, 'Shipper', shipperID);
+ shipper.companyName = 'Fastest Ever Shippers';
+
+ // create the financeCo
+ financeCo = factory.newResource(NS, 'FinanceCo', financeCoID);
+ financeCo.companyName = 'The Global Financier';
+
// create the order
let order = factory.newResource(NS, 'Order', orderNo);
order = createOrderTemplate(order);
@@ -152,13 +148,17 @@ describe('Finance Network', () => {
order.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier);
order.seller = factory.newRelationship(NS, 'Seller', seller.$identifier);
+ order.provider = factory.newRelationship(NS, 'Provider', provider.$identifier);
+ order.shipper = factory.newRelationship(NS, 'Shipper', shipper.$identifier);
+ order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier);
+ createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier);
createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
createNew.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier);
createNew.seller = factory.newRelationship(NS, 'Seller', seller.$identifier);
createNew.amount = order.amount;
// the buyer should of the commodity should be buyer
//order.buyer.$identifier.should.equal(buyer.$identifier);
- order.status.should.equal('Order Created');
+ JSON.parse(order.status).text.should.equal(orderStatus.Created.text);
order.amount.should.equal(orderAmount);
createNew.amount.should.equal(orderAmount);
createNew.order.$identifier.should.equal(orderNo);
@@ -174,7 +174,7 @@ describe('Finance Network', () => {
})
.then((participantRegistry) => {
// add the buyer and seller
- return participantRegistry.addAll([buyer, seller]);
+ return participantRegistry.addAll([buyer, seller, shipper, provider]);
})
.then(() => {
// submit the transaction
@@ -226,7 +226,7 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.buyer.$identifier.should.equal(buyerID);
- newOrder.status.should.equal('Purchased');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Bought.text);
});
});
@@ -238,18 +238,10 @@ describe('Finance Network', () => {
it('should be able to issue a supplier order', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- // create the provider
- const provider = factory.newResource(NS, 'Provider', providerID);
- provider.companyName = 'Ginsu Knife Specialists';
-
// create the buy transaction
const orderNow = factory.newTransaction(NS, 'OrderFromSupplier');
return businessNetworkConnection.getParticipantRegistry(NS + '.Provider')
- .then((participantRegistry) => {
- // add the provider
- return participantRegistry.addAll([provider]);
- })
.then(() => {
return businessNetworkConnection.getAssetRegistry(NS + '.Order');
})
@@ -263,6 +255,7 @@ describe('Finance Network', () => {
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
orderNow.provider = factory.newRelationship(NS, 'Provider', providerID);
+ orderNow.seller = factory.newRelationship(NS, 'Seller', sellerID);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
.then(() => {
@@ -274,9 +267,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('supplier', newOrder.vendors);
- vendor.should.equal(providerID);
- newOrder.status.should.equal('Ordered From Supplier');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Ordered.text);
});
});
@@ -287,10 +278,6 @@ describe('Finance Network', () => {
it('should be able to issue a request to ship product', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- // create the shipper
- const shipper = factory.newResource(NS, 'Shipper', shipperID);
- shipper.companyName = 'Fastest Ever Shippers';
-
// create the buy transaction
const orderNow = factory.newTransaction(NS, 'RequestShipping');
@@ -311,6 +298,7 @@ describe('Finance Network', () => {
newOrder.$identifier.should.equal(orderNo);
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
+ orderNow.provider = factory.newRelationship(NS, 'Provider', providerID);
orderNow.shipper = factory.newRelationship(NS, 'Shipper', shipperID);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
@@ -323,9 +311,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('shipper', newOrder.vendors);
- vendor.should.equal(shipperID);
- newOrder.status.should.equal('Shipment Requested');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.ShipRequest.text);
});
});
@@ -361,9 +347,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('shipper', newOrder.vendors);
- vendor.should.equal(shipperID);
- newOrder.status.should.equal('Delivered');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Delivered.text);
});
});
@@ -375,10 +359,6 @@ describe('Finance Network', () => {
it('should be able to issue a request to request payment for a product', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- // create the financeCo
- const financeCo = factory.newResource(NS, 'FinanceCo', financeCoID);
- financeCo.companyName = 'The Global Financier';
-
// create the buy transaction
const orderNow = factory.newTransaction(NS, 'RequestPayment');
@@ -400,7 +380,6 @@ describe('Finance Network', () => {
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
@@ -413,17 +392,53 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('financeCo', newOrder.vendors);
- vendor.should.equal(financeCoID);
- newOrder.status.should.equal('Payment Requested');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.PayRequest.text);
});
});
});
});
- describe('#issuePayment', () => {
+ describe('#authorizePayment', () => {
- it('should be able to record a product payment', () => {
+ it('should be able to record a approval for order payment', () => {
+ const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+
+ // create the Deliver transaction
+ const orderNow = factory.newTransaction(NS, 'AuthorizePayment');
+
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order')
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ newOrder.buyer.$identifier.should.equal(buyerID);
+ newOrder.$identifier.should.equal(orderNo);
+
+ orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
+ orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
+ // submit the transaction
+ return businessNetworkConnection.submitTransaction(orderNow)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order');
+ })
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ // the owner of the commodity should be buyer
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Authorize.text);
+ });
+
+ });
+ });
+ });
+
+ describe('#Pay', () => {
+
+ it('should be able to record an order payment', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
// create the Deliver transaction
@@ -452,9 +467,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('financeCo', newOrder.vendors);
- vendor.should.equal(financeCoID);
- newOrder.status.should.equal('Paid');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Paid.text);
});
});
@@ -495,7 +508,7 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.dispute.should.equal(dispute);
- newOrder.status.should.equal('In Dispute');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Dispute.text);
});
});
@@ -523,6 +536,8 @@ describe('Finance Network', () => {
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier);
+ orderNow.shipper = factory.newRelationship(NS, 'Shipper', newOrder.shipper.$identifier);
+ orderNow.provider = factory.newRelationship(NS, 'Provider', provider.$identifier);
orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
@@ -536,7 +551,7 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.resolve.should.equal(resolve);
- newOrder.status.should.equal('Resolved');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Resolve.text);
});
});
@@ -562,7 +577,7 @@ describe('Finance Network', () => {
orderNow.backorder = backorder;
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
- orderNow.provider = factory.newRelationship(NS, 'Provider', JSON.parse(newOrder.vendors[0]).supplier);
+ orderNow.provider = factory.newRelationship(NS, 'Provider', providerID);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
.then(() => {
@@ -575,7 +590,44 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.backorder.should.equal(backorder);
- newOrder.status.should.equal('Backordered');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Backordered.text);
+ });
+
+ });
+ });
+ });
+ describe('#issueCancel', () => {
+
+ it('should be able to record an order cancellation', () => {
+ const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+
+ // create the Deliver transaction
+ const orderNow = factory.newTransaction(NS, 'OrderCancel');
+
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order')
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ newOrder.buyer.$identifier.should.equal(buyerID);
+ newOrder.$identifier.should.equal(orderNo);
+
+ orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
+ orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier);
+ orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
+ // submit the transaction
+ return businessNetworkConnection.submitTransaction(orderNow)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order');
+ })
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ // the owner of the commodity should be buyer
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Cancelled.text);
});
});
diff --git a/Chapter03/package.json b/Chapter03/package.json
index 01578b9..57535e3 100644
--- a/Chapter03/package.json
+++ b/Chapter03/package.json
@@ -1,6 +1,6 @@
{
"engines": {
- "composer": "^0.10.0"
+ "composer": ""
},
"name": "zerotoblockchain-network",
"version": "0.1.6",
@@ -17,7 +17,8 @@
"doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out",
"test-inner": "mocha -t 0 --recursive && cucumber-js",
"test-cover": "nyc npm run test-inner",
- "test": "mocha network/test --recursive -t 4000"
+ "test": "mocha network/test --recursive -t 4000",
+ "start": "node index"
},
"repository": {
"type": "git",
@@ -33,15 +34,17 @@
"author": "Bob Dill, IBM Distinguished Engineer",
"license": "Apache-2.0",
"devDependencies": {
+ "extend": "",
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-admin": "^0.14.0",
- "composer-cli": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-common": "",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
+ "composer-admin": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-common": "^0.16.0",
+ "composer-runtime": "^0.16.0",
+ "composer-runtime-hlfv1": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
@@ -83,5 +86,26 @@
"branches": 100,
"functions": 100,
"lines": 100
+ },
+ "dependencies": {
+ "body-parser": "^1.18.1",
+ "cfenv": "^1.0.4",
+ "connect-busboy": "0.0.2",
+ "cookie-parser": "^1.4.3",
+ "date-format": "",
+ "ejs": "",
+ "express": "^4.15.4",
+ "express-session": "^1.15.5",
+ "fabric-client": "^1.0.2",
+ "fs": "0.0.1-security",
+ "http": "0.0.0",
+ "https": "^1.0.0",
+ "mime": "^2.0.2",
+ "os": "^0.1.1",
+ "path": "^0.12.7",
+ "sleep": "^5.1.1",
+ "uuid": "^3.1.0",
+ "vcap_services": "^0.3.4",
+ "websocket": "^1.0.24"
}
}
diff --git a/Chapter03/shutdown.sh b/Chapter03/shutdown.sh
index 3fb615d..f270d76 100755
--- a/Chapter03/shutdown.sh
+++ b/Chapter03/shutdown.sh
@@ -1,40 +1,11 @@
#!/bin/bash
- YELLOW='\033[1;33m'
- RED='\033[1;31m'
- GREEN='\033[1;32m'
- RESET='\033[0m'
+. ../common_OSX.sh
-# indent text on echo
-function indent() {
- c='s/^/ /'
- case $(uname) in
- Darwin) sed -l "$c";;
- *) sed -u "$c";;
- esac
-}
-
-# Grab the current directory
-function getCurrent()
- {
- showStep "getting current directory"
- DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
- THIS_SCRIPT=`basename "$0"`
- showStep "Running '${THIS_SCRIPT}'"
- }
-
-# displays where we are, uses the indent function (above) to indent each line
-function showStep ()
- {
- echo -e "${YELLOW}=====================================================" | indent
- echo -e "${RESET}-----> $*" | indent
- echo -e "${YELLOW}=====================================================${RESET}" | indent
- }
showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}"
cd "${HLF_INSTALL_PATH}"
showStep "stopping fabric"
./stopFabric.sh
showStep "tear down"
./teardownFabric.sh
-showStep "shut down complete"#!/bin/bash
-
\ No newline at end of file
+showStep "shut down complete"
\ No newline at end of file
diff --git a/Chapter03/startup.sh b/Chapter03/startup.sh
index b4c76e2..a4602d8 100755
--- a/Chapter03/startup.sh
+++ b/Chapter03/startup.sh
@@ -35,6 +35,12 @@ showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}"
cd "${HLF_INSTALL_PATH}"
showStep "starting fabric"
~/fabric-tools/startFabric.sh
-showStep "creating new composer profile (required with each restart)"
-~/fabric-tools/createComposerProfile.sh
+#
+# no longer required with hyperledger composer V0.15
+# showStep "creating new composer profile (required with each restart)"
+# ~/fabric-tools/createComposerProfile.sh
+#
+showStep "creating new PeerAdmin card (required with each restart)"
+~/fabric-tools/createPeerAdminCard.sh
+composer card list --name PeerAdmin@hlfv1
showStep "start up complete"
\ No newline at end of file
diff --git a/Chapter03/z2c_login b/Chapter03/z2c_login
index 9743fc0..b8aba8a 100755
--- a/Chapter03/z2c_login
+++ b/Chapter03/z2c_login
@@ -1,6 +1,5 @@
#!/bin/bash
-ded_URL="https://api.w3ibm.bluemix.net"
pub_URL="https://api.ng.bluemix.net"
gb_URL="https://api.eu-gb.bluemix.net"
de_URL="https://api.eu-de.bluemix.net"
@@ -18,7 +17,7 @@ then targetURL=$de_URL
elif [[ $2 == "sydney" ]]
then targetURL=$au_URL
else
- echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:"
+ echo "Parameter 2 is required to be one of the following public designations:"
echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'"
echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'"
exit -1
diff --git a/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf
index a02f0e5..403f61b 100644
Binary files a/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf and b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf differ
diff --git a/Chapter04/Documentation/Chinese/Z2B_Chapter04.pptx b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pptx
new file mode 100644
index 0000000..b57eb6c
Binary files /dev/null and b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pptx differ
diff --git a/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf
index 7222a59..1368a58 100644
Binary files a/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf and b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf differ
diff --git a/Chapter04/Documentation/Espanol/Z2B_Chapter04.pptx b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pptx
new file mode 100644
index 0000000..3068903
Binary files /dev/null and b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pptx differ
diff --git a/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf
index 130b9c1..2906dd7 100644
Binary files a/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf and b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf differ
diff --git a/Chapter04/Documentation/Japanese/Z2B_Chapter04.pptx b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pptx
new file mode 100644
index 0000000..da31099
Binary files /dev/null and b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pptx differ
diff --git a/Chapter04/Documentation/Z2B Chapter04.pdf b/Chapter04/Documentation/Z2B Chapter04.pdf
index 2f4ed6f..8fdca08 100644
Binary files a/Chapter04/Documentation/Z2B Chapter04.pdf and b/Chapter04/Documentation/Z2B Chapter04.pdf differ
diff --git a/Chapter04/Documentation/answers/lib/sample_complete.js b/Chapter04/Documentation/answers/lib/sample_complete.js
index 1036514..0c5bd5c 100644
--- a/Chapter04/Documentation/answers/lib/sample_complete.js
+++ b/Chapter04/Documentation/answers/lib/sample_complete.js
@@ -253,16 +253,3 @@ function BackOrder(purchase) {
return assetRegistry.update(purchase.order);
});
}
-
-/**
- * display using console.log the properties of each property in the inbound object
- * @param {displayObjectProperties} _string - string name of object
- * @param {displayObjectProperties} _object - the object to be parsed
- * @utility
- */
-function displayObjectValues (_string, _object)
-{
- for (var prop in _object){
- console.log(_string+'-->'+prop+':\t '+(((typeof(_object[prop]) === 'object') || (typeof(_object[prop]) === 'function')) ? typeof(_object[prop]) : _object[prop]));
- }
-}
\ No newline at end of file
diff --git a/Chapter04/Documentation/answers/placeholder_complete.js b/Chapter04/Documentation/answers/placeholder_complete.js
deleted file mode 100644
index c5996b4..0000000
--- a/Chapter04/Documentation/answers/placeholder_complete.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-
-var extend = require('extend');
-var watson = require('watson-developer-cloud');
-var vcapServices = require('vcap_services');
-
-var config = require('../../env.json');
-
-exports.placeholder = function(req, res) {
-
-}
diff --git a/Chapter04/Documentation/answers/test/sample_complete.js b/Chapter04/Documentation/answers/test/sample_complete.js
index 1c3e3e6..e5e48e8 100644
--- a/Chapter04/Documentation/answers/test/sample_complete.js
+++ b/Chapter04/Documentation/answers/test/sample_complete.js
@@ -15,17 +15,17 @@
'use strict';
const AdminConnection = require('composer-admin').AdminConnection;
-const BrowserFS = require('browserfs/dist/node/index');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
+
+const hlc_idCard = require('composer-common').IdCard;
const path = require('path');
+const _home = require('os').homedir();
require('chai').should();
const network = 'zerotoblockchain-network';
-const adminID = 'admin';
-const adminPW = 'adminpw';
-const bfs_fs = BrowserFS.BFSRequire('fs');
+const _timeout = 90000;
const NS = 'org.acme.Z2BTestNetwork';
const orderNo = '12345';
const buyerID = 'billybob@email.com';
@@ -58,6 +58,7 @@ let orderStatus = {
'Refunded': {'code': 13, 'text': 'Order Refunded'}
};
+
/**
* create an empty order
* @param {createOrderTemplate} _inbound - Order created with factory.newResource(NS, 'Order', orderNo)
@@ -110,30 +111,12 @@ function addItems (_inbound)
return (_inbound);
}
-describe('Finance Network', () => {
-
- // let adminConnection;
+describe('Finance Network', function () {
+ this.timeout(_timeout);
let businessNetworkConnection;
-
- before(() => {
- BrowserFS.initialize(new BrowserFS.FileSystem.InMemory());
- const adminConnection = new AdminConnection({ fs: bfs_fs });
- return adminConnection.createProfile('defaultProfile', {
- type: 'embedded'
- })
- .then(() => {
- return adminConnection.connect('defaultProfile', adminID, adminPW);
- })
- .then(() => {
- return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..'));
- })
- .then((businessNetworkDefinition) => {
- return adminConnection.deploy(businessNetworkDefinition);
- })
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs });
- return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW);
- });
+ before(function () {
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect('admin@zerotoblockchain-network');
});
describe('#createOrder', () => {
diff --git a/Chapter04/createArchive.sh b/Chapter04/createArchive.sh
index f7640c6..cb2371a 100755
--- a/Chapter04/createArchive.sh
+++ b/Chapter04/createArchive.sh
@@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent
showStep "creating archive"
cd ./network
-composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
\ No newline at end of file
+composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
+#
+# new create command from tutorial is following:
+# composer archive create -t dir -n .
+#
\ No newline at end of file
diff --git a/Chapter04/create_composer_docs.sh b/Chapter04/create_composer_docs.sh
index 27aae4c..35e56da 100755
--- a/Chapter04/create_composer_docs.sh
+++ b/Chapter04/create_composer_docs.sh
@@ -1,37 +1,7 @@
#!/bin/bash
- YELLOW='\033[1;33m'
- RED='\033[1;31m'
- GREEN='\033[1;32m'
- RESET='\033[0m'
+. ../common_OSX.sh
-# indent text on echo
-function indent() {
- c='s/^/ /'
- case $(uname) in
- Darwin) sed -l "$c";;
- *) sed -u "$c";;
- esac
-}
-
-# Grab the current directory
-function getCurrent()
- {
- showStep "getting current directory"
- DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
- THIS_SCRIPT=`basename "$0"`
- showStep "Running '${THIS_SCRIPT}'"
- echo $DIR
-
- }
-
-# displays where we are, uses the indent function (above) to indent each line
-function showStep ()
- {
- echo -e "${YELLOW}=====================================================" | indent
- echo -e "${RESET}-----> $*" | indent
- echo -e "${YELLOW}=====================================================${RESET}" | indent
- }
CHAPTER_DIR=""
DIR=""
REPO_DIR=""
@@ -49,7 +19,7 @@ declare -a folders=('Admin' 'Client' 'Common' 'hlfv1' 'Runtime')
showStep "getting current directory path"
getCurrent
CHAPTER_DIR=$DIR
-echo "${CHAPTER_DIR}"
+showStep "Chapter dir is: ${CHAPTER_DIR}"
for i in "${elements[@]}"
do
# switch to folder
@@ -71,6 +41,7 @@ done
pwd
getCurrent
REPO_DIR=$DIR
+ showStep "repo dir is: ${REPO_DIR}"
# remove old folders
showStep "Removing old documentation folders"
@@ -84,7 +55,7 @@ done
mkdir "${i}"
done
# copy new content
- showStep "copying new content"
+ showStep "copying new content from node_modules in ${CHAPTER_DIR} to Composer_Docs in ${pwd}"
pwd
count=${#elements[@]}
for i in `seq 1 $count`
diff --git a/Chapter04/deployNetwork.sh b/Chapter04/deployNetwork.sh
index 9c13a36..d9042c9 100755
--- a/Chapter04/deployNetwork.sh
+++ b/Chapter04/deployNetwork.sh
@@ -80,12 +80,38 @@ showStep "deploying network"
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString
#
-# what the documentation implies is required
+# what the v0.14 documentation implies is required
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
#
-# what really works
-composer identity request -p hlfv1 -i admin -s adminpw
-composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# what really works for v0.14
+# composer identity request -p hlfv1 -i admin -s adminpw
+# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# cd network/dist
+# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+#
+# documentation for v0.15
+#
cd network/dist
-composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+showStep "installing PeerAdmin card"
+composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME
+showStep "starting network"
+# change in documentation
+# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card
+# corrected to:
+composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card
+showStep "importing networkadmin card"
+if composer card list -n admin@$NETWORK_NAME > /dev/null; then
+ composer card delete -n admin@$NETWORK_NAME
+fi
+composer card import --file networkadmin.card
+showStep "pinging admin@$NETWORK_NAME card"
+composer network ping --card admin@$NETWORK_NAME
+#
+# creating card for test program
+# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin
+# composer card import --file defaultProfile@hlfv1.card
+# showStep "pinging defaultProfile@hlfv1 card"
+# composer network ping --card defaultProfile@hlfv1
+#
+
diff --git a/Chapter04/favicon.ico b/Chapter04/favicon.ico
index 4126853..fc9e25d 100755
Binary files a/Chapter04/favicon.ico and b/Chapter04/favicon.ico differ
diff --git a/Chapter04/network/dist/networkadmin.card b/Chapter04/network/dist/networkadmin.card
new file mode 100644
index 0000000..7911698
Binary files /dev/null and b/Chapter04/network/dist/networkadmin.card differ
diff --git a/Chapter04/network/dist/placeholder.txt b/Chapter04/network/dist/placeholder.txt
index 6773299..b3a4252 100644
--- a/Chapter04/network/dist/placeholder.txt
+++ b/Chapter04/network/dist/placeholder.txt
@@ -1 +1 @@
-placeholder to force dist to clone
+placeholder
\ No newline at end of file
diff --git a/Chapter04/network/features/sample.feature b/Chapter04/network/features/sample.feature
deleted file mode 100644
index 4c5ba21..0000000
--- a/Chapter04/network/features/sample.feature
+++ /dev/null
@@ -1,176 +0,0 @@
-#
-# 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.
-#
-
-Feature: Sample
-
- Background:
- Given I have deployed the business network definition ..
- And I have added the following participants of type org.acme.sample.SampleParticipant
- | participantId | firstName | lastName |
- | alice@email.com | Alice | A |
- | bob@email.com | Bob | B |
- And I have added the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 1 | alice@email.com | 10 |
- | 2 | bob@email.com | 20 |
- And I have issued the participant org.acme.sample.SampleParticipant#alice@email.com with the identity alice1
- And I have issued the participant org.acme.sample.SampleParticipant#bob@email.com with the identity bob1
-
- Scenario: Alice can read all of the assets
- When I use the identity alice1
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 1 | alice@email.com | 10 |
- | 2 | bob@email.com | 20 |
-
- Scenario: Bob can read all of the assets
- When I use the identity alice1
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 1 | alice@email.com | 10 |
- | 2 | bob@email.com | 20 |
-
- Scenario: Alice can add assets that she owns
- When I use the identity alice1
- And I add the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 3 | alice@email.com | 30 |
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 3 | alice@email.com | 30 |
-
- Scenario: Alice cannot add assets that Bob owns
- When I use the identity alice1
- And I add the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 3 | bob@email.com | 30 |
- Then I should get an error matching /does not have .* access to resource/
-
- Scenario: Bob can add assets that he owns
- When I use the identity bob1
- And I add the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 4 | bob@email.com | 40 |
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 4 | bob@email.com | 40 |
-
- Scenario: Bob cannot add assets that Alice owns
- When I use the identity bob1
- And I add the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 4 | alice@email.com | 40 |
- Then I should get an error matching /does not have .* access to resource/
-
- Scenario: Alice can update her assets
- When I use the identity alice1
- And I update the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 1 | alice@email.com | 50 |
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 1 | alice@email.com | 50 |
-
- Scenario: Alice cannot update Bob's assets
- When I use the identity alice1
- And I update the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 2 | bob@email.com | 50 |
- Then I should get an error matching /does not have .* access to resource/
-
- Scenario: Bob can update his assets
- When I use the identity bob1
- And I update the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 2 | bob@email.com | 60 |
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 2 | bob@email.com | 60 |
-
- Scenario: Bob cannot update Alice's assets
- When I use the identity bob1
- And I update the following asset of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 1 | alice@email.com | 60 |
- Then I should get an error matching /does not have .* access to resource/
-
- Scenario: Alice can remove her assets
- When I use the identity alice1
- And I remove the following asset of type org.acme.sample.SampleAsset
- | assetId |
- | 1 |
- Then I should not have the following assets of type org.acme.sample.SampleAsset
- | assetId |
- | 1 |
-
- Scenario: Alice cannot remove Bob's assets
- When I use the identity alice1
- And I remove the following asset of type org.acme.sample.SampleAsset
- | assetId |
- | 2 |
- Then I should get an error matching /does not have .* access to resource/
-
- Scenario: Bob can remove his assets
- When I use the identity bob1
- And I remove the following asset of type org.acme.sample.SampleAsset
- | assetId |
- | 2 |
- Then I should not have the following assets of type org.acme.sample.SampleAsset
- | assetId |
- | 2 |
-
- Scenario: Bob cannot remove Alice's assets
- When I use the identity bob1
- And I remove the following asset of type org.acme.sample.SampleAsset
- | assetId |
- | 1 |
- Then I should get an error matching /does not have .* access to resource/
-
- Scenario: Alice can submit a transaction for her assets
- When I use the identity alice1
- And I submit the following transaction of type org.acme.sample.SampleTransaction
- | asset | newValue |
- | 1 | 50 |
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 1 | alice@email.com | 50 |
- And I should have received the following event of type org.acme.sample.SampleEvent
- | asset | oldValue | newValue |
- | 1 | 10 | 50 |
-
- Scenario: Alice cannot submit a transaction for Bob's assets
- When I use the identity alice1
- And I submit the following transaction of type org.acme.sample.SampleTransaction
- | asset | newValue |
- | 2 | 50 |
- Then I should get an error matching /does not have .* access to resource/
-
- Scenario: Bob can submit a transaction for his assets
- When I use the identity bob1
- And I submit the following transaction of type org.acme.sample.SampleTransaction
- | asset | newValue |
- | 2 | 60 |
- Then I should have the following assets of type org.acme.sample.SampleAsset
- | assetId | owner | value |
- | 2 | bob@email.com | 60 |
- And I should have received the following event of type org.acme.sample.SampleEvent
- | asset | oldValue | newValue |
- | 2 | 20 | 60 |
-
- Scenario: Bob cannot submit a transaction for Alice's assets
- When I use the identity bob1
- And I submit the following transaction of type org.acme.sample.SampleTransaction
- | asset | newValue |
- | 1 | 60 |
- Then I should get an error matching /does not have .* access to resource/
diff --git a/Chapter04/network/features/support/index.js b/Chapter04/network/features/support/index.js
deleted file mode 100644
index 7325f1f..0000000
--- a/Chapter04/network/features/support/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 composerSteps = require('composer-cucumber-steps');
-const cucumber = require('cucumber');
-
-module.exports = function () {
- composerSteps.call(this);
-};
-
-if (cucumber.defineSupportCode) {
- cucumber.defineSupportCode((context) => {
- module.exports.call(context);
- });
-}
diff --git a/Chapter04/network/lib/sample.js b/Chapter04/network/lib/sample.js
index 6a82d26..1036514 100644
--- a/Chapter04/network/lib/sample.js
+++ b/Chapter04/network/lib/sample.js
@@ -12,6 +12,24 @@
* limitations under the License.
*/
+var orderStatus = {
+ Created: {code: 1, text: 'Order Created'},
+ Bought: {code: 2, text: 'Order Purchased'},
+ Cancelled: {code: 3, text: 'Order Cancelled'},
+ Ordered: {code: 4, text: 'Order Submitted to Provider'},
+ ShipRequest: {code: 5, text: 'Shipping Requested'},
+ Delivered: {code: 6, text: 'Order Delivered'},
+ Delivering: {code: 15, text: 'Order being Delivered'},
+ Backordered: {code: 7, text: 'Order Backordered'},
+ Dispute: {code: 8, text: 'Order Disputed'},
+ Resolve: {code: 9, text: 'Order Dispute Resolved'},
+ PayRequest: {code: 10, text: 'Payment Requested'},
+ Authorize: {code: 11, text: 'Payment Approved'},
+ Paid: {code: 14, text: 'Payment Processed'},
+ Refund: {code: 12, text: 'Order Refund Requested'},
+ Refunded: {code: 13, text: 'Order Refunded'}
+};
+
/**
* create an order to purchase
* @param {org.acme.Z2BTestNetwork.CreateOrder} purchase - the order to be processed
@@ -20,8 +38,9 @@
function CreateOrder(purchase) {
purchase.order.buyer = purchase.buyer;
purchase.order.amount = purchase.amount;
+ purchase.order.financeCo = purchase.financeCo;
purchase.order.created = new Date().toISOString();
- purchase.order.status = "Order Created";
+ purchase.order.status = JSON.stringify(orderStatus.Created);
return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
.then(function (assetRegistry) {
return assetRegistry.update(purchase.order);
@@ -33,7 +52,35 @@ function CreateOrder(purchase) {
* @transaction
*/
function Buy(purchase) {
-
+ if (purchase.order.status = JSON.stringify(orderStatus.Created))
+ {
+ purchase.order.buyer = purchase.buyer;
+ purchase.order.seller = purchase.seller;
+ purchase.order.bought = new Date().toISOString();
+ purchase.order.status = JSON.stringify(orderStatus.Bought);
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
+ }
+}
+/**
+ * Record a request to cancel an order
+ * @param {org.acme.Z2BTestNetwork.OrderCancel} purchase - the order to be processed
+ * @transaction
+ */
+function OrderCancel(purchase) {
+ if ((purchase.order.status = JSON.stringify(orderStatus.Created)) || (purchase.order.status = JSON.stringify(orderStatus.Bought)))
+ {
+ purchase.order.buyer = purchase.buyer;
+ purchase.order.seller = purchase.seller;
+ purchase.order.cancelled = new Date().toISOString();
+ purchase.order.status = JSON.stringify(orderStatus.Cancelled);
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
+ }
}
/**
* Record a request to order by seller from supplier
@@ -41,7 +88,16 @@ function Buy(purchase) {
* @transaction
*/
function OrderFromSupplier(purchase) {
-
+ if (purchase.order.status = JSON.stringify(orderStatus.Bought))
+ {
+ purchase.order.provider = purchase.provider;
+ purchase.order.ordered = new Date().toISOString();
+ purchase.order.status = JSON.stringify(orderStatus.Ordered);
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
+ }
}
/**
* Record a request to ship by supplier to shipper
@@ -49,7 +105,34 @@ function OrderFromSupplier(purchase) {
* @transaction
*/
function RequestShipping(purchase) {
-
+ if (purchase.order.status = JSON.stringify(orderStatus.Ordered))
+ {
+ purchase.order.shipper = purchase.shipper;
+ purchase.order.requestShipment = new Date().toISOString();
+ purchase.order.status = JSON.stringify(orderStatus.ShipRequest);
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
+ }
+}
+/**
+ * Record a delivery by shipper
+ * @param {org.acme.Z2BTestNetwork.Delivering} purchase - the order to be processed
+ * @transaction
+ */
+function Delivering(purchase) {
+ if ((purchase.order.status = JSON.stringify(orderStatus.ShipRequest)) || (JSON.parse(purchase.order.status).code = orderStatus.Delivering.code))
+ {
+ purchase.order.delivering = new Date().toISOString();
+ var _status = orderStatus.Delivering;
+ _status.text += ' '+purchase.deliveryStatus;
+ purchase.order.status = JSON.stringify(_status);
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
+ }
}
/**
* Record a delivery by shipper
@@ -57,7 +140,15 @@ function RequestShipping(purchase) {
* @transaction
*/
function Deliver(purchase) {
-
+ if ((purchase.order.status = JSON.stringify(orderStatus.ShipRequest)) || (JSON.parse(purchase.order.status).code = orderStatus.Delivering.code))
+ {
+ purchase.order.delivered = new Date().toISOString();
+ purchase.order.status = JSON.stringify(orderStatus.Delivered);
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
+ }
}
/**
* Record a request for payment by the seller
@@ -65,7 +156,30 @@ function Deliver(purchase) {
* @transaction
*/
function RequestPayment(purchase) {
-
+ if ((JSON.parse(purchase.order.status).text == orderStatus.Delivered.text) || (JSON.parse(purchase.order.status).text == orderStatus.Resolve.text))
+ {purchase.order.status = JSON.stringify(orderStatus.PayRequest);
+ purchase.order.financeCo = purchase.financeCo;
+ purchase.order.paymentRequested = new Date().toISOString();
+ }
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
+}
+ /**
+ * Record a payment to the seller
+ * @param {org.acme.Z2BTestNetwork.AuthorizePayment} purchase - the order to be processed
+ * @transaction
+ */
+function AuthorizePayment(purchase) {
+ if ((JSON.parse(purchase.order.status).text == orderStatus.PayRequest.text ) || (JSON.parse(purchase.order.status).text == orderStatus.Resolve.text ))
+ {purchase.order.status = JSON.stringify(orderStatus.Authorize);
+ purchase.order.approved = new Date().toISOString();
+ }
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
}
/**
* Record a payment to the seller
@@ -73,7 +187,14 @@ function RequestPayment(purchase) {
* @transaction
*/
function Pay(purchase) {
-
+ if (JSON.parse(purchase.order.status).text == orderStatus.Authorize.text )
+ {purchase.order.status = JSON.stringify(orderStatus.Paid);
+ purchase.order.paid = new Date().toISOString();
+ }
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
}
/**
* Record a dispute by the buyer
@@ -81,7 +202,13 @@ function Pay(purchase) {
* @transaction
*/
function Dispute(purchase) {
-
+ purchase.order.status = JSON.stringify(orderStatus.Dispute);
+ purchase.order.dispute = purchase.dispute;
+ purchase.order.disputeOpened = new Date().toISOString();
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
}
/**
* Resolve a seller initiated dispute
@@ -89,7 +216,13 @@ function Dispute(purchase) {
* @transaction
*/
function Resolve(purchase) {
-
+ purchase.order.status = JSON.stringify(orderStatus.Resolve);
+ purchase.order.resolve = purchase.resolve;
+ purchase.order.disputeResolved = new Date().toISOString();
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
}
/**
* Record a refund to the buyer
@@ -97,7 +230,13 @@ function Resolve(purchase) {
* @transaction
*/
function Refund(purchase) {
-
+ purchase.order.status = JSON.stringify(orderStatus.Refund);
+ purchase.order.refund = purchase.refund;
+ purchase.order.orderRefunded = new Date().toISOString();
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
}
/**
* Record a backorder by the supplier
@@ -105,18 +244,25 @@ function Refund(purchase) {
* @transaction
*/
function BackOrder(purchase) {
-
+ purchase.order.status = JSON.stringify(orderStatus.Backordered);
+ purchase.order.backorder = purchase.backorder;
+ purchase.order.dateBackordered = new Date().toISOString();
+ purchase.order.provider = purchase.provider;
+ return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
+ .then(function (assetRegistry) {
+ return assetRegistry.update(purchase.order);
+ });
}
- /**
+
+/**
* display using console.log the properties of each property in the inbound object
* @param {displayObjectProperties} _string - string name of object
* @param {displayObjectProperties} _object - the object to be parsed
* @utility
*/
-
function displayObjectValues (_string, _object)
{
for (var prop in _object){
console.log(_string+'-->'+prop+':\t '+(((typeof(_object[prop]) === 'object') || (typeof(_object[prop]) === 'function')) ? typeof(_object[prop]) : _object[prop]));
}
-}
+}
\ No newline at end of file
diff --git a/Chapter04/network/models/events.cto b/Chapter04/network/models/events.cto
index c55a608..ab9f549 100644
--- a/Chapter04/network/models/events.cto
+++ b/Chapter04/network/models/events.cto
@@ -23,4 +23,69 @@ abstract event BasicEvent {
// notify seller, financeCo that an order has been placed
event requested extends BasicEvent {
o String orderNumber
+ o String sellerID
+ o String orderID
+}
+
+// notify seller, supplier that a fulfillment request has been placed
+event ordered extends BasicEvent {
+ o String orderNumber
+ o String providerID
+ o String orderID
+}
+
+// notify seller, buyer that items are on backorder
+event backordered extends BasicEvent {
+ o String orderNumber
+ o String sellerID
+ o String orderID
+}
+
+// notify seller, buyer, shipper that shipper has been contacted
+event shipRequest extends BasicEvent {
+ o String orderNumber
+ o String shipperID
+ o String orderID
+}
+
+// notify seller, supplier, buyer that order has been delivered
+event delivering extends BasicEvent {
+ o String orderNumber
+ o String buyerID
+ o String orderID
+}
+
+// notify seller, supplier, buyer that order has been delivered
+event delivered extends BasicEvent {
+ o String orderNumber
+ o String buyerID
+ o String orderID
+}
+
+// notify seller, financeCo that order is in dispute
+event dispute extends BasicEvent {
+ o String orderNumber
+ o String sellerID
+ o String orderID
+}
+
+// notify seller, buyer that dispute has been resolved
+event resolved extends BasicEvent {
+ o String orderNumber
+ o String sellerID
+ o String orderID
+}
+
+// notify financeCo, buyer that a request for payment has been issued
+event requestPayment extends BasicEvent {
+ o String buyerID
+ o String orderID
+ o String orderNumber
+}
+
+// notify seller, buyer that order has been paid /
+event Paid extends BasicEvent {
+ o String sellerID
+ o String orderID
+ o String orderNumber
}
diff --git a/Chapter04/network/models/sample.cto b/Chapter04/network/models/sample.cto
index 1c5e8de..a803085 100644
--- a/Chapter04/network/models/sample.cto
+++ b/Chapter04/network/models/sample.cto
@@ -1,20 +1,131 @@
-/**
- * Zero To Blockchain multi-party finance network
- */
-namespace org.acme.Z2BTestNetwork
-import composer.base.*
-import composer.events.*
-
-participant Buyer identified by buyerID extends Member{
- o String buyerID
-}
-
-asset Order identified by orderNumber {
- o String orderNumber
-
-}
- transaction CreateOrder {
- o Integer amount
- --> Order order
- --> Buyer buyer
-}
+/**
+ * Zero To Blockchain multi-party finance network
+ */
+namespace org.acme.Z2BTestNetwork
+import composer.base.*
+import composer.events.*
+
+participant Buyer identified by buyerID extends Member{
+ o String buyerID
+}
+participant Seller identified by sellerID extends Member{
+ o String sellerID
+}
+participant Shipper identified by shipperID extends Member {
+ o String shipperID
+}
+participant Provider identified by providerID extends Member {
+ o String providerID
+}
+participant FinanceCo identified by financeCoID extends Member {
+ o String financeCoID
+}
+
+asset Order identified by orderNumber {
+ o String orderNumber
+ o String[] items
+ o String status
+ o String dispute
+ o String resolve
+ o String backorder
+ o String refund
+ o Integer amount
+ o String created
+ o String bought
+ o String cancelled
+ o String ordered
+ o String dateBackordered
+ o String requestShipment
+ o String delivered
+ o String delivering
+ o String disputeOpened
+ o String disputeResolved
+ o String paymentRequested
+ o String orderRefunded
+ o String approved
+ o String paid
+ --> Provider provider
+ --> Shipper shipper
+ --> Buyer buyer
+ --> Seller seller
+ --> FinanceCo financeCo
+
+}
+ transaction CreateOrder {
+ o Integer amount
+ --> Order order
+ --> Buyer buyer
+ --> Seller seller
+ --> FinanceCo financeCo
+}
+ transaction OrderCancel {
+ --> Order order
+ --> Buyer buyer
+ --> Seller seller
+}
+ transaction Buy {
+ --> Order order
+ --> Buyer buyer
+ --> Seller seller
+}
+ transaction OrderFromSupplier {
+ --> Order order
+ --> Provider provider
+ --> Seller seller
+}
+ transaction RequestShipping {
+ --> Order order
+ --> Shipper shipper
+ --> Provider provider
+}
+ transaction Deliver {
+ --> Order order
+ --> Shipper shipper
+}
+ transaction Delivering {
+ o String deliveryStatus
+ --> Order order
+ --> Shipper shipper
+}
+ transaction BackOrder {
+ o String backorder
+ --> Order order
+ --> Provider provider
+}
+ transaction Dispute {
+ o String dispute
+ --> Order order
+ --> Buyer buyer
+ --> Seller seller
+ --> FinanceCo financeCo
+}
+ transaction Resolve {
+ o String resolve
+ --> Order order
+ --> Buyer buyer
+ --> Seller seller
+ --> Shipper shipper
+ --> Provider provider
+ --> FinanceCo financeCo
+}
+ transaction RequestPayment {
+ --> Order order
+ --> Seller seller
+ --> FinanceCo financeCo
+}
+ transaction AuthorizePayment {
+ --> Order order
+ --> Buyer buyer
+ --> FinanceCo financeCo
+}
+ transaction Pay {
+ --> Order order
+ --> Seller seller
+ --> FinanceCo financeCo
+}
+ transaction Refund {
+ o String refund
+ --> Order order
+ --> Seller seller
+ --> FinanceCo financeCo
+}
diff --git a/Chapter04/network/package.json b/Chapter04/network/package.json
index be89bc0..5ef56b0 100644
--- a/Chapter04/network/package.json
+++ b/Chapter04/network/package.json
@@ -36,11 +36,11 @@
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-admin": "^0.14.0",
- "composer-cli": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
+ "composer-admin": "^0.16.0",
+ "composer-cli": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
diff --git a/Chapter04/network/test/sample.js b/Chapter04/network/test/sample.js
index 0ea5df1..f6e7ea5 100644
--- a/Chapter04/network/test/sample.js
+++ b/Chapter04/network/test/sample.js
@@ -14,18 +14,12 @@
'use strict';
-const AdminConnection = require('composer-admin').AdminConnection;
-const BrowserFS = require('browserfs/dist/node/index');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
-const path = require('path');
require('chai').should();
-const network = 'zerotoblockchain-network';
-const adminID = 'admin';
-const adminPW = 'adminpw';
-const bfs_fs = BrowserFS.BFSRequire('fs');
+// const network = 'zerotoblockchain-network';
+const _timeout = 90000;
const NS = 'org.acme.Z2BTestNetwork';
const orderNo = '12345';
const buyerID = 'billybob@email.com';
@@ -36,7 +30,28 @@ const financeCoID = 'GlobalFinancier';
const dispute = 'ordered products received but defective';
const resolve = 'defective products will be refunded';
const backorder = 'order received, products on backorder. Will be shipped in 2 weeks.';
+let shipper;
+let provider;
+let financeCo;
let orderAmount = 0;
+let orderStatus = {
+ 'Created': {'code': 1, 'text': 'Order Created'},
+ 'Bought': {'code': 2, 'text': 'Order Purchased'},
+ 'Cancelled': {'code': 3, 'text': 'Order Cancelled'},
+ 'Ordered': {'code': 4, 'text': 'Order Submitted to Provider'},
+ 'ShipRequest': {'code': 5, 'text': 'Shipping Requested'},
+ 'Delivered': {'code': 6, 'text': 'Order Delivered'},
+ 'Delivering': {'code': 15, 'text': 'Order being Delivered'},
+ 'Backordered': {'code': 7, 'text': 'Order Backordered'},
+ 'Dispute': {'code': 8, 'text': 'Order Disputed'},
+ 'Resolve': {'code': 9, 'text': 'Order Dispute Resolved'},
+ 'PayRequest': {'code': 10, 'text': 'Payment Requested'},
+ 'Authorize': {'code': 11, 'text': 'Payment Approved'},
+ 'Paid': {'code': 14, 'text': 'Payment Processed'},
+ 'Refund': {'code': 12, 'text': 'Order Refund Requested'},
+ 'Refunded': {'code': 13, 'text': 'Order Refunded'}
+};
+
/**
* create an empty order
@@ -49,23 +64,25 @@ function createOrderTemplate (_inbound)
_inbound.orderNumber = '';
_inbound.amount = 0;
_inbound.items = [];
- _inbound.status = 'Order Created';
+ _inbound.status = JSON.stringify(orderStatus.Created);
_inbound.created = new Date().toISOString();
+ _inbound.cancelled = '';
_inbound.ordered = '';
_inbound.bought = '';
_inbound.dateBackordered = '';
_inbound.requestShipment = '';
_inbound.delivered = '';
+ _inbound.delivering = '';
_inbound.disputeOpened = '';
_inbound.disputeResolved = '';
_inbound.orderRefunded = '';
_inbound.paymentRequested = '';
+ _inbound.approved = '';
_inbound.paid = '';
_inbound.dispute = '';
_inbound.resolve = '';
_inbound.backorder = '';
_inbound.refund = '';
- _inbound.vendors = [];
return(_inbound);
}
/**
@@ -87,52 +104,19 @@ function addItems (_inbound)
orderAmount= _inbound.amount;
return (_inbound);
}
-/**
- * find a vendor in an array
- * @param {vendor_type} _string - type of vendor to find (e.g. 'supplier', 'shipper', etc.)
- * @param {vendor_array} _vendorArray - vendor array from order
- * @returns {$identifier} - returns the identifier if found else -1
- * @utility
- */
-function getVendor(_string, _vendorArray)
-{
- for (let each in _vendorArray)
- {for (let _prop in JSON.parse(_vendorArray[each]))
- {if (_prop === _string){return (JSON.parse(_vendorArray[each])[_string]);}}}
- return(-1);
-}
-
-describe('Finance Network', () => {
- // let adminConnection;
+describe('Finance Network', function () {
+ this.timeout(_timeout);
let businessNetworkConnection;
-
- before(() => {
- BrowserFS.initialize(new BrowserFS.FileSystem.InMemory());
- const adminConnection = new AdminConnection({ fs: bfs_fs });
- return adminConnection.createProfile('defaultProfile', {
- type: 'embedded'
- })
- .then(() => {
- return adminConnection.connect('defaultProfile', adminID, adminPW);
- })
- .then(() => {
- return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..'));
- })
- .then((businessNetworkDefinition) => {
- return adminConnection.deploy(businessNetworkDefinition);
- })
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs });
- return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW);
- });
+ before(function () {
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect('admin@zerotoblockchain-network');
});
describe('#createOrder', () => {
it('should be able to create an order', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
-
// create the buyer
const buyer = factory.newResource(NS, 'Buyer', buyerID);
buyer.companyName = 'billybob computing';
@@ -141,6 +125,18 @@ describe('Finance Network', () => {
const seller = factory.newResource(NS, 'Seller', sellerID);
seller.companyName = 'Simon PC Hardware, Inc';
+ // create the provider
+ provider = factory.newResource(NS, 'Provider', providerID);
+ provider.companyName = 'Ginsu Knife Specialists';
+
+ // create the shipper
+ shipper = factory.newResource(NS, 'Shipper', shipperID);
+ shipper.companyName = 'Fastest Ever Shippers';
+
+ // create the financeCo
+ financeCo = factory.newResource(NS, 'FinanceCo', financeCoID);
+ financeCo.companyName = 'The Global Financier';
+
// create the order
let order = factory.newResource(NS, 'Order', orderNo);
order = createOrderTemplate(order);
@@ -152,13 +148,17 @@ describe('Finance Network', () => {
order.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier);
order.seller = factory.newRelationship(NS, 'Seller', seller.$identifier);
+ order.provider = factory.newRelationship(NS, 'Provider', provider.$identifier);
+ order.shipper = factory.newRelationship(NS, 'Shipper', shipper.$identifier);
+ order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier);
+ createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier);
createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
createNew.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier);
createNew.seller = factory.newRelationship(NS, 'Seller', seller.$identifier);
createNew.amount = order.amount;
// the buyer should of the commodity should be buyer
//order.buyer.$identifier.should.equal(buyer.$identifier);
- order.status.should.equal('Order Created');
+ JSON.parse(order.status).text.should.equal(orderStatus.Created.text);
order.amount.should.equal(orderAmount);
createNew.amount.should.equal(orderAmount);
createNew.order.$identifier.should.equal(orderNo);
@@ -174,7 +174,7 @@ describe('Finance Network', () => {
})
.then((participantRegistry) => {
// add the buyer and seller
- return participantRegistry.addAll([buyer, seller]);
+ return participantRegistry.addAll([buyer, seller, shipper, provider]);
})
.then(() => {
// submit the transaction
@@ -226,7 +226,7 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.buyer.$identifier.should.equal(buyerID);
- newOrder.status.should.equal('Purchased');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Bought.text);
});
});
@@ -238,18 +238,10 @@ describe('Finance Network', () => {
it('should be able to issue a supplier order', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- // create the provider
- const provider = factory.newResource(NS, 'Provider', providerID);
- provider.companyName = 'Ginsu Knife Specialists';
-
// create the buy transaction
const orderNow = factory.newTransaction(NS, 'OrderFromSupplier');
return businessNetworkConnection.getParticipantRegistry(NS + '.Provider')
- .then((participantRegistry) => {
- // add the provider
- return participantRegistry.addAll([provider]);
- })
.then(() => {
return businessNetworkConnection.getAssetRegistry(NS + '.Order');
})
@@ -263,6 +255,7 @@ describe('Finance Network', () => {
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
orderNow.provider = factory.newRelationship(NS, 'Provider', providerID);
+ orderNow.seller = factory.newRelationship(NS, 'Seller', sellerID);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
.then(() => {
@@ -274,9 +267,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('supplier', newOrder.vendors);
- vendor.should.equal(providerID);
- newOrder.status.should.equal('Ordered From Supplier');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Ordered.text);
});
});
@@ -287,10 +278,6 @@ describe('Finance Network', () => {
it('should be able to issue a request to ship product', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- // create the shipper
- const shipper = factory.newResource(NS, 'Shipper', shipperID);
- shipper.companyName = 'Fastest Ever Shippers';
-
// create the buy transaction
const orderNow = factory.newTransaction(NS, 'RequestShipping');
@@ -311,6 +298,7 @@ describe('Finance Network', () => {
newOrder.$identifier.should.equal(orderNo);
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
+ orderNow.provider = factory.newRelationship(NS, 'Provider', providerID);
orderNow.shipper = factory.newRelationship(NS, 'Shipper', shipperID);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
@@ -323,9 +311,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('shipper', newOrder.vendors);
- vendor.should.equal(shipperID);
- newOrder.status.should.equal('Shipment Requested');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.ShipRequest.text);
});
});
@@ -361,9 +347,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('shipper', newOrder.vendors);
- vendor.should.equal(shipperID);
- newOrder.status.should.equal('Delivered');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Delivered.text);
});
});
@@ -375,10 +359,6 @@ describe('Finance Network', () => {
it('should be able to issue a request to request payment for a product', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- // create the financeCo
- const financeCo = factory.newResource(NS, 'FinanceCo', financeCoID);
- financeCo.companyName = 'The Global Financier';
-
// create the buy transaction
const orderNow = factory.newTransaction(NS, 'RequestPayment');
@@ -400,7 +380,6 @@ describe('Finance Network', () => {
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
@@ -413,17 +392,53 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('financeCo', newOrder.vendors);
- vendor.should.equal(financeCoID);
- newOrder.status.should.equal('Payment Requested');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.PayRequest.text);
});
});
});
});
- describe('#issuePayment', () => {
+ describe('#authorizePayment', () => {
- it('should be able to record a product payment', () => {
+ it('should be able to record a approval for order payment', () => {
+ const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+
+ // create the Deliver transaction
+ const orderNow = factory.newTransaction(NS, 'AuthorizePayment');
+
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order')
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ newOrder.buyer.$identifier.should.equal(buyerID);
+ newOrder.$identifier.should.equal(orderNo);
+
+ orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
+ orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
+ // submit the transaction
+ return businessNetworkConnection.submitTransaction(orderNow)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order');
+ })
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ // the owner of the commodity should be buyer
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Authorize.text);
+ });
+
+ });
+ });
+ });
+
+ describe('#Pay', () => {
+
+ it('should be able to record an order payment', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
// create the Deliver transaction
@@ -452,9 +467,7 @@ describe('Finance Network', () => {
})
.then((newOrder) => {
// the owner of the commodity should be buyer
- let vendor = getVendor('financeCo', newOrder.vendors);
- vendor.should.equal(financeCoID);
- newOrder.status.should.equal('Paid');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Paid.text);
});
});
@@ -495,7 +508,7 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.dispute.should.equal(dispute);
- newOrder.status.should.equal('In Dispute');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Dispute.text);
});
});
@@ -523,6 +536,8 @@ describe('Finance Network', () => {
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier);
+ orderNow.shipper = factory.newRelationship(NS, 'Shipper', newOrder.shipper.$identifier);
+ orderNow.provider = factory.newRelationship(NS, 'Provider', provider.$identifier);
orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
@@ -536,7 +551,7 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.resolve.should.equal(resolve);
- newOrder.status.should.equal('Resolved');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Resolve.text);
});
});
@@ -562,7 +577,7 @@ describe('Finance Network', () => {
orderNow.backorder = backorder;
orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
- orderNow.provider = factory.newRelationship(NS, 'Provider', JSON.parse(newOrder.vendors[0]).supplier);
+ orderNow.provider = factory.newRelationship(NS, 'Provider', providerID);
// submit the transaction
return businessNetworkConnection.submitTransaction(orderNow)
.then(() => {
@@ -575,7 +590,44 @@ describe('Finance Network', () => {
.then((newOrder) => {
// the owner of the commodity should be buyer
newOrder.backorder.should.equal(backorder);
- newOrder.status.should.equal('Backordered');
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Backordered.text);
+ });
+
+ });
+ });
+ });
+ describe('#issueCancel', () => {
+
+ it('should be able to record an order cancellation', () => {
+ const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+
+ // create the Deliver transaction
+ const orderNow = factory.newTransaction(NS, 'OrderCancel');
+
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order')
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ newOrder.buyer.$identifier.should.equal(buyerID);
+ newOrder.$identifier.should.equal(orderNo);
+
+ orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier);
+ orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier);
+ orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier);
+ // submit the transaction
+ return businessNetworkConnection.submitTransaction(orderNow)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS + '.Order');
+ })
+ .then((assetRegistry) => {
+ // re-get the commodity
+ return assetRegistry.get(orderNo);
+ })
+ .then((newOrder) => {
+ // the owner of the commodity should be buyer
+ JSON.parse(newOrder.status).text.should.equal(orderStatus.Cancelled.text);
});
});
diff --git a/Chapter04/package.json b/Chapter04/package.json
index 1d086ff..57535e3 100644
--- a/Chapter04/package.json
+++ b/Chapter04/package.json
@@ -17,7 +17,8 @@
"doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out",
"test-inner": "mocha -t 0 --recursive && cucumber-js",
"test-cover": "nyc npm run test-inner",
- "test": "mocha network/test --recursive -t 4000"
+ "test": "mocha network/test --recursive -t 4000",
+ "start": "node index"
},
"repository": {
"type": "git",
@@ -37,13 +38,13 @@
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
- "composer-admin": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-common": "^0.14.0",
- "composer-runtime": "^0.14.0",
- "composer-runtime-hlfv1": "^0.14.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
+ "composer-admin": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-common": "^0.16.0",
+ "composer-runtime": "^0.16.0",
+ "composer-runtime-hlfv1": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
@@ -100,6 +101,7 @@
"http": "0.0.0",
"https": "^1.0.0",
"mime": "^2.0.2",
+ "os": "^0.1.1",
"path": "^0.12.7",
"sleep": "^5.1.1",
"uuid": "^3.1.0",
diff --git a/Chapter04/shutdown.sh b/Chapter04/shutdown.sh
index 3fb615d..f270d76 100755
--- a/Chapter04/shutdown.sh
+++ b/Chapter04/shutdown.sh
@@ -1,40 +1,11 @@
#!/bin/bash
- YELLOW='\033[1;33m'
- RED='\033[1;31m'
- GREEN='\033[1;32m'
- RESET='\033[0m'
+. ../common_OSX.sh
-# indent text on echo
-function indent() {
- c='s/^/ /'
- case $(uname) in
- Darwin) sed -l "$c";;
- *) sed -u "$c";;
- esac
-}
-
-# Grab the current directory
-function getCurrent()
- {
- showStep "getting current directory"
- DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
- THIS_SCRIPT=`basename "$0"`
- showStep "Running '${THIS_SCRIPT}'"
- }
-
-# displays where we are, uses the indent function (above) to indent each line
-function showStep ()
- {
- echo -e "${YELLOW}=====================================================" | indent
- echo -e "${RESET}-----> $*" | indent
- echo -e "${YELLOW}=====================================================${RESET}" | indent
- }
showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}"
cd "${HLF_INSTALL_PATH}"
showStep "stopping fabric"
./stopFabric.sh
showStep "tear down"
./teardownFabric.sh
-showStep "shut down complete"#!/bin/bash
-
\ No newline at end of file
+showStep "shut down complete"
\ No newline at end of file
diff --git a/Chapter04/startup.sh b/Chapter04/startup.sh
index b4c76e2..a4602d8 100755
--- a/Chapter04/startup.sh
+++ b/Chapter04/startup.sh
@@ -35,6 +35,12 @@ showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}"
cd "${HLF_INSTALL_PATH}"
showStep "starting fabric"
~/fabric-tools/startFabric.sh
-showStep "creating new composer profile (required with each restart)"
-~/fabric-tools/createComposerProfile.sh
+#
+# no longer required with hyperledger composer V0.15
+# showStep "creating new composer profile (required with each restart)"
+# ~/fabric-tools/createComposerProfile.sh
+#
+showStep "creating new PeerAdmin card (required with each restart)"
+~/fabric-tools/createPeerAdminCard.sh
+composer card list --name PeerAdmin@hlfv1
showStep "start up complete"
\ No newline at end of file
diff --git a/Chapter04/z2c_login b/Chapter04/z2c_login
index 9743fc0..b8aba8a 100755
--- a/Chapter04/z2c_login
+++ b/Chapter04/z2c_login
@@ -1,6 +1,5 @@
#!/bin/bash
-ded_URL="https://api.w3ibm.bluemix.net"
pub_URL="https://api.ng.bluemix.net"
gb_URL="https://api.eu-gb.bluemix.net"
de_URL="https://api.eu-de.bluemix.net"
@@ -18,7 +17,7 @@ then targetURL=$de_URL
elif [[ $2 == "sydney" ]]
then targetURL=$au_URL
else
- echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:"
+ echo "Parameter 2 is required to be one of the following public designations:"
echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'"
echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'"
exit -1
diff --git a/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf
index 09309b3..07b156c 100644
Binary files a/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf and b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf differ
diff --git a/Chapter05/Documentation/Chinese/Z2B_Chapter05.pptx b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pptx
new file mode 100644
index 0000000..0e74563
Binary files /dev/null and b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pptx differ
diff --git a/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf
index 35e602a..0829563 100644
Binary files a/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf and b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf differ
diff --git a/Chapter05/Documentation/Espanol/Z2B_Chapter05.pptx b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pptx
new file mode 100644
index 0000000..1eaba4e
Binary files /dev/null and b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pptx differ
diff --git a/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf
index 15a25a3..dcebfa5 100644
Binary files a/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf and b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf differ
diff --git a/Chapter05/Documentation/Japanese/Z2B_Chapter05.pptx b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pptx
new file mode 100644
index 0000000..3226c0e
Binary files /dev/null and b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pptx differ
diff --git a/Chapter05/Documentation/Z2B Chapter05.pdf b/Chapter05/Documentation/Z2B Chapter05.pdf
index 1516823..7b51202 100644
Binary files a/Chapter05/Documentation/Z2B Chapter05.pdf and b/Chapter05/Documentation/Z2B Chapter05.pdf differ
diff --git a/Chapter05/Documentation/answers/HTML/admin_complete.html b/Chapter05/Documentation/answers/HTML/admin_complete.html
index a010464..53b3a2d 100644
--- a/Chapter05/Documentation/answers/HTML/admin_complete.html
+++ b/Chapter05/Documentation/answers/HTML/admin_complete.html
@@ -1,41 +1,45 @@
-
-
-
-
-
-
(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
y
-
-
-
-
+
Why All The Changes?
+
+
+
+
+
+
(
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
Result
-
-
+
+
+
y
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/Chapter05/Documentation/answers/HTML/removeMember_complete.html b/Chapter05/Documentation/answers/HTML/removeMember_complete.html
index 718b809..63adcf5 100644
--- a/Chapter05/Documentation/answers/HTML/removeMember_complete.html
+++ b/Chapter05/Documentation/answers/HTML/removeMember_complete.html
@@ -5,7 +5,7 @@
-
+
diff --git a/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js b/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js
index 27b12a3..8e9e8b9 100644
--- a/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js
+++ b/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js
@@ -16,19 +16,16 @@
'use strict';
const fs = require('fs');
const path = require('path');
+const _home = require('os').homedir();
+const hlc_idCard = require('composer-common').IdCard;
const composerAdmin = require('composer-admin');
const AdminConnection = require('composer-admin').AdminConnection;
-const composerClient = require('composer-client');
-const composerCommon = require('composer-common');
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const Serializer = require('composer-common').Serializer;
const config = require('../../../env.json');
const NS = 'org.acme.Z2BTestNetwork';
-const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
-var orderStatus = svc.orderStatus;
-
+// const svc = require('./Z2B_Services');
+// const mod = 'hlcAdmin.js';
/**
* display the admin and network info
@@ -56,7 +53,10 @@ exports.adminNew = function() {
*/
exports.adminConnect = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(function(){
console.log('create connection successful ');
res.send({connection: 'succeeded'});
@@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) {
* @function
*/
exports.createProfile = function(req, res, next) {
- let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL',
- 'keyValStore', 'channel', 'mspID', 'timeout'];
-
let adminOptions = {
type: req.body.type,
keyValStore: req.body.keyValStore,
@@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) {
peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}]
};
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.createProfile(req.body.profileName, adminOptions)
- .then(function(result){
- console.log('create profile successful: ');
- res.send({profile: 'succeeded'});
- })
- .catch(function(error){
- console.log('create profile failed: ',error);
- res.send({profile: error});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.createProfile(req.body.profileName, adminOptions)
+ .then(function(result){
+ console.log('create profile successful: ');
+ res.send({profile: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('create profile failed: ',error);
+ res.send({profile: error});
+ });
+ });
};
/**
* Deletes the specified connection profile from the profile store being used by this AdminConnection.
@@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) {
*/
exports.deleteProfile = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.deleteProfile(req.body.profileName)
- .then(function(result){
- console.log('delete profile successful: ',result);
- res.send({profile: 'succeeded'});
- })
- .catch(function(error){
- console.log('delete profile failed: ',error);
- res.send({profile: error});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.deleteProfile(req.body.profileName)
+ .then(function(result){
+ console.log('delete profile successful: ',result);
+ res.send({profile: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('delete profile failed: ',error);
+ res.send({profile: error});
+ });
+ });
};
+
/**
* Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
* @param {express.req} req - the inbound request object from the client
@@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.deploy = function(req, res, next) {
- let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
- let adminConnection = new composerAdmin.AdminConnection();
+ let adminConnection = new composerAdmin.AdminConnection();
- return BusinessNetworkDefinition.fromArchive(archiveFile)
- .then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.deploy(archive)
- .then(function(){
- console.log('business network '+req.body.myArchive+' deployed successful: ');
- res.send({deploy: req.body.myArchive+' deploy succeeded'});
- })
- .catch(function(error){
- console.log('business network '+req.body.myArchive+' deploy failed: ',error);
- res.send({deploy: error});
- });
+ return BusinessNetworkDefinition.fromArchive(archiveFile)
+ .then(function(archive) {
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.deploy(archive)
+ .then(function(){
+ console.log('business network '+req.body.myArchive+' deployed successful: ');
+ res.send({deploy: req.body.myArchive+' deploy succeeded'});
+ })
+ .catch(function(error){
+ console.log('business network '+req.body.myArchive+' deploy failed: ',error);
+ res.send({deploy: error});
});
- });
- };
+ });
+ });
+};
/**
* Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
* @param {express.req} req - the inbound request object from the client
@@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.networkInstall = function(req, res, next) {
@@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((businessNetworkDefinition) => {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(() => {
return adminConnection.install(businessNetworkDefinition.getName())
.then(() => {
@@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) {
.catch((error) => {
console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message);
res.send({install: error.message});
- });
- })
- .catch((error) => {console.log('error with adminConnection.connect', error.message)
- res.send({install: error.message});
});
- })
- .catch((error) => {console.log('error with fromArchive', error.message)});
+ })
+ .catch((error) => {console.log('error with adminConnection.connect', error.message);
+ res.send({install: error.message});
+ });
+ })
+ .catch((error) => {console.log('error with fromArchive', error.message);
res.send({install: error.message});
- }
+ });
+};
/**
* Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
@@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.networkStart = function(req, res, next) {
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(function(){
adminConnection.start(archive)
.then(function(){
@@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) {
.catch(function(error){
console.log('business network '+req.body.myArchive+' install failed: ',error);
res.send({install: error});
- });
- });
+ });
});
- };
+ });
+};
/**
* disconnects this connection
@@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) {
*/
exports.disconnect = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.disconnect()
- .then(function(result){
- console.log('network disconnect successful: ');
- res.send({disconnect: 'succeeded'});
- })
- .catch(function(error){
- console.log('network disconnect failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.disconnect()
+ .then(function(result){
+ console.log('network disconnect successful: ');
+ res.send({disconnect: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('network disconnect failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* Retrieve all connection profiles from the profile store being used by this AdminConnection.
@@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) {
*/
exports.getAllProfiles = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.getAllProfiles()
- .then((profiles) => {
- res.send(profiles);
- })
- .catch(function(error){
- console.log('network disconnect failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.getAllProfiles()
+ .then((profiles) => {
+ res.send(profiles);
+ })
+ .catch(function(error){
+ console.log('network disconnect failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* Retrieve the specified connection profile from the profile store being used by this AdminConnection.
@@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) {
*/
exports.getProfile = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.getProfile(req.body.connectionProfile)
- .then((profile) => {
- console.log('get profile Succeeded: ',profile);
- res.send(profile);
- })
- .catch(function(error){
- console.log('get profile failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.getProfile(req.body.connectionProfile)
+ .then((profile) => {
+ console.log('get profile Succeeded: ',profile);
+ res.send(profile);
+ })
+ .catch(function(error){
+ console.log('get profile failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* List all of the deployed business networks. The connection must be connected for this method to succeed.
@@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) {
*/
exports.listAsAdmin = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- util.displayObjectValuesRecursive(adminConnection);
// updated to use PeerAdmin, PeerPW to work with V0.14
- adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW)
- .then(function(){
- adminConnection.list()
- .then((businessNetworks) => {
- // Connection has been tested
- businessNetworks.forEach((businessNetwork) => {
- console.log('Deployed business network', businessNetwork);
- });
- res.send(businessNetworks);
- })
- .catch(function(_error){
- let error = _error;
- console.log('get business networks failed: ',error);
- res.send(error);
- });
- });
-};
-/**
- * List all of the deployed business networks. The connection must be connected for this method to succeed.
- * @param {express.req} req - the inbound request object from the client
- * @param {express.res} res - the outbound response object for communicating back to client
- * @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
- * @function
- */
-exports.listAsPeerAdmin = function(req, res, next) {
- let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.list()
- .then((businessNetworks) => {
- // Connection has been tested
- businessNetworks.forEach((businessNetwork) => {
- console.log('Deployed business network', businessNetwork);
- });
- res.send(businessNetworks);
- })
- .catch(function(_error){
- let error = _error;
- console.log('get business networks failed: ',error);
- res.send(error);
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ console.log('config.composer.PeerCard: '+config.composer.PeerCard);
+ adminConnection.connect(config.composer.PeerCard)
+ .then(function(){
+ adminConnection.list()
+ .then((businessNetworks) => {
+ // Connection has been tested
+ businessNetworks.forEach((businessNetwork) => {
+ console.log('Deployed business network', businessNetwork);
});
- });
+ res.send(businessNetworks);
+ })
+ .catch(function(_error){
+ let error = _error;
+ console.log('get business networks failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module.
@@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) {
*/
exports.ping = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork)
- .then(function(){
- adminConnection.ping()
- .then(function(result){
- console.log('network ping successful: ',result);
- res.send({ping: result});
- })
- .catch(function(error){
- let _error = error;
- console.log('network ping failed: '+_error);
- res.send({ping: _error.toString()});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.ping()
+ .then(function(result){
+ console.log('network ping successful: ',result);
+ res.send({ping: result});
+ })
+ .catch(function(error){
+ let _error = error;
+ console.log('network ping failed: '+_error);
+ res.send({ping: _error.toString()});
+ });
+ });
};
/**
* Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions.
@@ -388,19 +391,22 @@ exports.ping = function(req, res, next) {
*/
exports.undeploy = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork)
- .then(function(){
- adminConnection.undeploy(req.body.businessNetwork)
- .then(function(result){
- console.log(req.body.businessNetwork+' network undeploy successful ');
- res.send({undeploy: req.body.businessNetwork+' network undeploy successful '});
- })
- .catch(function(error){
- let _error = error;
- console.log(req.body.businessNetwork+' network undeploy failed: '+_error);
- res.send({undeploy: _error.toString()});
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.undeploy(req.body.businessNetwork)
+ .then(function(result){
+ console.log(req.body.businessNetwork+' network undeploy successful ');
+ res.send({undeploy: req.body.businessNetwork+' network undeploy successful '});
+ })
+ .catch(function(error){
+ let _error = error;
+ console.log(req.body.businessNetwork+' network undeploy failed: '+_error);
+ res.send({undeploy: _error.toString()});
});
+ });
};
/**
* Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed.
@@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) {
* req.body.myArchive: _string - name of archive to deploy
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.update = function(req, res, next) {
@@ -419,21 +425,24 @@ exports.update = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
- .then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName)
- .then(function(){
- adminConnection.update(archive)
- .then(function(){
- console.log(netName+' network update successful: ');
- res.send({update: req.body.myArchive+' network update successful '});
- })
- .catch(function(error){
- let _error = error;
- console.log(req.body.myArchive+' network update failed: '+_error);
- res.send({update: _error.toString()});
- });
- });
+ .then(function(archive) {
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.update(archive)
+ .then(function(){
+ console.log(netName+' network update successful: ');
+ res.send({update: req.body.myArchive+' network update successful '});
+ })
+ .catch(function(error){
+ let _error = error;
+ console.log(req.body.myArchive+' network update failed: '+_error);
+ res.send({update: _error.toString()});
+ });
});
+ });
};
/**
@@ -441,7 +450,7 @@ exports.update = function(req, res, next) {
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns array of registries
+ * @returns {Object} array of registries
* @function
*/
exports.getRegistries = function(req, res, next)
@@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next)
// connect to the network
let allRegistries = new Array();
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getAllParticipantRegistries()
- .then(function(participantRegistries){
- for (let each in participantRegistries)
- { (function (_idx, _arr)
- { let r_type = _arr[_idx].name.split('.');
- allRegistries.push([r_type[r_type.length-1]]);
- })(each, participantRegistries)
- }
- res.send({'result': 'success', 'registries': allRegistries});
- })
- .catch((error) => {console.log('error with getAllRegistries', error)});
- })
- .catch((error) => {console.log('error with business network Connect', error)});
+ return businessNetworkConnection.getAllParticipantRegistries()
+ .then(function(participantRegistries){
+ for (let each in participantRegistries)
+ { (function (_idx, _arr)
+ {
+ let r_type = _arr[_idx].name.split('.');
+ allRegistries.push([r_type[r_type.length-1]]);
+ })(each, participantRegistries);
+ }
+ res.send({'result': 'success', 'registries': allRegistries});
+ })
+ .catch((error) => {console.log('error with getAllRegistries', error);});
})
- .catch((error) => {console.log('error with admin network Connect', error)});
-}
+ .catch((error) => {console.log('error with business network Connect', error);});
+};
/**
* retrieve array of members from specified registry type
@@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next)
* req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of members
+ * @returns {Object} an array of members
* @function
*/
exports.getMembers = function(req, res, next) {
// connect to the network
+ // let method = 'getMembers';
let allMembers = new Array();
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
- .then(function(registry){
- return registry.getAll()
- .then ((members) => {
- for (let each in members)
- { (function (_idx, _arr)
- { let _jsn = {};
- _jsn.type = req.body.registry;
- _jsn.companyName = _arr[_idx].companyName;
- switch (req.body.registry)
- {
- case 'Buyer':
- _jsn.id = _arr[_idx].buyerID;
- break;
- case 'Seller':
- _jsn.id = _arr[_idx].sellerID;
- break;
- case 'Provider':
- _jsn.id = _arr[_idx].providerID;
- break;
- case 'Shipper':
- _jsn.id = _arr[_idx].shipperID;
- break;
- case 'FinanceCo':
- _jsn.id = _arr[_idx].financeCoID;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allMembers.push(_jsn); })(each, members)
- }
- res.send({'result': 'success', 'members': allMembers});
- })
- .catch((error) => {console.log('error with getAllMembers', error);
- res.send({'result': 'failed '+error.message, 'members': []});});
- })
- .catch((error) => {console.log('error with getRegistry', error);
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
+ .then(function(registry){
+ return registry.getAll()
+ .then ((members) => {
+ for (let each in members)
+ { (function (_idx, _arr)
+ { let _jsn = {};
+ _jsn.type = req.body.registry;
+ _jsn.companyName = _arr[_idx].companyName;
+ switch (req.body.registry)
+ {
+ case 'Buyer':
+ _jsn.id = _arr[_idx].buyerID;
+ break;
+ case 'Seller':
+ _jsn.id = _arr[_idx].sellerID;
+ break;
+ case 'Provider':
+ _jsn.id = _arr[_idx].providerID;
+ break;
+ case 'Shipper':
+ _jsn.id = _arr[_idx].shipperID;
+ break;
+ case 'FinanceCo':
+ _jsn.id = _arr[_idx].financeCoID;
+ break;
+ default:
+ _jsn.id = _arr[_idx].id;
+ }
+ allMembers.push(_jsn); })(each, members);
+ }
+ res.send({'result': 'success', 'members': allMembers});
+ })
+ .catch((error) => {console.log('error with getAllMembers', error);
res.send({'result': 'failed '+error.message, 'members': []});});
- })
- .catch((error) => {console.log('error with business network Connect', error.message);
- res.send({'result': 'failed '+error.message, 'members': []});});
+ })
+ .catch((error) => {console.log('error with getRegistry', error);
+ res.send({'result': 'failed '+error.message, 'members': []});});
})
- .catch((error) => {console.log('error with admin network Connect', error);
- res.send({'result': 'failed '+error.message, 'members': []});});
+ .catch((error) => {console.log('error with business network Connect', error.message);
+ res.send({'result': 'failed '+error.message, 'members': []});});
+};
-}
+/**
+ * Checks to see if the provided id already has a card issued for it
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * returns {object} - a JSON object
+ * @function
+ */
+exports.checkCard = function(req, res, next) {
+ let adminConnection = new AdminConnection();
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {adminConnection.hasCard(req.body.id)
+ .then((_res) => {
+ let cardState = ((_res) ? 'exists' : 'does not exist');
+ res.send({'result': 'success', 'card': cardState});
+ })
+ .catch((error) => {
+ res.send({'result': 'failed', 'message': error.message});
+ });
+ })
+ .catch((error) => {
+ res.send({'result': 'admin Connect failed', 'message': error.message});
+ });
+};
+
+/**
+ * Creates a card for an existing member
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * req.body.pw - the pw of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * returns {object} - a JSON object
+ * @function
+ */
+exports.createCard = function(req, res, next) {
+ let adminConnection = new AdminConnection();
+ let _meta = {};
+ for (let each in config.composer.metaData)
+ {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); }
+ _meta.businessNetwork = config.composer.network;
+ _meta.userName = req.body.id;
+ _meta.enrollmentSecret = req.body.secret;
+ config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore;
+ let tempCard = new hlc_idCard(_meta, config.connectionProfile);
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return adminConnection.importCard(req.body.id, tempCard)
+ .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported');
+ console.log('create Card succeeded:'+_msg);
+ res.send({'result': 'success', 'card': _msg});
+ })
+ .catch((error) => {
+ console.error('adminConnection.importCard failed. ',error.message);
+ res.send({'result': 'failed', 'error': error.message});
+ });
+ })
+ .catch((error) => {
+ console.error('adminConnection.connect failed. ',error.message);
+ res.send({'result': 'failed', 'error': error.message});
+ });
+};
+
+/**
+ * creates an identity for a member already created in a member registry
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * req.body.type - the member type of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * @returns {object} - a JSON object
+ * @function
+ */
+exports.issueIdentity = function(req, res, next) {
+ let businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id);
+ return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id)
+ .then((result) => {
+ console.log('result.userID: '+result.userID);
+ console.log('result.userSecret: '+result.userSecret);
+ res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret});
+ })
+ .catch((error) => {
+ res.send({'result': 'failed', 'message': error.message});
+ });
+ })
+ .catch((error) => {
+ res.send({'result': 'business network Connect failed', 'message': error.message});
+ });
+};
/**
* gets the assets from the order registry
@@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) {
* req.body.id - the id of the individual making the request
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} - an array of assets
* @function
*/
exports.getAssets = function(req, res, next) {
- // connect to the network
- let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json')));
- let allOrders = new Array();
- let businessNetworkConnection;
- let factory;
- let serializer;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connect to the network
+ let allOrders = new Array();
+ let businessNetworkConnection;
+ let serializer;
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return BusinessNetworkDefinition.fromArchive(archiveFile)
+ .then((bnd) => {
+ serializer = bnd.getSerializer();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
-// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON);
-// retry this with fromArchive when time allows
-// serializer = bnd.getSerializer();
- return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry)
- .then(function(registry){
- return registry.getAll()
- .then ((members) => {
- console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace);
- for (let each in members)
- { (function (_idx, _arr)
+ return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry)
+ .then(function(registry){
+ return registry.getAll()
+ .then ((members) => {
+ console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace);
+ for (let each in members)
+ { (function (_idx, _arr)
+ {
+ switch(req.body.type)
+ {
+ case 'Buyer':
+ if (req.body.id === _arr[_idx].buyer.$identifier)
{
- switch(req.body.type)
+ let _jsn = serializer.toJSON(_arr[_idx]);
+ _jsn.type = req.body.registry;
+ switch (req.body.registry)
{
- case 'Buyer':
- if (req.body.id == _arr[_idx].buyer.$identifier)
- {
- let _jsn = svc.getOrderData(_arr[_idx]);
- _jsn.type = req.body.registry;
- switch (req.body.registry)
- {
- case 'Order':
- _jsn.id = _arr[_idx].orderNumber;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allOrders.push(_jsn);
- }
- break;
- case 'admin':
- let _jsn = svc.getOrderData(_arr[_idx]);
- _jsn.type = req.body.registry;
- switch (req.body.registry)
- {
- case 'Order':
- _jsn.id = _arr[_idx].orderNumber;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allOrders.push(_jsn);
- break;
- default:
+ case 'Order':
+ _jsn.id = _arr[_idx].orderNumber;
break;
+ default:
+ _jsn.id = _arr[_idx].id;
}
- })(each, members)
+ allOrders.push(_jsn);
+ }
+ break;
+ case 'admin':
+ let _jsn = serializer.toJSON(_arr[_idx]);
+ _jsn.type = req.body.registry;
+ switch (req.body.registry)
+ {
+ case 'Order':
+ _jsn.id = _arr[_idx].orderNumber;
+ break;
+ default:
+ _jsn.id = _arr[_idx].id;
+ }
+ allOrders.push(_jsn);
+ break;
+ default:
+ break;
}
- res.send({'result': 'success', 'orders': allOrders});
- })
- .catch((error) => {console.log('error with getAllOrders', error)
- res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message});
- });
- })
- .catch((error) => {console.log('error with getRegistry', error)
- res.send({'result': 'failed', 'error': 'getRegistry: '+error.message});
- });
+ })(each, members);
+ }
+ res.send({'result': 'success', 'orders': allOrders});
})
- .catch((error) => {console.log('error with business network Connect', error)
- res.send({'result': 'failed', 'error': 'business network Connect: '+error.message});
+ .catch((error) => {console.log('error with getAllOrders', error);
+ res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('error with getRegistry', error);
+ res.send({'result': 'failed', 'error': 'getRegistry: '+error.message});
});
- })
- .catch((error) => {console.log('error with admin network Connect', error)
- res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message});
- });
-}
+ })
+ .catch((error) => {console.log('error with business network Connect', error);
+ res.send({'result': 'failed', 'error': 'business network Connect: '+error.message});
+ });
+ });
+};
/**
* Adds a new member to the specified registry
@@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) {
* req.body.id: _string - id of member to add (email address)
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns JSON object with success or error results
+ * @returns {JSON} object with success or error results
* @function
*/
exports.addMember = function(req, res, next) {
let businessNetworkConnection;
let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type)
- .then(function(participantRegistry){
- return participantRegistry.get(req.body.id)
- .then((_res) => { res.send('member already exists. add cancelled');})
- .catch((_res) => {
- console.log(req.body.id+' not in '+req.body.type+' registry. ');
- let participant = factory.newResource(NS, req.body.type,req.body.id);
- participant.companyName = req.body.companyName;
- participantRegistry.add(participant)
- .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");})
- .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);});
- });
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);});
- })
- .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);});
- })
- .catch((error) => {console.log('error with adminConnection', error); res.send(error);});
-}
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type)
+ .then(function(participantRegistry){
+ return participantRegistry.get(req.body.id)
+ .then((_res) => { res.send('member already exists. add cancelled');})
+ .catch((_res) => {
+ console.log(req.body.id+' not in '+req.body.type+' registry. ');
+ let participant = factory.newResource(NS, req.body.type,req.body.id);
+ participant.companyName = req.body.companyName;
+ participantRegistry.add(participant)
+ .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');})
+ .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);});
+ });
+ })
+ .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);});
+ })
+ .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);});
+};
/**
* Removes a member from a registry.
@@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) {
* req.body.id: _string - id of member to delete
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns JSON object with success or error results
+ * @returns {JSON} object with success or error results
* @function
*/
exports.removeMember = function(req, res, next) {
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
- .then(function(participantRegistry){
- return participantRegistry.get(req.body.id)
- .then((_res) => {
- return participantRegistry.remove(req.body.id)
- .then((_res) => {
- res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.');
- })
- .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
- res.send('member already exists. add cancelled');
- })
- .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
+ .then(function(participantRegistry){
+ return participantRegistry.get(req.body.id)
+ .then((_res) => {
+ return participantRegistry.remove(req.body.id)
+ .then((_res) => {
+ res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.');
})
- .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);});
+ .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');
+ res.send('member already exists. add cancelled');
+ });
})
- .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);});
+ .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
})
- .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);});
-}
+ .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);});
+ })
+ .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);});
+};
/**
* get Historian Records
@@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) {
* req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of members
+ * @returns {Array} an array of members
* @function
*/
exports.getHistory = function(req, res, next) {
let allHistory = new Array();
let businessNetworkConnection;
- let factory;
let ser;
let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
- let adminConnection = new AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((bnd) => {
ser = bnd.getSerializer();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord')
- .then(function(registry){
- return registry.getAll()
- .then ((history) => {
- for (let each in history)
- { (function (_idx, _arr)
- { let _jsn = _arr[_idx];
- allHistory.push(ser.toJSON(_jsn));
- })(each, history)
- }
- res.send({'result': 'success', 'history': allHistory});
- })
- .catch((error) => {console.log('error with getAll History', error)});
- })
- .catch((error) => {console.log('error with getRegistry', error)});
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord')
+ .then(function(registry){
+ return registry.getAll()
+ .then ((history) => {
+ for (let each in history)
+ { (function (_idx, _arr)
+ { let _jsn = _arr[_idx];
+ allHistory.push(ser.toJSON(_jsn));
+ })(each, history);
+ }
+ res.send({'result': 'success', 'history': allHistory});
})
- .catch((error) => {console.log('error with business network Connect', error)});
- })
- .catch((error) => {console.log('error with admin network Connect', error)});
+ .catch((error) => {console.log('error with getAll History', error);});
+ })
+ .catch((error) => {console.log('error with getRegistry', error);});
+ })
+ .catch((error) => {console.log('error with business network Connect', error);});
})
- .catch((error) => {console.log('error with business network definition', error)});
-}
+ .catch((error) => {console.log('error with admin network Connect', error);});
+};
diff --git a/Chapter05/Documentation/answers/js/z2b-admin_complete.js b/Chapter05/Documentation/answers/js/z2b-admin_complete.js
index c716cb8..1ad3017 100644
--- a/Chapter05/Documentation/answers/js/z2b-admin_complete.js
+++ b/Chapter05/Documentation/answers/js/z2b-admin_complete.js
@@ -14,57 +14,53 @@
// z2b-admin.js
-var creds;
-var connection;
-var connectionProfileName = 'z2b-test-profile';
-var networkFile = 'zerotoblockchain-network.bna'
-var businessNetwork = 'zerotoblockchain-network';
-var msgPort = null;
-var _blctr = 0;
+'use strict';
+
+let creds;
+let connection;
+let msgPort = null;
+let _blctr = 0;
/**
* load the administration User Experience
*/
function loadAdminUX ()
{
- toLoad = 'admin.html';
- $.when($.get(toLoad)).done(function (page)
- {$('#body').empty();
- $('#body').append(page);
- updatePage("admin");
- listMemRegistries();
- });
+ let toLoad = 'admin.html';
+ $.when($.get(toLoad)).done(function (page)
+ {$('#body').empty();
+ $('#body').append(page);
+ updatePage('admin');
+ listMemRegistries();
+ });
}
/**
* connect to the provided web socket
- * @param {loc} - _target location to post messages
- * @param {port} - web socket port #
+ * @param {String} _target - location to post messages
+ * @param {Integer} _port - web socket port #
*/
function wsDisplay(_target, _port)
{
- var content = $('#'+_target);
- var wsSocket = new WebSocket('ws://localhost:'+_port);
- wsSocket.onopen = function () {wsSocket.send('connected to client');};
-
- wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));};
-
- wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);};
-
+ let content = $('#'+_target);
+ let wsSocket = new WebSocket('ws://localhost:'+_port);
+ wsSocket.onopen = function () {wsSocket.send('connected to client');};
+ wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));};
+ wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);};
}
/**
* list the available business networks
*/
function adminList()
{
- var _url = '/composer/admin/listAsAdmin';
- $.when($.get(_url)).done(function (_connection)
- { var _str = '
Current Active Business Networks
';
- for (each in _connection)
- {(function(_idx, _arr){_str += '
';
- for (each in _profiles) {_str += displayProfile(_profiles[each], each)}
- _str += '
';
- $('#admin-forms').empty();
- $('#admin-forms').append(_str);
-
- });
+ $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles)
+ {
+ let _str = '';
+ // ========> Your Code Goes Here <=========
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+
+ });
}
/**
* gather and list all of the current network connection profiles
- * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button.
- * This allows the same routine to be used for display or delete processing
+ * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button.
+ * This allows the same routine to be used for display or delete processing
*/
function listProfiles(_state)
{
- $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page)
- {
- $('#admin-forms').empty();
- $('#admin-forms').append(page);
- updatePage("deleteConnectionProfile");
- $('#connection_profiles').on('change',function()
- { var name = $('#connection_profiles').find(':selected').text();
- var profile = connection_profiles[name];
- var _str = displayProfile(profile,name);
- $('#selected_profile').empty();
- $('#selected_profile').append(_str);
+ $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page)
+ {
+ $('#admin-forms').empty();
+ $('#admin-forms').append(page);
+ updatePage('deleteConnectionProfile');
+ $('#connection_profiles').on('change',function()
+ {
+ // ========> Your Code Goes Here <=========
+ });
+ let connection_profiles = _profiles[0];
+ for (let each in connection_profiles)
+ { (function (_idx, _arr)
+ { $('#connection_profiles').append(''); })(each, connection_profiles); }
+ let first = $('#connection_profiles').find(':first').text();
+ let _str = displayProfile(connection_profiles[first],first);
+ $('#selected_profile').empty();
+ $('#selected_profile').append(_str);
+ let _cancel = $('#cancel');
+ let _submit = $('#submit');
+ _cancel.on('click', function (){$('#admin-forms').empty();});
+ if (_state === 0)
+ {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});}
+ else
+ {_submit.hide();}
});
- var connection_profiles = _profiles[0];
- for (each in connection_profiles)
- { (function (_idx, _arr)
- { $('#connection_profiles').append(''); })(each, connection_profiles); }
- var first = $('#connection_profiles').find(':first').text();
- var _str = displayProfile(connection_profiles[first],first);
- $('#selected_profile').empty();
- $('#selected_profile').append(_str);
- var _cancel = $('#cancel');
- var _submit = $('#submit');
- _cancel.on('click', function (){$('#admin-forms').empty();});
- if (_state == 0)
- {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});}
- else
- {_submit.hide();}
- });
}
/**
@@ -186,15 +165,15 @@ function listProfiles(_state)
*/
function networkDeploy()
{
- var options = {};
- options.myArchive = networkFile;
- $.when($.post('/composer/admin/deploy', options)).done(function (_results)
- { var _str = '';
- _str +='
network deploy request for '+networkFile+'
';
- _str += '
Network deploy results: '+_results.deploy+'
';
- $('#admin-forms').empty();
- $('#admin-forms').append(_str);
-});
+ let options = {};
+ options.myArchive = networkFile;
+ $.when($.post('/composer/admin/deploy', options)).done(function (_results)
+ {
+ let _str = '';
+ // ========> Your Code Goes Here <=========
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
}
/**
@@ -202,15 +181,15 @@ function networkDeploy()
*/
function networkInstall()
{
- var options = {};
- options.myArchive = networkFile;
- $.when($.post('/composer/admin/install', options)).done(function (_results)
- { var _str = '';
- _str +='
network install request for '+networkFile+'
';
- _str += '
Network install results: '+_results.install+'
';
- $('#admin-forms').empty();
- $('#admin-forms').append(_str);
-});
+ let options = {};
+ options.myArchive = networkFile;
+ $.when($.post('/composer/admin/install', options)).done(function (_results)
+ {
+ let _str = '';
+ // ========> Your Code Goes Here <=========
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
}
/**
@@ -218,15 +197,14 @@ function networkInstall()
*/
function networkStart()
{
- var options = {};
- options.myArchive = networkName;
- $.when($.post('/composer/admin/start', options)).done(function (_results)
- { var _str = '';
- _str +='
network start request for '+networkName+'
';
- _str += '
Network start results: '+_results.start+'
';
- $('#admin-forms').empty();
- $('#admin-forms').append(_str);
-});
+ let options = {};
+ options.myArchive = networkName;
+ $.when($.post('/composer/admin/start', options)).done(function (_results)
+ {
+ // ========> Your Code Goes Here <=========
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
}
/**
@@ -235,23 +213,22 @@ function networkStart()
*/
function deleteConnectionProfile(_name)
{
- var options = {};
- options.profileName = _name;
- if (confirm('Are you sure you want to delete the '+_name+' profile?') == true)
- {
- $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results)
+ let options = {};
+ options.profileName = _name;
+ if (confirm('Are you sure you want to delete the '+_name+' profile?') === true)
{
- var _str = '';
- _str +='
';
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
}
-/*
-* get member in a registry
-*/
+/**
+ * get member in a registry
+ */
function listRegistry()
{
- var options = {};
- options.registry = $('#registryName').find(':selected').text();
- $.when($.post('/composer/admin/getMembers', options)).done(function (_results)
- {
- var _str = '';
- _str +='
Registry List
';
- _str += '
Network update results: '+_results.result+'
';
- _str += '
Type
Company
email
';
- for (each in _results.members)
- {(function(_idx, _arr){
- _str += '
-
+
\ No newline at end of file
diff --git a/Chapter05/HTML/adminHelp.html b/Chapter05/HTML/adminHelp.html
new file mode 100644
index 0000000..f1cf21c
--- /dev/null
+++ b/Chapter05/HTML/adminHelp.html
@@ -0,0 +1,29 @@
+
Why All The Changes?
+
HyperLedger Composer has gone through two significant changes in 4Q2017.
+ The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and
+the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did
+change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change
+is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant
+change required adding two statements to the permissions.acl file.
+
+
Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method)
+ to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh),
+ required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin
+ interface. You'll see a number of items which have a yellow strikethrough, indicating that they
+ are no longer available.
+
+
We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful.
+ Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each
+ Member. so that is deactivated.
+
+
We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need
+ the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new
+ functions in the Resource Management part of the administrative user interface, along with a feature which will
+ check to see if an idCard already exists for a specific member.
+
+
An Identity can only be issued for an existing Member, so the process is to:
Add a Member
+
Issue an Identity
Create an idCard
+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these
+ functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard
+ process, so that you don't have to remember to copy the generated secret and type it into the createCard page.
+
\ No newline at end of file
diff --git a/Chapter05/HTML/js/z2b-admin.js b/Chapter05/HTML/js/z2b-admin.js
index 569b294..67f421a 100644
--- a/Chapter05/HTML/js/z2b-admin.js
+++ b/Chapter05/HTML/js/z2b-admin.js
@@ -14,57 +14,53 @@
// z2b-admin.js
-var creds;
-var connection;
-var connectionProfileName = 'z2b-test-profile';
-var networkFile = 'zerotoblockchain-network.bna'
-var businessNetwork = 'zerotoblockchain-network';
-var msgPort = null;
-var _blctr = 0;
+'use strict';
+
+let creds;
+let connection;
+let msgPort = null;
+let _blctr = 0;
/**
* load the administration User Experience
*/
function loadAdminUX ()
{
- toLoad = 'admin.html';
- $.when($.get(toLoad)).done(function (page)
- {$('#body').empty();
- $('#body').append(page);
- updatePage("admin");
- listMemRegistries();
- });
+ let toLoad = 'admin.html';
+ $.when($.get(toLoad)).done(function (page)
+ {$('#body').empty();
+ $('#body').append(page);
+ updatePage('admin');
+ listMemRegistries();
+ });
}
/**
* connect to the provided web socket
- * @param {loc} - _target location to post messages
- * @param {port} - web socket port #
+ * @param {String} _target - location to post messages
+ * @param {Integer} _port - web socket port #
*/
function wsDisplay(_target, _port)
{
- var content = $('#'+_target);
- var wsSocket = new WebSocket('ws://localhost:'+_port);
- wsSocket.onopen = function () {wsSocket.send('connected to client');};
-
- wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));};
-
- wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);};
-
+ let content = $('#'+_target);
+ let wsSocket = new WebSocket('ws://localhost:'+_port);
+ wsSocket.onopen = function () {wsSocket.send('connected to client');};
+ wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));};
+ wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);};
}
/**
* list the available business networks
*/
function adminList()
{
- var _url = '/composer/admin/listAsAdmin';
- $.when($.get(_url)).done(function (_connection)
- { var _str = '
Current Active Business Networks
';
- for (each in _connection)
- {(function(_idx, _arr){_str += '
';
+ for (let each in _profiles) {_str += displayProfile(_profiles[each], each);}
+ _str += '
';
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+
+ });
}
/**
* gather and list all of the current network connection profiles
- * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button.
- * This allows the same routine to be used for display or delete processing
+ * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button.
+ * This allows the same routine to be used for display or delete processing
*/
function listProfiles(_state)
{
- $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page)
- {
- $('#admin-forms').empty();
- $('#admin-forms').append(page);
- $('#connection_profiles').on('change',function()
- { var name = $('#connection_profiles').find(':selected').text();
- var profile = connection_profiles[name];
- var _str = displayProfile(profile,name);
- $('#selected_profile').empty();
- $('#selected_profile').append(_str);
+ $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page)
+ {
+ $('#admin-forms').empty();
+ $('#admin-forms').append(page);
+ updatePage('deleteConnectionProfile');
+ $('#connection_profiles').on('change',function()
+ { let name = $('#connection_profiles').find(':selected').text();
+ let profile = connection_profiles[name];
+ let _str = displayProfile(profile,name);
+ $('#selected_profile').empty();
+ $('#selected_profile').append(_str);
+ });
+ let connection_profiles = _profiles[0];
+ for (let each in connection_profiles)
+ { (function (_idx, _arr)
+ { $('#connection_profiles').append(''); })(each, connection_profiles); }
+ let first = $('#connection_profiles').find(':first').text();
+ let _str = displayProfile(connection_profiles[first],first);
+ $('#selected_profile').empty();
+ $('#selected_profile').append(_str);
+ let _cancel = $('#cancel');
+ let _submit = $('#submit');
+ _cancel.on('click', function (){$('#admin-forms').empty();});
+ if (_state === 0)
+ {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});}
+ else
+ {_submit.hide();}
});
- var connection_profiles = _profiles[0];
- for (each in connection_profiles)
- { (function (_idx, _arr)
- { $('#connection_profiles').append(''); })(each, connection_profiles); }
- var first = $('#connection_profiles').find(':first').text();
- var _str = displayProfile(connection_profiles[first],first);
- $('#selected_profile').empty();
- $('#selected_profile').append(_str);
- var _cancel = $('#cancel');
- var _submit = $('#submit');
- _cancel.on('click', function (){$('#admin-forms').empty();});
- if (_state == 0)
- {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});}
- else
- {_submit.hide();}
- });
}
/**
@@ -184,15 +181,15 @@ function listProfiles(_state)
*/
function networkDeploy()
{
- var options = {};
- options.myArchive = networkFile;
- $.when($.post('/composer/admin/deploy', options)).done(function (_results)
- { var _str = '';
- _str +='
';
+ for (let each in _results.ping){(function(_idx, _arr){_str+='
'+_idx+'
'+_arr[_idx]+'
';})(each, _results.ping);}
+ _str+='
';
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
});
}
@@ -275,25 +272,23 @@ function ping()
*/
function networkUndeploy()
{
-
- var options = {};
- options.businessNetwork = businessNetwork;
- if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true)
- {
- $.when($.post('/composer/admin/undeploy', options)).done(function(_results)
+ let options = {};
+ options.businessNetwork = businessNetwork;
+ if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true)
{
- var _str = '';
- _str +='
';
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
}
-/*
-* get member in a registry
-*/
+/**
+ * get member in a registry
+ */
function listRegistry()
{
- var options = {};
- options.registry = $('#registryName').find(':selected').text();
- $.when($.post('/composer/admin/getMembers', options)).done(function (_results)
- {
- var _str = '';
- _str +='
Registry List
';
- _str += '
Network update results: '+_results.result+'
';
- _str += '
Type
Company
email
';
- for (each in _results.members)
- {(function(_idx, _arr){
- _str += '
Get Chain events requested. Sending to port: '+_res.port+'
';
- var content = $('#blockchain');
- var csSocket = new WebSocket('ws://localhost:'+_res.port);
- csSocket.onopen = function () {csSocket.send('connected to client');};
- csSocket.onmessage = function (message) {
- _blctr ++;
- if (message.data != 'connected')
- {$('#blockchain').append('block '+JSON.parse(message.data).header.number+' Hash: '+JSON.parse(message.data).header.data_hash+'');
- if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);}
- }
- };
- csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);};
- $("#admin-forms").empty();
- $("#admin-forms").append(_str);
- });
+ $.when($.get('fabric/getChainEvents')).done(function(_res)
+ { let _str = '
Get Chain events requested. Sending to port: '+_res.port+'
';
+ let content = $('#blockchain');
+ let csSocket = new WebSocket('ws://localhost:'+_res.port);
+ csSocket.onopen = function () {csSocket.send('connected to client');};
+ csSocket.onmessage = function (message) {
+ _blctr ++;
+ if (message.data !== 'connected')
+ {$(content).append('block '+JSON.parse(message.data).header.number+' Hash: '+JSON.parse(message.data).header.data_hash+'');
+ if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);}
+ }
+ };
+ csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);};
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
+}
+/**
+ * display blockchain updates
+ */
+function displayAdminUpdate()
+{
+ let toLoad = 'adminHelp.html';
+ $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);});
}
\ No newline at end of file
diff --git a/Chapter05/HTML/js/z2b-initiate.js b/Chapter05/HTML/js/z2b-initiate.js
index b566a28..8f676be 100644
--- a/Chapter05/HTML/js/z2b-initiate.js
+++ b/Chapter05/HTML/js/z2b-initiate.js
@@ -46,8 +46,8 @@ var orderStatus = {
{
// goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English
goMultiLingual("US_English", "index");
- // memberLoad loads the members already present in the network
+ // singleUX loads the members already present in the network
memberLoad();
- // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring
- getChainEvents();
+ // getChainEvents creates a web socket connection with the server and initiates blockchain event monitoring
+ getChainEvents();
}
diff --git a/Chapter05/HTML/removeMember.html b/Chapter05/HTML/removeMember.html
index 718b809..63adcf5 100644
--- a/Chapter05/HTML/removeMember.html
+++ b/Chapter05/HTML/removeMember.html
@@ -5,7 +5,7 @@
-
+
diff --git a/Chapter05/buildAndDeploy b/Chapter05/buildAndDeploy
index fad9c34..83c72bb 100755
--- a/Chapter05/buildAndDeploy
+++ b/Chapter05/buildAndDeploy
@@ -51,6 +51,4 @@ showStep "creating archive"
showStep "starting network"
./startup.sh
showStep "deploying network"
-./deployNetwork.sh -n $NETWORK_NAME
-showStep "copying credentials"
-cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store
\ No newline at end of file
+./deployNetwork.sh -n $NETWORK_NAME
\ No newline at end of file
diff --git a/Chapter05/controller/env.json b/Chapter05/controller/env.json
index 0afea4b..dd1c45d 100644
--- a/Chapter05/controller/env.json
+++ b/Chapter05/controller/env.json
@@ -7,7 +7,9 @@
"adminPW": "adminpw",
"PeerAdmin": "PeerAdmin",
"PeerPW": "randomString",
- "NS": "org.acme.Z2BTestNetwork"
+ "NS": "org.acme.Z2BTestNetwork",
+ "adminCard": "admin@zerotoblockchain-network",
+ "PeerCard": "PeerAdmin@hlfv1"
},
"fabric":
{
@@ -21,5 +23,24 @@
"peerEventURL": "grpc://localhost:7053",
"ordererURL" : "grpc://localhost:7050",
"caURL": "http://localhost:7054"
+ },
+ "metaData":
+ { "version": 1,
+ "userName": "temp",
+ "roles": [ ],
+ "businessNetwork":"",
+ "enrollmentSecret": "temp"
+ },
+ "connectionProfile":
+ {
+ "name": "hlfv1",
+ "type": "hlfv1",
+ "orderers": [ { "url": "grpc://localhost:7050" } ],
+ "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" },
+ "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ],
+ "keyValStore": "/.composer-credentials",
+ "channel": "composerchannel",
+ "mspID": "Org1MSP",
+ "timeout": 300
}
}
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/composer/autoLoad.js b/Chapter05/controller/restapi/features/composer/autoLoad.js
index 1f5214f..ce3d81b 100644
--- a/Chapter05/controller/restapi/features/composer/autoLoad.js
+++ b/Chapter05/controller/restapi/features/composer/autoLoad.js
@@ -14,62 +14,57 @@
/**
* This file is used to automatically populate the network with Order assets and members
- * The opening section loads node modules required for this set of nodejs services
- * to work. Most of these are from the hyperledger composer SDK. This module also
+ * The opening section loads node modules required for this set of nodejs services
+ * to work. Most of these are from the hyperledger composer SDK. This module also
* uses services created specifically for this tutorial, in the Z2B_Services.js
- * and Z2B_Utilities.js modules.
+ * and Z2B_Utilities.js modules.
*/
'use strict';
-const BrowserFS = require('browserfs/dist/node/index');
-const network = 'zerotoblockchain-network';
-var fs = require('fs');
-var path = require('path');
+const fs = require('fs');
+const path = require('path');
+const _home = require('os').homedir();
+const hlc_idCard = require('composer-common').IdCard;
-const composerAdmin = require('composer-admin');
const AdminConnection = require('composer-admin').AdminConnection;
-const composerClient = require('composer-client');
-const composerCommon = require('composer-common');
-const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
const financeCoID = 'easymoney@easymoneyinc.com';
const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
const config = require('../../../env.json');
-const NS = 'org.acme.Z2BTestNetwork';
/**
- * itemTable and memberTable are used by the server to reduce load time requests
+ * itemTable and memberTable are used by the server to reduce load time requests
* for member secrets and item information
*/
let itemTable = new Array();
let memberTable = new Array();
-let orderStatus = svc.orderStatus;
+let socketAddr;
+
+
-let connection; let socketAddr;
/**
- * getPort is used to return the port number for socket interactions so that
- * the browser can receive asynchronous notifications of work in process.
- * This helps the user understand the current status of the auto load process.
+ * getPort is used to return the port number for socket interactions so that
+ * the browser can receive asynchronous notifications of work in process.
+ * This helps the user understand the current status of the auto load process.
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- *
+ *
* @function
*/
exports.getPort = function(req, res, next) {
let _conn = svc.createMessageSocket();
res.send({'port': _conn.socket});
-}
+};
/**
- * autoLoad reads the memberList.json file from the Startup folder and adds members,
+ * autoLoad reads the memberList.json file from the Startup folder and adds members,
* executes the identity process, and then loads orders
- *
+ *
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
@@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) {
let businessNetworkConnection;
let factory; let participant;
svc.createMessageSocket();
- connection = svc.m_connection;
socketAddr = svc.m_socketAddr;
let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {
+ // a businessNetworkConnection is required to add members
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- // a businessNetworkConnection is required to add members
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- // a factory is required to build the member object
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- //iterate through the list of members in the memberList.json file and
- // first add the member to the network, then create an identity for
- // them. This generates the memberList.txt file later used for
- // retrieving member secrets.
- for (let each in startupFile.members)
- {(function(_idx, _arr)
- {
- // the participant registry is where member information is first stored
- // there are individual registries for each type of participant, or member.
- // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type)
- .then(function(participantRegistry){
- return participantRegistry.get(_arr[_idx].id)
- .then((_res) => {
- console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- })
- .catch((error) => {
- participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id);
- participant.companyName = _arr[_idx].companyName;
- participantRegistry.add(participant)
- .then(() => {
- console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added");
- svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added");
- })
- .then(() => {
- // an identity is required before a member can take action in the network.
- return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw)
- .then((result) => {
- let _mem = _arr[_idx];
- _mem.secret = result.userSecret;
- _mem.userID = result.userID;
- memberTable.push(_mem);
- svc.saveMemberTable(memberTable);
- })
- .catch((error) => {
- console.error('create id for '+_arr[_idx].id+'failed.',error.message);
- });
- })
- .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);});
- });
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error.message)});
- })(each, startupFile.members)
- }
- // iterate through the order objects in the memberList.json file.
- for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)}
- svc.saveItemTable(itemTable);
- for (let each in startupFile.assets)
- {(function(_idx, _arr)
- {
- // each type of asset, like each member, gets it's own registry. Our application
- // has only one type of asset: "Order"
- return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type)
- .then((assetRegistry) => {
- return assetRegistry.get(_arr[_idx].id)
- .then((_res) => {
- console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- })
- .catch((error) => {
- // first, an Order Object is created
- let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id);
- order = svc.createOrderTemplate(order);
- let _tmp = svc.addItems(_arr[_idx], itemTable);
- order.items = _tmp.items;
- order.amount = _tmp.amount;
- order.orderNumber = _arr[_idx].id;
- // then the buy transaction is created
- const createNew = factory.newTransaction(NS, 'CreateOrder');
- order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer);
- order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller);
- order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
- order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
- order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
- createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer);
- createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller);
- createNew.amount = order.amount;
- // then the order is added to the asset registry.
- return assetRegistry.add(order)
- .then(() => {
- // then a createOrder transaction is processed which uses the chaincode
- // establish the order with it's initial transaction state.
- svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection);
- })
+ // a factory is required to build the member object
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ //iterate through the list of members in the memberList.json file and
+ // first add the member to the network, then create an identity for
+ // them. This generates the memberList.txt file later used for
+ // retrieving member secrets.
+ for (let each in startupFile.members)
+ {(function(_idx, _arr)
+ {
+ // the participant registry is where member information is first stored
+ // there are individual registries for each type of participant, or member.
+ // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo
+ return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type)
+ .then(function(participantRegistry){
+ return participantRegistry.get(_arr[_idx].id)
+ .then((_res) => {
+ console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ })
+ .catch((error) => {
+ participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id);
+ participant.companyName = _arr[_idx].companyName;
+ participantRegistry.add(participant)
+ .then(() => {
+ console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added');
+ svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added');
+ })
+ .then(() => {
+ // an identity is required before a member can take action in the network.
+ // V0.14
+ // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw)
+ // V0.15
+ console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id);
+ return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id)
+ .then((result) => {
+ console.log('_arr[_idx].id: '+_arr[_idx].id);
+ console.log('result.userID: '+result.userID);
+ let _mem = _arr[_idx];
+ _mem.secret = result.userSecret;
+ _mem.userID = result.userID;
+ memberTable.push(_mem);
+ // svc.saveMemberTable(memberTable);
+ let _meta = {};
+ for (each in config.composer.metaData)
+ {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); }
+ _meta.businessNetwork = config.composer.network;
+ _meta.userName = result.userID;
+ _meta.enrollmentSecret = result.userSecret;
+ config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore;
+ let tempCard = new hlc_idCard(_meta, config.connectionProfile);
+ return adminConnection.importCard(result.userID, tempCard)
+ .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} })
.catch((error) => {
- // in the development environment, because of how timing is set up, it is normal to
- // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a
- // logical transaction error.
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id);
- svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection);
- }
- else {console.log('error with assetRegistry.add', error.message)}
+ console.error('adminConnection.importCard failed. ',error.message);
});
- });
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error.message)});
- })(each, startupFile.assets)
- }
+ })
+ .catch((error) => {
+ console.error('create id for '+_arr[_idx].id+'failed. ',error.message);
+ });
+ })
+ .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);});
+ });
+ })
+ .catch((error) => {console.log('error with getParticipantRegistry', error.message);});
+ })(each, startupFile.members);
+ }
+ // iterate through the order objects in the memberList.json file.
+ for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);}
+ svc.saveItemTable(itemTable);
+ for (let each in startupFile.assets)
+ {(function(_idx, _arr)
+ {
+ // each type of asset, like each member, gets it's own registry. Our application
+ // has only one type of asset: 'Order'
+ return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type)
+ .then((assetRegistry) => {
+ return assetRegistry.get(_arr[_idx].id)
+ .then((_res) => {
+ console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ })
+ .catch((error) => {
+ // first, an Order Object is created
+ let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id);
+ order = svc.createOrderTemplate(order);
+ let _tmp = svc.addItems(_arr[_idx], itemTable);
+ order.items = _tmp.items;
+ order.amount = _tmp.amount;
+ order.orderNumber = _arr[_idx].id;
+ // then the buy transaction is created
+ const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder');
+ order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer);
+ order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller);
+ order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy');
+ order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy');
+ order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID);
+ createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID);
+ createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier);
+ createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer);
+ createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller);
+ createNew.amount = order.amount;
+ // then the order is added to the asset registry.
+ return assetRegistry.add(order)
+ .then(() => {
+ // then a createOrder transaction is processed which uses the chaincode
+ // establish the order with it's initial transaction state.
+ svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection);
+ })
+ .catch((error) => {
+ // in the development environment, because of how timing is set up, it is normal to
+ // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a
+ // logical transaction error.
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id);
+ svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection);
+ }
+ else {console.log('error with assetRegistry.add', error.message);}
+ });
+ });
})
- .catch((error) => {console.log('error with business network Connect', error.message)});
+ .catch((error) => {console.log('error with getParticipantRegistry', error.message);});
+ })(each, startupFile.assets);
+ }
})
- .catch((error) => {console.log('error with adminConnect', error.message)});
- res.send({'port': socketAddr});
-}
+ .catch((error) => {console.log('error with business network Connect', error.message);});
+ })
+ .catch((error) => {console.log('error with adminConnect', error.message);});
+ res.send({'port': socketAddr});
+};
/**
* get member secret from member table. In normal production, the use would be responsible
* for knowing their member secret. Because this is a demo, we're managing that informaiton
* on the server and this routine gets that information for us so that we can successfully
- * execute transactions.
+ * execute transactions.
* @param {express.req} req - the inbound request object from the client
* req.body.id - the id of the member to find
* @param {express.res} res - the outbound response object for communicating back to client
@@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next)
{
let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
let _table = JSON.parse(fs.readFileSync(newFile));
- let bFound = false;
+ let bFound = false;
for (let each in _table.members)
- { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}}
- if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});}
-}
\ No newline at end of file
+ { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}}
+ if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});}
+};
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/composer/hlcAdmin.js b/Chapter05/controller/restapi/features/composer/hlcAdmin.js
index 7190361..03049e8 100644
--- a/Chapter05/controller/restapi/features/composer/hlcAdmin.js
+++ b/Chapter05/controller/restapi/features/composer/hlcAdmin.js
@@ -16,19 +16,16 @@
'use strict';
const fs = require('fs');
const path = require('path');
+const _home = require('os').homedir();
+const hlc_idCard = require('composer-common').IdCard;
const composerAdmin = require('composer-admin');
const AdminConnection = require('composer-admin').AdminConnection;
-const composerClient = require('composer-client');
-const composerCommon = require('composer-common');
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const Serializer = require('composer-common').Serializer;
const config = require('../../../env.json');
const NS = 'org.acme.Z2BTestNetwork';
-const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
-var orderStatus = svc.orderStatus;
-
+// const svc = require('./Z2B_Services');
+// const mod = 'hlcAdmin.js';
/**
* display the admin and network info
@@ -56,7 +53,10 @@ exports.adminNew = function() {
*/
exports.adminConnect = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(function(){
console.log('create connection successful ');
res.send({connection: 'succeeded'});
@@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) {
* @function
*/
exports.createProfile = function(req, res, next) {
- let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL',
- 'keyValStore', 'channel', 'mspID', 'timeout'];
-
let adminOptions = {
type: req.body.type,
keyValStore: req.body.keyValStore,
@@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) {
peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}]
};
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.createProfile(req.body.profileName, adminOptions)
- .then(function(result){
- console.log('create profile successful: ');
- res.send({profile: 'succeeded'});
- })
- .catch(function(error){
- console.log('create profile failed: ',error);
- res.send({profile: error});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.createProfile(req.body.profileName, adminOptions)
+ .then(function(result){
+ console.log('create profile successful: ');
+ res.send({profile: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('create profile failed: ',error);
+ res.send({profile: error});
+ });
+ });
};
/**
* Deletes the specified connection profile from the profile store being used by this AdminConnection.
@@ -115,51 +115,60 @@ exports.createProfile = function(req, res, next) {
*/
exports.deleteProfile = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.deleteProfile(req.body.profileName)
- .then(function(result){
- console.log('delete profile successful: ',result);
- res.send({profile: 'succeeded'});
- })
- .catch(function(error){
- console.log('delete profile failed: ',error);
- res.send({profile: error});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.deleteProfile(req.body.profileName)
+ .then(function(result){
+ console.log('delete profile successful: ',result);
+ res.send({profile: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('delete profile failed: ',error);
+ res.send({profile: error});
+ });
+ });
};
+
/**
* Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
+ * This method will be superceded in v0.17, possibly as early as v0.16, with adminConnection.start(), which will create the necessary
+ * business network admin id as part of the start process, in line with how the cli now operates
* @param {express.req} req - the inbound request object from the client
* req.body.myArchive: _string - string name of object
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.deploy = function(req, res, next) {
-
- let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
-
- let adminConnection = new composerAdmin.AdminConnection();
-
- return BusinessNetworkDefinition.fromArchive(archiveFile)
- .then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.deploy(archive)
- .then(function(){
- console.log('business network '+req.body.myArchive+' deployed successful: ');
- res.send({deploy: req.body.myArchive+' deploy succeeded'});
- })
- .catch(function(error){
- console.log('business network '+req.body.myArchive+' deploy failed: ',error);
- res.send({deploy: error});
- });
+
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
+
+ let adminConnection = new composerAdmin.AdminConnection();
+
+ return BusinessNetworkDefinition.fromArchive(archiveFile)
+ .then(function(archive) {
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.deploy(archive)
+ .then(function(){
+ console.log('business network '+req.body.myArchive+' deployed successful: ');
+ res.send({deploy: req.body.myArchive+' deploy succeeded'});
+ })
+ .catch(function(error){
+ console.log('business network '+req.body.myArchive+' deploy failed: ',error);
+ res.send({deploy: error});
});
- });
- };
+ });
+ });
+};
/**
* Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
* @param {express.req} req - the inbound request object from the client
@@ -167,35 +176,31 @@ exports.deploy = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.networkInstall = function(req, res, next) {
-
+
let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((businessNetworkDefinition) => {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(() => {
- return adminConnection.install(businessNetworkDefinition.getName())
- .then(() => {
- console.log('business network '+req.body.myArchive+' installed successful: ');
- res.send({install: req.body.myArchive+' install succeeded'});
- })
- .catch((error) => {
- console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message);
- res.send({install: error.message});
- });
- })
- .catch((error) => {console.log('error with adminConnection.connect', error.message)
- res.send({install: error.message});
- });
- })
- .catch((error) => {console.log('error with fromArchive', error.message)});
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {console.log('error with adminConnection.connect', error.message);
+ res.send({install: error.message});
+ });
+ })
+ .catch((error) => {console.log('error with fromArchive', error.message);
res.send({install: error.message});
- }
+ });
+};
/**
* Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
@@ -204,29 +209,25 @@ exports.networkInstall = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.networkStart = function(req, res, next) {
-
+
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(function(){
- adminConnection.start(archive)
- .then(function(){
- console.log('business network '+req.body.myArchive+' installed successful: ');
- res.send({install: req.body.myArchive+' install succeeded'});
- })
- .catch(function(error){
- console.log('business network '+req.body.myArchive+' install failed: ',error);
- res.send({install: error});
- });
- });
- });
- };
+ // ========> Your Code Goes Here <=========
+ });
+ });
+};
/**
* disconnects this connection
@@ -238,18 +239,13 @@ exports.networkStart = function(req, res, next) {
*/
exports.disconnect = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.disconnect()
- .then(function(result){
- console.log('network disconnect successful: ');
- res.send({disconnect: 'succeeded'});
- })
- .catch(function(error){
- console.log('network disconnect failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ // ========> Your Code Goes Here <=========
+ });
};
/**
* Retrieve all connection profiles from the profile store being used by this AdminConnection.
@@ -261,17 +257,13 @@ exports.disconnect = function(req, res, next) {
*/
exports.getAllProfiles = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.getAllProfiles()
- .then((profiles) => {
- res.send(profiles);
- })
- .catch(function(error){
- console.log('network disconnect failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ // ========> Your Code Goes Here <=========
+ });
};
/**
* Retrieve the specified connection profile from the profile store being used by this AdminConnection.
@@ -284,18 +276,13 @@ exports.getAllProfiles = function(req, res, next) {
*/
exports.getProfile = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.getProfile(req.body.connectionProfile)
- .then((profile) => {
- console.log('get profile Succeeded: ',profile);
- res.send(profile);
- })
- .catch(function(error){
- console.log('get profile failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ // ========> Your Code Goes Here <=========
+ });
};
/**
* List all of the deployed business networks. The connection must be connected for this method to succeed.
@@ -307,50 +294,15 @@ exports.getProfile = function(req, res, next) {
*/
exports.listAsAdmin = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- util.displayObjectValuesRecursive(adminConnection);
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.list()
- .then((businessNetworks) => {
- // Connection has been tested
- businessNetworks.forEach((businessNetwork) => {
- console.log('Deployed business network', businessNetwork);
- });
- res.send(businessNetworks);
- })
- .catch(function(_error){
- let error = _error;
- console.log('get business networks failed: ',error);
- res.send(error);
- });
- });
-};
-/**
- * List all of the deployed business networks. The connection must be connected for this method to succeed.
- * @param {express.req} req - the inbound request object from the client
- * @param {express.res} res - the outbound response object for communicating back to client
- * @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
- * @function
- */
-exports.listAsPeerAdmin = function(req, res, next) {
- let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.list()
- .then((businessNetworks) => {
- // Connection has been tested
- businessNetworks.forEach((businessNetwork) => {
- console.log('Deployed business network', businessNetwork);
- });
- res.send(businessNetworks);
- })
- .catch(function(_error){
- let error = _error;
- console.log('get business networks failed: ',error);
- res.send(error);
- });
- });
+ // updated to use PeerAdmin, PeerPW to work with V0.14
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ console.log('config.composer.PeerCard: '+config.composer.PeerCard);
+ adminConnection.connect(config.composer.PeerCard)
+ .then(function(){
+ // ========> Your Code Goes Here <=========
+ });
};
/**
* Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module.
@@ -362,19 +314,13 @@ exports.listAsPeerAdmin = function(req, res, next) {
*/
exports.ping = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork)
- .then(function(){
- adminConnection.ping()
- .then(function(result){
- console.log('network ping successful: ',result);
- res.send({ping: result});
- })
- .catch(function(error){
- let _error = error;
- console.log('network ping failed: '+_error);
- res.send({ping: _error.toString()});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ // ========> Your Code Goes Here <=========
+ });
};
/**
* Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions.
@@ -387,19 +333,13 @@ exports.ping = function(req, res, next) {
*/
exports.undeploy = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork)
- .then(function(){
- adminConnection.undeploy(req.body.businessNetwork)
- .then(function(result){
- console.log(req.body.businessNetwork+' network undeploy successful ');
- res.send({undeploy: req.body.businessNetwork+' network undeploy successful '});
- })
- .catch(function(error){
- let _error = error;
- console.log(req.body.businessNetwork+' network undeploy failed: '+_error);
- res.send({undeploy: _error.toString()});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ // ========> Your Code Goes Here <=========
+ });
};
/**
* Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed.
@@ -407,7 +347,7 @@ exports.undeploy = function(req, res, next) {
* req.body.myArchive: _string - name of archive to deploy
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.update = function(req, res, next) {
@@ -418,21 +358,14 @@ exports.update = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
- .then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName)
- .then(function(){
- adminConnection.update(archive)
- .then(function(){
- console.log(netName+' network update successful: ');
- res.send({update: req.body.myArchive+' network update successful '});
- })
- .catch(function(error){
- let _error = error;
- console.log(req.body.myArchive+' network update failed: '+_error);
- res.send({update: _error.toString()});
- });
- });
- });
+ .then(function(archive) {
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ // ========> Your Code Goes Here <=========
+ });
};
/**
@@ -440,7 +373,7 @@ exports.update = function(req, res, next) {
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns array of registries
+ * @returns {Object} array of registries
* @function
*/
exports.getRegistries = function(req, res, next)
@@ -449,29 +382,16 @@ exports.getRegistries = function(req, res, next)
// connect to the network
let allRegistries = new Array();
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getAllParticipantRegistries()
- .then(function(participantRegistries){
- for (let each in participantRegistries)
- { (function (_idx, _arr)
- { let r_type = _arr[_idx].name.split('.');
- allRegistries.push([r_type[r_type.length-1]]);
- })(each, participantRegistries)
- }
- res.send({'result': 'success', 'registries': allRegistries});
- })
- .catch((error) => {console.log('error with getAllRegistries', error)});
- })
- .catch((error) => {console.log('error with business network Connect', error)});
- })
- .catch((error) => {console.log('error with admin network Connect', error)});
-}
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {console.log('error with business network Connect', error);});
+};
/**
* retrieve array of members from specified registry type
@@ -479,66 +399,102 @@ exports.getRegistries = function(req, res, next)
* req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of members
+ * @returns {Object} an array of members
* @function
*/
exports.getMembers = function(req, res, next) {
// connect to the network
+ // let method = 'getMembers';
let allMembers = new Array();
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
- .then(function(registry){
- return registry.getAll()
- .then ((members) => {
- for (let each in members)
- { (function (_idx, _arr)
- { let _jsn = {};
- _jsn.type = req.body.registry;
- _jsn.companyName = _arr[_idx].companyName;
- switch (req.body.registry)
- {
- case 'Buyer':
- _jsn.id = _arr[_idx].buyerID;
- break;
- case 'Seller':
- _jsn.id = _arr[_idx].sellerID;
- break;
- case 'Provider':
- _jsn.id = _arr[_idx].providerID;
- break;
- case 'Shipper':
- _jsn.id = _arr[_idx].shipperID;
- break;
- case 'FinanceCo':
- _jsn.id = _arr[_idx].financeCoID;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allMembers.push(_jsn); })(each, members)
- }
- res.send({'result': 'success', 'members': allMembers});
- })
- .catch((error) => {console.log('error with getAllMembers', error);
- res.send({'result': 'failed '+error.message, 'members': []});});
- })
- .catch((error) => {console.log('error with getRegistry', error);
- res.send({'result': 'failed '+error.message, 'members': []});});
- })
- .catch((error) => {console.log('error with business network Connect', error.message);
- res.send({'result': 'failed '+error.message, 'members': []});});
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
+ .then(function(registry){
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {console.log('error with getRegistry', error);
+ res.send({'result': 'failed '+error.message, 'members': []});});
})
- .catch((error) => {console.log('error with admin network Connect', error);
- res.send({'result': 'failed '+error.message, 'members': []});});
-
-}
+ .catch((error) => {console.log('error with business network Connect', error.message);
+ res.send({'result': 'failed '+error.message, 'members': []});});
+};
+
+/**
+ * Checks to see if the provided id already has a card issued for it
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * returns {object} - a JSON object
+ * @function
+ */
+exports.checkCard = function(req, res, next) {
+ let adminConnection = new AdminConnection();
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {
+ res.send({'result': 'admin Connect failed', 'message': error.message});
+ });
+};
+
+/**
+ * Creates a card for an existing member
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * req.body.pw - the pw of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * returns {object} - a JSON object
+ * @function
+ */
+exports.createCard = function(req, res, next) {
+ let adminConnection = new AdminConnection();
+ let _meta = {};
+ for (let each in config.composer.metaData)
+ {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); }
+ _meta.businessNetwork = config.composer.network;
+ _meta.userName = req.body.id;
+ _meta.enrollmentSecret = req.body.secret;
+ config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore;
+ let tempCard = new hlc_idCard(_meta, config.connectionProfile);
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {
+ console.error('adminConnection.connect failed. ',error.message);
+ res.send({'result': 'failed', 'error': error.message});
+ });
+};
+
+/**
+ * creates an identity for a member already created in a member registry
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * req.body.type - the member type of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * @returns {object} - a JSON object
+ * @function
+ */
+exports.issueIdentity = function(req, res, next) {
+ let businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id);
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {
+ res.send({'result': 'business network Connect failed', 'message': error.message});
+ });
+};
/**
* gets the assets from the order registry
@@ -547,87 +503,83 @@ exports.getMembers = function(req, res, next) {
* req.body.id - the id of the individual making the request
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} - an array of assets
* @function
*/
exports.getAssets = function(req, res, next) {
- // connect to the network
- let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json')));
- let allOrders = new Array();
- let businessNetworkConnection;
- let factory;
- let serializer;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connect to the network
+ let allOrders = new Array();
+ let businessNetworkConnection;
+ let serializer;
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return BusinessNetworkDefinition.fromArchive(archiveFile)
+ .then((bnd) => {
+ serializer = bnd.getSerializer();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
-// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON);
-// retry this with fromArchive when time allows
-// serializer = bnd.getSerializer();
- return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry)
- .then(function(registry){
- return registry.getAll()
- .then ((members) => {
- console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace);
- for (let each in members)
- { (function (_idx, _arr)
- {
- switch(req.body.type)
+ return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry)
+ .then(function(registry){
+ return registry.getAll()
+ .then ((members) => {
+ console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace);
+ for (let each in members)
+ { (function (_idx, _arr)
+ {
+ switch(req.body.type)
+ {
+ case 'Buyer':
+ if (req.body.id === _arr[_idx].buyer.$identifier)
+ {
+ let _jsn = serializer.toJSON(_arr[_idx]);
+ _jsn.type = req.body.registry;
+ switch (req.body.registry)
{
- case 'Buyer':
- if (req.body.id == _arr[_idx].buyer.$identifier)
- {
- let _jsn = svc.getOrderData(_arr[_idx]);
- _jsn.type = req.body.registry;
- switch (req.body.registry)
- {
- case 'Order':
- _jsn.id = _arr[_idx].orderNumber;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allOrders.push(_jsn);
- }
- break;
- case 'admin':
- let _jsn = svc.getOrderData(_arr[_idx]);
- _jsn.type = req.body.registry;
- switch (req.body.registry)
- {
- case 'Order':
- _jsn.id = _arr[_idx].orderNumber;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allOrders.push(_jsn);
- break;
- default:
+ case 'Order':
+ _jsn.id = _arr[_idx].orderNumber;
break;
+ default:
+ _jsn.id = _arr[_idx].id;
}
- })(each, members)
+ allOrders.push(_jsn);
+ }
+ break;
+ case 'admin':
+ let _jsn = serializer.toJSON(_arr[_idx]);
+ _jsn.type = req.body.registry;
+ switch (req.body.registry)
+ {
+ case 'Order':
+ _jsn.id = _arr[_idx].orderNumber;
+ break;
+ default:
+ _jsn.id = _arr[_idx].id;
+ }
+ allOrders.push(_jsn);
+ break;
+ default:
+ break;
}
- res.send({'result': 'success', 'orders': allOrders});
- })
- .catch((error) => {console.log('error with getAllOrders', error)
- res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message});
- });
- })
- .catch((error) => {console.log('error with getRegistry', error)
- res.send({'result': 'failed', 'error': 'getRegistry: '+error.message});
- });
+ })(each, members);
+ }
+ res.send({'result': 'success', 'orders': allOrders});
})
- .catch((error) => {console.log('error with business network Connect', error)
- res.send({'result': 'failed', 'error': 'business network Connect: '+error.message});
+ .catch((error) => {console.log('error with getAllOrders', error);
+ res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('error with getRegistry', error);
+ res.send({'result': 'failed', 'error': 'getRegistry: '+error.message});
});
- })
- .catch((error) => {console.log('error with admin network Connect', error)
- res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message});
- });
-}
+ })
+ .catch((error) => {console.log('error with business network Connect', error);
+ res.send({'result': 'failed', 'error': 'business network Connect: '+error.message});
+ });
+ });
+};
/**
* Adds a new member to the specified registry
@@ -637,38 +589,27 @@ exports.getAssets = function(req, res, next) {
* req.body.id: _string - id of member to add (email address)
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns JSON object with success or error results
+ * @returns {JSON} object with success or error results
* @function
*/
exports.addMember = function(req, res, next) {
let businessNetworkConnection;
let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type)
- .then(function(participantRegistry){
- return participantRegistry.get(req.body.id)
- .then((_res) => { res.send('member already exists. add cancelled');})
- .catch((_res) => {
- console.log(req.body.id+' not in '+req.body.type+' registry. ');
- let participant = factory.newResource(NS, req.body.type,req.body.id);
- participant.companyName = req.body.companyName;
- participantRegistry.add(participant)
- .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");})
- .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);});
- });
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);});
- })
- .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);});
- })
- .catch((error) => {console.log('error with adminConnection', error); res.send(error);});
-}
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type)
+ .then(function(participantRegistry){
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);});
+ })
+ .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);});
+};
/**
* Removes a member from a registry.
@@ -677,38 +618,29 @@ exports.addMember = function(req, res, next) {
* req.body.id: _string - id of member to delete
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns JSON object with success or error results
+ * @returns {JSON} object with success or error results
* @function
*/
exports.removeMember = function(req, res, next) {
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
- .then(function(participantRegistry){
- return participantRegistry.get(req.body.id)
- .then((_res) => {
- return participantRegistry.remove(req.body.id)
- .then((_res) => {
- res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.');
- })
- .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
- res.send('member already exists. add cancelled');
- })
- .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);});
- })
- .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);});
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
+ .then(function(participantRegistry){
+ return participantRegistry.get(req.body.id)
+ .then((_res) => {
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
})
- .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);});
-}
+ .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);});
+ })
+ .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);});
+};
/**
* get Historian Records
@@ -716,43 +648,40 @@ exports.removeMember = function(req, res, next) {
* req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of members
+ * @returns {Array} an array of members
* @function
*/
exports.getHistory = function(req, res, next) {
let allHistory = new Array();
let businessNetworkConnection;
- let factory;
let ser;
let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
- let adminConnection = new AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((bnd) => {
ser = bnd.getSerializer();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord')
- .then(function(registry){
- return registry.getAll()
- .then ((history) => {
- for (let each in history)
- { (function (_idx, _arr)
- { let _jsn = _arr[_idx];
- allHistory.push(ser.toJSON(_jsn));
- })(each, history)
- }
- res.send({'result': 'success', 'history': allHistory});
- })
- .catch((error) => {console.log('error with getAll History', error)});
- })
- .catch((error) => {console.log('error with getRegistry', error)});
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord')
+ .then(function(registry){
+ return registry.getAll()
+ .then ((history) => {
+ for (let each in history)
+ { (function (_idx, _arr)
+ { let _jsn = _arr[_idx];
+ allHistory.push(ser.toJSON(_jsn));
+ })(each, history);
+ }
+ res.send({'result': 'success', 'history': allHistory});
})
- .catch((error) => {console.log('error with business network Connect', error)});
- })
- .catch((error) => {console.log('error with admin network Connect', error)});
+ .catch((error) => {console.log('error with getAll History', error);});
+ })
+ .catch((error) => {console.log('error with getRegistry', error);});
+ })
+ .catch((error) => {console.log('error with business network Connect', error);});
})
- .catch((error) => {console.log('error with business network definition', error)});
-}
+ .catch((error) => {console.log('error with admin network Connect', error);});
+};
diff --git a/Chapter05/controller/restapi/features/composer/hlcClient.js b/Chapter05/controller/restapi/features/composer/hlcClient.js
index 03d9523..bc5bfb6 100644
--- a/Chapter05/controller/restapi/features/composer/hlcClient.js
+++ b/Chapter05/controller/restapi/features/composer/hlcClient.js
@@ -14,14 +14,14 @@
'use strict';
-var fs = require('fs');
-var path = require('path');
+let fs = require('fs');
+let path = require('path');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const config = require('../../../env.json');
+const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
+// const config = require('../../../env.json');
const NS = 'org.acme.Z2BTestNetwork';
let itemTable = null;
const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
const financeCoID = 'easymoney@easymoneyinc.com';
/**
@@ -29,70 +29,83 @@ const financeCoID = 'easymoney@easymoneyinc.com';
* @param {express.req} req - the inbound request object from the client
* req.body.id - the id of the buyer making the request
* req.body.userID - the user id of the buyer in the identity table making this request
- * req.body.secret - the pw of this user.
+ * req.body.secret - the pw of this user.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.getMyOrders = function (req, res, next) {
// connect to the network
- let newFile = path.join(path.dirname(require.main.filename),'network','package.json');
- let packageJSON = JSON.parse(fs.readFileSync(newFile));
+ let method = 'getMyOrders';
+ console.log(method+' req.body.userID is: '+req.body.userID );
let allOrders = new Array();
let businessNetworkConnection;
- let factory;
- let serializer;
- if (svc.m_connection == null) {svc.createMessageSocket();}
+ if (svc.m_connection === null) {svc.createMessageSocket();}
+ let ser;
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
businessNetworkConnection = new BusinessNetworkConnection();
- console.log('getMyOrders for user: '+req.body.userID+' with secret: '+req.body.secret);
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
- .then(() => {
+ return BusinessNetworkDefinition.fromArchive(archiveFile)
+ .then((bnd) => {
+ ser = bnd.getSerializer();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
+ //
+ // v0.15
+ console.log(method+' req.body.userID is: '+req.body.userID );
+ return businessNetworkConnection.connect(req.body.userID)
+ .then(() => {
return businessNetworkConnection.query('selectOrders')
.then((orders) => {
- console.log('there are '+orders.length+' orders for '+req.body.userID);
- let jsn;
- let allOrders = new Array();
- for (let each in orders)
- { (function (_idx, _arr)
- {
- let _jsn = svc.getOrderData(_arr[_idx]);
- _jsn.id = _arr[_idx].orderNumber;
- allOrders.push(_jsn);
- })(each, orders)
- }
- res.send({'result': 'success', 'orders': allOrders});
- })
- .catch((error) => {console.log('selectOrders failed ', error); })
- res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});;
- })
- .catch((error) => {console.log('businessNetwork connect failed ', error); })
- res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});;
- }
+ allOrders = new Array();
+ for (let each in orders)
+ { (function (_idx, _arr)
+ {
+ let _jsn = ser.toJSON(_arr[_idx]);
+ _jsn.id = _arr[_idx].orderNumber;
+ allOrders.push(_jsn);
+ })(each, orders);
+ }
+ res.send({'result': 'success', 'orders': allOrders});
+ })
+ .catch((error) => {console.log('selectOrders failed ', error);
+ res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('businessNetwork connect failed ', error);
+ res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('create bnd from archive failed ', error);
+ res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message});
+ });
+};
+
/**
* return a json object built from the item table created by the autoload function
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * return {Array} an array of assets
* @function
*/
exports.getItemTable = function (req, res, next)
{
- if (itemTable == null)
+ if (itemTable === null)
{
- let options = { flag : 'w' };
let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt');
itemTable = JSON.parse(fs.readFileSync(newFile));
}
res.send(itemTable);
-}
+};
+
/**
* orderAction - act on an order for a buyer
* @param {express.req} req - the inbound request object from the client
* req.body.action - string with buyer requested action
- * buyer available actions are:
+ * buyer available actions are:
* Pay - approve payment for an order
* Dispute - dispute an existing order. requires a reason
* Purchase - submit created order to seller for execution
@@ -102,156 +115,156 @@ exports.getItemTable = function (req, res, next)
* req.body.reason - reason for dispute, required for dispute processing to proceed
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.orderAction = function (req, res, next) {
- if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) )
- {let reason = req.body.reason;}
+ let method = 'orderAction';
+ console.log(method+' req.body.participant is: '+req.body.participant );
+ if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) )
+ {/*let reason = req.body.reason;*/}
else {
- if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) ))
- res.send({'result': 'failed', 'error': 'no reason provided for dispute'});
+ if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) ))
+ {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});}
}
- if (svc.m_connection == null) {svc.createMessageSocket();}
- console.log('req.body.orderNo is: ', req.body.orderNo);
+ if (svc.m_connection === null) {svc.createMessageSocket();}
let businessNetworkConnection;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let updateOrder;
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.get(req.body.orderNo)
- .then((order) => {
- let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- order.status = req.body.action;
- switch (req.body.action)
- {
- case 'Pay':
- console.log('Pay entered');
- updateOrder = factory.newTransaction(NS, 'Pay');
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Dispute':
- console.log('Dispute entered');
- updateOrder = factory.newTransaction(NS, 'Dispute');
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.dispute = req.body.reason;
- break;
- case 'Purchase':
- console.log('Purchase entered');
- updateOrder = factory.newTransaction(NS, 'Buy');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Order From Supplier':
- console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier);
- updateOrder = factory.newTransaction(NS, 'OrderFromSupplier');
- updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Request Payment':
- console.log('Request Payment entered');
- updateOrder = factory.newTransaction(NS, 'RequestPayment');
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- break;
- case 'Refund':
- console.log('Refund Payment entered');
- updateOrder = factory.newTransaction(NS, 'Refund');
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.refund = req.body.reason;
- break;
- case 'Resolve':
- console.log('Resolve entered');
- console.log('participants: buyer: '+order.buyer.$identifier+' seller: '+order.seller.$identifier+' provider: '+order.provider.$identifier+' shipper: '+order.shipper.$identifier)
- updateOrder = factory.newTransaction(NS, 'Resolve');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier);
- updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.resolve = req.body.reason;
- break;
- case 'Request Shipping':
- console.log('Request Shipping entered');
- updateOrder = factory.newTransaction(NS, 'RequestShipping');
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper);
- updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
- break;
- case 'Update Delivery Status':
- console.log('Update Delivery Status');
- updateOrder = factory.newTransaction(NS, 'Delivering');
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant);
- updateOrder.deliveryStatus = req.body.delivery;
- break;
- case 'Delivered':
- console.log('Delivered entered');
- updateOrder = factory.newTransaction(NS, 'Deliver');
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant);
- break;
- case 'BackOrder':
- console.log('BackOrder entered');
- updateOrder = factory.newTransaction(NS, 'BackOrder');
- updateOrder.backorder = req.body.reason;
- updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
- updateOrder.backorder = req.body.reason;
- break;
- case 'Authorize Payment':
- console.log('Authorize Payment entered');
- updateOrder = factory.newTransaction(NS, 'AuthorizePayment');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- break;
- case 'Cancel':
- console.log('Cancel entered');
- updateOrder = factory.newTransaction(NS, 'OrderCancel');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- default :
- console.log('default entered for action: '+req.body.action);
- res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
- }
- updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
- return businessNetworkConnection.submitTransaction(updateOrder)
- .then(() => {
- console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action);
- res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action});
- })
- .catch((error) => {
- console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(" retrying assetRegistry.update for: "+req.body.orderNo);
- svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
- }
- });
-
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.participant)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.get(req.body.orderNo)
+ .then((order) => {
+ let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ order.status = req.body.action;
+ switch (req.body.action)
+ {
+ case 'Pay':
+ console.log('Pay entered');
+ updateOrder = factory.newTransaction(NS, 'Pay');
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ case 'Dispute':
+ console.log('Dispute entered');
+ updateOrder = factory.newTransaction(NS, 'Dispute');
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.dispute = req.body.reason;
+ break;
+ case 'Purchase':
+ console.log('Purchase entered');
+ updateOrder = factory.newTransaction(NS, 'Buy');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ case 'Order From Supplier':
+ console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier);
+ updateOrder = factory.newTransaction(NS, 'OrderFromSupplier');
+ updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ case 'Request Payment':
+ console.log('Request Payment entered');
+ updateOrder = factory.newTransaction(NS, 'RequestPayment');
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ break;
+ case 'Refund':
+ console.log('Refund Payment entered');
+ updateOrder = factory.newTransaction(NS, 'Refund');
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.refund = req.body.reason;
+ break;
+ case 'Resolve':
+ console.log('Resolve entered');
+ updateOrder = factory.newTransaction(NS, 'Resolve');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier);
+ updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.resolve = req.body.reason;
+ break;
+ case 'Request Shipping':
+ console.log('Request Shipping entered');
+ updateOrder = factory.newTransaction(NS, 'RequestShipping');
+ updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper);
+ updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
+ break;
+ case 'Update Delivery Status':
+ console.log('Update Delivery Status');
+ updateOrder = factory.newTransaction(NS, 'Delivering');
+ updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant);
+ updateOrder.deliveryStatus = req.body.delivery;
+ break;
+ case 'Delivered':
+ console.log('Delivered entered');
+ updateOrder = factory.newTransaction(NS, 'Deliver');
+ updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant);
+ break;
+ case 'BackOrder':
+ console.log('BackOrder entered');
+ updateOrder = factory.newTransaction(NS, 'BackOrder');
+ updateOrder.backorder = req.body.reason;
+ updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
+ updateOrder.backorder = req.body.reason;
+ break;
+ case 'Authorize Payment':
+ console.log('Authorize Payment entered');
+ updateOrder = factory.newTransaction(NS, 'AuthorizePayment');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ break;
+ case 'Cancel':
+ console.log('Cancel entered');
+ updateOrder = factory.newTransaction(NS, 'OrderCancel');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ default :
+ console.log('default entered for action: '+req.body.action);
+ res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
+ }
+ updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
+ return businessNetworkConnection.submitTransaction(updateOrder)
+ .then(() => {
+ console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action);
+ res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action});
})
.catch((error) => {
- console.log('Registry Get Order failed: '+error.message);
- res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(' retrying assetRegistry.update for: '+req.body.orderNo);
+ svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
+ }
+ else
+ {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);}
});
+
})
- .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
+ .catch((error) => {
+ console.log('Registry Get Order failed: '+error.message);
+ res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
- })
- .catch((error) => {console.log('Business Network Connect failed: '+error.message);
+ })
+ .catch((error) => {console.log('Business Network Connect failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
-}
+};
+
/**
* adds an order to the blockchain
* @param {express.req} req - the inbound request object from the client
@@ -260,83 +273,87 @@ exports.orderAction = function (req, res, next) {
* req.body.items - array with items for order
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.addOrder = function (req, res, next) {
+ let method = 'addOrder';
+ console.log(method+' req.body.buyer is: '+req.body.buyer );
let businessNetworkConnection;
let factory;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let ts = Date.now();
- let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
- if (svc.m_connection == null) {svc.createMessageSocket();}
- console.log(orderNo);
-
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- let order = factory.newResource(NS, 'Order', orderNo);
- order = svc.createOrderTemplate(order);
- order.amount = 0;
- order.orderNumber = orderNo;
- order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
- order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
- order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- for (let each in req.body.items)
- {(function(_idx, _arr)
- { _arr[_idx].description = _arr[_idx].itemDescription;
- order.items.push(JSON.stringify(_arr[_idx]));
- order.amount += parseInt(_arr[_idx].extendedPrice);
- })(each, req.body.items)
- }
- // create the buy transaction
- const createNew = factory.newTransaction(NS, 'CreateOrder');
-
- createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
- createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- createNew.amount = order.amount;
- // add the order to the asset registry.
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.add(order)
- .then(() => {
- return businessNetworkConnection.submitTransaction(createNew)
- .then(() => {console.log(' order '+orderNo+" successfully added");
- res.send({'result': ' order '+orderNo+' successfully added'});
- })
- .catch((error) => {
- console.log(orderNo+" submitTransaction failed with text: ",error.message);
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- });
- })
- .catch((error) => {
- console.log(orderNo+" assetRegistry.add failed: ",error.message);
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- });
- })
- .catch((error) => {
- console.log(orderNo+" getAssetRegistry failed: ",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
- });
- })
- .catch((error) => {
- console.log(orderNo+" business network connection failed: text",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
- });
+ let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
+ if (svc.m_connection === null) {svc.createMessageSocket();}
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.buyer)
+ .then(() => {
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ let order = factory.newResource(NS, 'Order', orderNo);
+ order = svc.createOrderTemplate(order);
+ order.amount = 0;
+ order.orderNumber = orderNo;
+ order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
+ order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
+ order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
+ order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
+ order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ for (let each in req.body.items)
+ {(function(_idx, _arr)
+ { _arr[_idx].description = _arr[_idx].itemDescription;
+ order.items.push(JSON.stringify(_arr[_idx]));
+ order.amount += parseInt(_arr[_idx].extendedPrice);
+ })(each, req.body.items);
}
+ // create the buy transaction
+ const createNew = factory.newTransaction(NS, 'CreateOrder');
+
+ createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
+ createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
+ createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
+ createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ createNew.amount = order.amount;
+ // add the order to the asset registry.
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.add(order)
+ .then(() => {
+ return businessNetworkConnection.submitTransaction(createNew)
+ .then(() => {console.log(' order '+orderNo+' successfully added');
+ res.send({'result': ' order '+orderNo+' successfully added'});
+ })
+ .catch((error) => {
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo);
+ svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
+ }
+ else
+ {console.log(orderNo+' submitTransaction failed with text: ',error.message);}
+ });
+ })
+ .catch((error) => {
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo);
+ svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
+ }
+ else
+ {
+ console.log(orderNo+' assetRegistry.add failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ }
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' getAssetRegistry failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' business network connection failed: text',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
+ });
+};
diff --git a/Chapter05/controller/restapi/features/text/ch/prompts.json b/Chapter05/controller/restapi/features/text/ch/prompts.json
index 363128d..5c6091d 100644
--- a/Chapter05/controller/restapi/features/text/ch/prompts.json
+++ b/Chapter05/controller/restapi/features/text/ch/prompts.json
@@ -54,6 +54,9 @@
"rm_am_param":"Co 名字,ID, 类型",
"rm_rm_api":"删除成员",
"rm_gs_api":"获取成员秘密",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Check if card exists",
+ "rm_cc2_api": "Create Card",
"bc":"区块链",
"bc_api":"API",
"bc_param":"参数",
@@ -96,8 +99,8 @@
"cd_financeco":"FinanceCo",
"cd_cn":"公司名称",
"cd_e":"电子邮箱地址",
- "cancelNewOrder":"取消",
- "submitNewOrder":"提交"
+ "cancel":"取消",
+ "submit":"提交"
},
"createOrder": {
"title":"创建新订单",
diff --git a/Chapter05/controller/restapi/features/text/en-UK/prompts.json b/Chapter05/controller/restapi/features/text/en-UK/prompts.json
index 5a91a08..8f2be89 100644
--- a/Chapter05/controller/restapi/features/text/en-UK/prompts.json
+++ b/Chapter05/controller/restapi/features/text/en-UK/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language": "UK English",
- "title": "Z2B Chapter 5",
- "header": "Chapter 5: Building the Administration User Experience",
- "titleBar": "Zero to Blockchain Tutorial",
- "idx_unified": "load Unified User Experience",
- "idx_buyer": "load Buyer User Experience",
- "idx_seller": "load Seller User Experience",
- "idx_provider": "load Provider User Experience",
- "idx_shipper": "load Shipper User Experience",
- "idx_financeco": "load Finance Company User Experience",
- "idx_roles": "Roles",
- "idx_admin": "Admin",
- "idx_adminUX": "load Admin User Experience",
- "idx_preload": "Preload Network"
- },
- "admin": {
- "title": "Zero To Blockchain Chapter 5",
- "npm": "Network Profile Management",
- "npm_API": "API",
- "npm_param": "Parameters",
- "npm_dp_api": "delete profile",
- "npm_dp_param": "profile name",
- "npm_cp_api": "create Profile",
- "npm_cp_param": "profile object",
- "npm_ga_api": "get all connection profiles",
- "npm_ga_param": "(none)",
- "npm_g1_api": "get a specific network connection profile",
- "npm_g1_param": "profile name",
- "bnm": "Business Network Management",
- "bnm_param": "Parameters",
- "bnm_api": "API",
- "bnm_nd_api": "deploy a network",
- "bnm_nd_param": "network archive file, options",
- "bnm_ni_api": "install new a network",
- "bnm_ni_param": "network archive file, options",
- "bnm_ns_api": "start an installed network",
- "bnm_ns_param": "network name, options",
- "bnm_nl_api": "list the deployed business networks",
- "bnm_nl_param": "(none)",
- "bnm_np_api": "touch a network, check compatibility",
- "bnm_np_param": "business network name",
- "bnm_nu_api": "take a business network off line",
- "bnm_nu_param": "business network name<",
- "bnm_nuu_api": "update an existing business network",
- "bnm_nuu_param": "business network name, archive file",
- "rm": "Resource Management",
- "rm_api": "API",
- "rm_param": "Parameters",
- "rm_lr_api": "list members of a registry",
- "rm_la_api": "List Assets in the registry",
- "rm_la_param": "(none)",
- "rm_am_api": "Add Member",
- "rm_am_param": "Co Name, id, Type",
- "rm_rm_api": "Remove Member",
- "rm_gs_api": "getMemberSecret",
- "bc": "BlockChain",
- "bc_api": "API",
- "bc_param": "Parameters",
- "bc_gi_api": "initiate connection to blockchain",
- "bc_gi_param": "(none)",
- "bc_ge_api": "register for blockchain events",
- "bc_ge_param": "(none)",
- "bc_gh_api": "get Historian",
- "bc_gh_param": "(none)"
- },
- "buyer": {
- "title": "Buyer Chapter 5. Select Buyer to see their view: ",
- "newOrder": "Create New Order",
- "orderStatus": "Display Order Status"
- },
- "createConnectionProfile": {
- "title": "type the name of the new profile here: ",
- "cp_type": "type",
- "cp_orderers": "orderers",
- "cp_orderers_url": "url",
- "cp_ca": "ca",
- "cp_ca_url": "url",
- "cp_ca_name": "name",
- "cp_peers": "peers",
- "cp_peers_event_url": "eventURL",
- "cp_peers_request_url": "requestURL",
- "cp_keyValStore": "keyValStore",
- "cp_channel": "channel",
- "cp_mspID": "mspID",
- "cp_timeout": "timeout",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "createMember": {
- "cd_type": "Type",
- "cd_buyer": "Buyer",
- "cd_seller": "Seller",
- "cd_shipper": "Shipper",
- "cd_provider": "Provider",
- "cd_financeco": "FinanceCo",
- "cd_cn": "Company Name",
- "cd_e": "email Address",
- "cancelNewOrder": "Cancel",
- "submitNewOrder": "Submit"
- },
- "createOrder": {
- "title": "Create New Order",
- "selectVendor": "Select Vendor: ",
- "cn_on": "Order Number",
- "cn_status": "Status",
- "cn_date": "Date",
- "cn_total": "Total",
- "cn_selectItem": "Select Item",
- "addItem": "Add Item",
- "cancelNewOrder": "Cancel",
- "submitNewOrder": "Submit"
- },
- "deleteConnectionProfile": {
- "title": "Select Profile to delete: ",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "financeCo": {
- "title": "Zero To Blockchain Chapter 5: The Global Financier",
- "financeCOclear": "Clear Window",
- "financeCOorderStatus": "Display Order Status"
- },
- "getMemberSecret": {
- "gs_type": "Type",
- "gs_members": "Members",
- "gs_company": "Company Name",
- "gs_email": "email Address",
- "gs_userID": "userID",
- "gs_secret": "secret",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "provider": {
- "title": "Provider Chapter 5, Select Provider to see their view: ",
- "provider_clear": "Clear Window",
- "providerOrderStatus": "Display Order Status"
- },
- "removeMember": {
- "rm_type": "Type",
- "rm_members": "Members",
- "rm_company": "Company Name",
- "rm_email": "email Address",
- "rm_userID": "userID",
- "rm_secret": "secret",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "seller": {
- "title": "Seller Chapter 5, Select Seller to see their view: ",
- "seller_clear": "Clear Window",
- "sellerOrderStatus": "Display Order Status"
- },
- "shipper": {
- "title": "Shipper Chapter 5, Select Shipper to see their view: ",
- "shipper_clear": "Clear Window",
- "shipperOrderStatus": "Display Order Status "
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"},
- "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "},
- "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "},
- "Purchase": {"select": "Purchase", "message": "Purchase"},
- "Cancel": {"select": "Cancel", "message": "Cancel"},
- "Pay": {"select": "Pay", "message": "Pay"},
- "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"},
- "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "},
- "PayRequest": {"select": "PayRequest", "message": "Request Payment"},
- "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "},
- "Delivered": {"select": "Delivered", "message": "Delivered"},
- "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "},
- "Order": {"select": "Order", "message": "Order From Supplier"},
- "NoAction": {"select": "NoAction", "message": "Take No Action"},
- "ex_button": "Execute",
- "ca_button": "Cancel",
- "orderno": "Order #",
- "status": "Status",
- "total": "Total",
- "seller": "Seller: ",
- "itemno": "Item Number",
- "description": "Description",
- "qty": "Quantity",
- "price": "Price",
- "processing_msg": "Processing {0} request for order number: {1}",
- "b_no_order_msg": "No orders for this buyer: ",
- "s_no_order_msg": "No orders for this seller: ",
- "p_no_order_msg": "No orders for this provider: ",
- "sh_no_order_msg": "No orders for this shipper: ",
- "create_msg": "Processing Create Order request",
- "buyer": "Buyer: "
- },
- "financeCoOrder": {
- "status": "Current Status: ",
- "action": "Action",
- "by": "By",
- "date": "Date",
- "comments": "Comments",
- "created": "Created",
- "cancelled": "Cancelled?",
- "notCancel": "(not Cancelled)",
- "purchased": "Purchased",
- "noPurchase": "(no Purchase Request)",
- "thirdParty": "3rd Party Order",
- "nothirdParty": "(not yet sent to 3rd Party)",
- "backordered": "Backordered?",
- "notBackordered": "(not Backordered)",
- "shippingRequested": "Shipping Requested",
- "noRequestShip": "(No Request to Shipper)",
- "shippingStarted": "Shipping Started",
- "noDeliveryStart": "(Delivery not Started)",
- "delivered": "Delivered",
- "notDelivered": "(not yet Delivered)",
- "payRequested": "Payment Requested",
- "noRequest": "(no request for payment)",
- "disputed": "Dispute Raised",
- "noDispute": "(not in Dispute)"
- }
-}
+ "index": {"language":"US English",
+ "title":"Z2B Chapter 5",
+ "header":"Chapter 5: Building the Administrative User Experience",
+ "titleBar":"Zero to Blockchain Tutorial",
+ "idx_unified":"load Unified User Experience",
+ "idx_buyer":"load Buyer User Experience",
+ "idx_seller":"load Seller User Experience",
+ "idx_provider":"load Provider User Experience",
+ "idx_shipper":"load Shipper User Experience",
+ "idx_financeco":"load Finance Company User Experience",
+ "idx_roles":"Roles",
+ "idx_admin":"Admin",
+ "idx_adminUX":"load Admin User Experience",
+ "idx_preload":"Preload Network"
+ },
+ "admin": {
+ "title":"Zero To Blockchain Chapter 05",
+ "npm":"Network Profile Management",
+ "npm_API":"API",
+ "npm_param":"Parameters",
+ "npm_dp_api":"delete profile",
+ "npm_dp_param":"profile name",
+ "npm_cp_api":"create Profile",
+ "npm_cp_param":"profile object",
+ "npm_ga_api":"get all connection profiles",
+ "npm_ga_param":"(none)",
+ "npm_g1_api":"get a specific network connection profile",
+ "npm_g1_param":"profile name",
+ "bnm":"Business Network Management",
+ "bnm_param":"Parameters",
+ "bnm_api":"API",
+ "bnm_nd_api":"deploy a network",
+ "bnm_nd_param":"network archive file, options",
+ "bnm_ni_api":"install new a network",
+ "bnm_ni_param":"network archive file, options",
+ "bnm_ns_api":"start an installed network",
+ "bnm_ns_param":"network name, options",
+ "bnm_nl_api":"list the deployed business networks",
+ "bnm_nl_param":"(none)",
+ "bnm_np_api":"touch a network, check compatibility",
+ "bnm_np_param":"business network name",
+ "bnm_nu_api":"take a business network off line",
+ "bnm_nu_param":"business network name<",
+ "bnm_nuu_api":"update an existing business network",
+ "bnm_nuu_param":"business network name, archive file",
+ "rm":"Resource Management",
+ "rm_api":"API",
+ "rm_param":"Parameters",
+ "rm_lr_api":"list members of a registry",
+ "rm_la_api":"List Assets in the registry",
+ "rm_la_param":"(none)",
+ "rm_am_api":"Add Member",
+ "rm_am_param":"Co Name, id, Type",
+ "rm_rm_api":"Remove Member",
+ "rm_gs_api":"getMemberSecret",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Check if card exists",
+ "rm_cc2_api": "Create Card",
+ "bc":"BlockChain",
+ "bc_api":"API",
+ "bc_param":"Parameters",
+ "bc_gi_api":"initiate connection to blockchain",
+ "bc_gi_param":"(none)",
+ "bc_ge_api":"register for blockchain events",
+ "bc_ge_param":"(none)",
+ "bc_gh_api":"get Historian",
+ "bc_gh_param":"(none)"
+ },
+ "buyer": {
+ "title":"Buyer Chapter 06. Select Buyer to see their view: ",
+ "newOrder":"Create New Order",
+ "orderStatus":"Display Order Status"
+ },
+ "createConnectionProfile": {
+ "title":"type the name of the new profile here: ",
+ "cp_type":"type",
+ "cp_orderers":"orderers",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"name",
+ "cp_peers":"peers",
+ "cp_peers_event_url":"eventURL",
+ "cp_peers_request_url":"requestURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"channel",
+ "cp_mspID":"mspID",
+ "cp_timeout":"timeout",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "createMember": {
+ "cd_type":"Type",
+ "cd_buyer":"Buyer",
+ "cd_seller":"Seller",
+ "cd_shipper":"Shipper",
+ "cd_provider":"Provider",
+ "cd_financeco":"FinanceCo",
+ "cd_cn":"Company Name",
+ "cd_e":"email Address",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "createOrder": {
+ "title":"Create New Order",
+ "selectVendor":"Select Vendor: ",
+ "cn_on":"Order Number",
+ "cn_status":"Status",
+ "cn_date":"Date",
+ "cn_total":"Total",
+ "cn_selectItem":"Select Item",
+ "addItem":"Add Item",
+ "cancelNewOrder":"Cancel",
+ "submitNewOrder":"Submit"
+ },
+ "deleteConnectionProfile": {
+ "title":"Select Profile to delete: ",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "financeCo": {
+ "title":"Zero To Blockchain Chapter 10: The Global Financier",
+ "financeCOclear":"Clear Window",
+ "financeCOorderStatus":"Display Order Status"
+ },
+ "getMemberSecret": {
+ "gs_type":"Type",
+ "gs_members":"Members",
+ "gs_company":"Company Name",
+ "gs_email":"email Address",
+ "gs_userID":"userID",
+ "gs_secret":"secret",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "provider": {
+ "title":"Provider Chapter 08, Select Provider to see their view: ",
+ "provider_clear":"Clear Window",
+ "providerOrderStatus":"Display Order Status"
+ },
+ "removeMember": {
+ "rm_type":"Type",
+ "rm_members":"Members",
+ "rm_company":"Company Name",
+ "rm_email":"email Address",
+ "rm_userID":"userID",
+ "rm_secret":"secret",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "seller": {
+ "title":"Seller Chapter 07, Select Seller to see their view: ",
+ "seller_clear":"Clear Window",
+ "sellerOrderStatus":"Display Order Status"
+ },
+ "shipper": {
+ "title":"Shipper Chapter 09, Select Shipper to see their view: ",
+ "shipper_clear":"Clear Window",
+ "shipperOrderStatus":"Display Order Status "
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"},
+ "Dispute": {"select": "Dispute","message":"Dispute"},
+ "Resolve": {"select": "Resolve","message":"Resolve"},
+ "Purchase": {"select": "Purchase","message":"Purchase"},
+ "Cancel": {"select": "Cancel","message":"Cancel"},
+ "Pay": {"select": "Pay","message":"Pay"},
+ "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"},
+ "BackOrder": {"select": "BackOrder","message":"BackOrder"},
+ "PayRequest": {"select": "PayRequest","message":"Request Payment"},
+ "Refund": {"select": "Refund","message":"Refund"},
+ "Delivered": {"select": "Delivered","message":"Delivered"},
+ "Delivering": {"select": "Delivering","message":"Update Delivery Status"},
+ "Order": {"select": "Order","message":"Order From Supplier"},
+ "NoAction": {"select": "NoAction","message":"Take No Action"},
+ "ex_button":"Execute",
+ "ca_button":"Cancel",
+ "orderno":"Order #",
+ "status":"Status",
+ "total":"Total",
+ "seller":"Seller: ",
+ "itemno":"Item Number",
+ "description":"Description",
+ "qty":"Quantity",
+ "price":"Price",
+ "processing_msg":"Processing {0} request for order number: {1}",
+ "b_no_order_msg":"No orders for this buyer: ",
+ "s_no_order_msg":"No orders for this seller: ",
+ "p_no_order_msg":"No orders for this provider: ",
+ "sh_no_order_msg":"No orders for this shipper: ",
+ "create_msg":"Processing Create Order request",
+ "buyer":"Buyer: "
+ },
+ "financeCoOrder": {
+ "status":"Current Status: ",
+ "action":"Action",
+ "by":"By",
+ "date":"Date",
+ "comments":"Comments",
+ "created":"Created",
+ "cancelled":"Cancelled?",
+ "notCancel":"(not Cancelled)",
+ "purchased":"Purchased",
+ "noPurchase":"(no Purchase Request)",
+ "thirdParty":"3rd Party Order",
+ "nothirdParty":"(not yet sent to 3rd Party)",
+ "backordered":"Backordered?",
+ "notBackordered":"(not Backordered)",
+ "shippingRequested":"Shipping Requested",
+ "noRequestShip":"(No Request to Shipper)",
+ "shippingStarted":"Shipping Started",
+ "noDeliveryStart":"(Delivery not Started)",
+ "delivered":"Delivered",
+ "notDelivered":"(not yet Delivered)",
+ "payRequested":"Payment Requested",
+ "noRequest":"(no request for payment)",
+ "disputed":"Dispute Raised",
+ "noDispute":"(not in Dispute)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/text/en-US/prompts.json b/Chapter05/controller/restapi/features/text/en-US/prompts.json
index a4ab1f1..bc9e5c5 100644
--- a/Chapter05/controller/restapi/features/text/en-US/prompts.json
+++ b/Chapter05/controller/restapi/features/text/en-US/prompts.json
@@ -1,219 +1,223 @@
{
- "index": {"language": "US English",
- "title": "Z2B Chapter 5",
- "header": "Chapter 5: Building the Administration User Experience",
- "titleBar": "Zero to Blockchain Tutorial",
- "idx_unified": "load Unified User Experience",
- "idx_buyer": "load Buyer User Experience",
- "idx_seller": "load Seller User Experience",
- "idx_provider": "load Provider User Experience",
- "idx_shipper": "load Shipper User Experience",
- "idx_financeco": "load Finance Company User Experience",
- "idx_roles": "Roles",
- "idx_admin": "Admin",
- "idx_adminUX": "load Admin User Experience",
- "idx_preload": "Preload Network"
- },
- "admin": {
- "title": "Zero To Blockchain Chapter 5",
- "npm": "Network Profile Management",
- "npm_API": "API",
- "npm_param": "Parameters",
- "npm_dp_api": "delete profile",
- "npm_dp_param": "profile name",
- "npm_cp_api": "create Profile",
- "npm_cp_param": "profile object",
- "npm_ga_api": "get all connection profiles",
- "npm_ga_param": "(none)",
- "npm_g1_api": "get a specific network connection profile",
- "npm_g1_param": "profile name",
- "bnm": "Business Network Management",
- "bnm_param": "Parameters",
- "bnm_api": "API",
- "bnm_nd_api": "deploy a network",
- "bnm_nd_param": "network archive file, options",
- "bnm_ni_api": "install new a network",
- "bnm_ni_param": "network archive file, options",
- "bnm_ns_api": "start an installed network",
- "bnm_ns_param": "network name, options",
- "bnm_nl_api": "list the deployed business networks",
- "bnm_nl_param": "(none)",
- "bnm_np_api": "touch a network, check compatibility",
- "bnm_np_param": "business network name",
- "bnm_nu_api": "take a business network off line",
- "bnm_nu_param": "business network name<",
- "bnm_nuu_api": "update an existing business network",
- "bnm_nuu_param": "business network name, archive file",
- "rm": "Resource Management",
- "rm_api": "API",
- "rm_param": "Parameters",
- "rm_lr_api": "list members of a registry",
- "rm_la_api": "List Assets in the registry",
- "rm_la_param": "(none)",
- "rm_am_api": "Add Member",
- "rm_am_param": "Co Name, id, Type",
- "rm_rm_api": "Remove Member",
- "rm_gs_api": "getMemberSecret",
- "bc": "BlockChain",
- "bc_api": "API",
- "bc_param": "Parameters",
- "bc_gi_api": "initiate connection to blockchain",
- "bc_gi_param": "(none)",
- "bc_ge_api": "register for blockchain events",
- "bc_ge_param": "(none)",
- "bc_gh_api": "get Historian",
- "bc_gh_param": "(none)"
- },
- "buyer": {
- "title": "Buyer Chapter 5. Select Buyer to see their view: ",
- "newOrder": "Create New Order",
- "orderStatus": "Display Order Status"
- },
- "createConnectionProfile": {
- "title": "type the name of the new profile here: ",
- "cp_type": "type",
- "cp_orderers": "orderers",
- "cp_orderers_url": "url",
- "cp_ca": "ca",
- "cp_ca_url": "url",
- "cp_ca_name": "name",
- "cp_peers": "peers",
- "cp_peers_event_url": "eventURL",
- "cp_peers_request_url": "requestURL",
- "cp_keyValStore": "keyValStore",
- "cp_channel": "channel",
- "cp_mspID": "mspID",
- "cp_timeout": "timeout",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "createMember": {
- "cd_type": "Type",
- "cd_buyer": "Buyer",
- "cd_seller": "Seller",
- "cd_shipper": "Shipper",
- "cd_provider": "Provider",
- "cd_financeco": "FinanceCo",
- "cd_cn": "Company Name",
- "cd_e": "email Address",
- "cancelNewOrder": "Cancel",
- "submitNewOrder": "Submit"
- },
- "createOrder": {
- "title": "Create New Order",
- "selectVendor": "Select Vendor: ",
- "cn_on": "Order Number",
- "cn_status": "Status",
- "cn_date": "Date",
- "cn_total": "Total",
- "cn_selectItem": "Select Item",
- "addItem": "Add Item",
- "cancelNewOrder": "Cancel",
- "submitNewOrder": "Submit"
- },
- "deleteConnectionProfile": {
- "title": "Select Profile to delete: ",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "financeCo": {
- "title": "Zero To Blockchain Chapter 5: The Global Financier",
- "financeCOclear": "Clear Window",
- "financeCOorderStatus": "Display Order Status"
- },
- "getMemberSecret": {
- "gs_type": "Type",
- "gs_members": "Members",
- "gs_company": "Company Name",
- "gs_email": "email Address",
- "gs_userID": "userID",
- "gs_secret": "secret",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "provider": {
- "title": "Provider Chapter 5, Select Provider to see their view: ",
- "provider_clear": "Clear Window",
- "providerOrderStatus": "Display Order Status"
- },
- "removeMember": {
- "rm_type": "Type",
- "rm_members": "Members",
- "rm_company": "Company Name",
- "rm_email": "email Address",
- "rm_userID": "userID",
- "rm_secret": "secret",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "seller": {
- "title": "Seller Chapter 5, Select Seller to see their view: ",
- "seller_clear": "Clear Window",
- "sellerOrderStatus": "Display Order Status"
- },
- "shipper": {
- "title": "Shipper Chapter 5, Select Shipper to see their view: ",
- "shipper_clear": "Clear Window",
- "shipperOrderStatus": "Display Order Status "
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"},
- "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "},
- "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "},
- "Purchase": {"select": "Purchase", "message": "Purchase"},
- "Cancel": {"select": "Cancel", "message": "Cancel"},
- "Pay": {"select": "Pay", "message": "Pay"},
- "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"},
- "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "},
- "PayRequest": {"select": "PayRequest", "message": "Request Payment"},
- "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "},
- "Delivered": {"select": "Delivered", "message": "Delivered"},
- "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "},
- "Order": {"select": "Order", "message": "Order From Supplier"},
- "NoAction": {"select": "NoAction", "message": "Take No Action"},
- "ex_button": "Execute",
- "ca_button": "Cancel",
- "orderno": "Order #",
- "status": "Status",
- "total": "Total",
- "seller": "Seller: ",
- "itemno": "Item Number",
- "description": "Description",
- "qty": "Quantity",
- "price": "Price",
- "processing_msg": "Processing {0} request for order number: {1}",
- "b_no_order_msg": "No orders for this buyer: ",
- "s_no_order_msg": "No orders for this seller: ",
- "p_no_order_msg": "No orders for this provider: ",
- "sh_no_order_msg": "No orders for this shipper: ",
- "create_msg": "Processing Create Order request",
- "buyer": "Buyer: "
- },
- "financeCoOrder": {
- "status": "Current Status: ",
- "action": "Action",
- "by": "By",
- "date": "Date",
- "comments": "Comments",
- "created": "Created",
- "cancelled": "Cancelled?",
- "notCancel": "(not Cancelled)",
- "purchased": "Purchased",
- "noPurchase": "(no Purchase Request)",
- "thirdParty": "3rd Party Order",
- "nothirdParty": "(not yet sent to 3rd Party)",
- "backordered": "Backordered?",
- "notBackordered": "(not Backordered)",
- "shippingRequested": "Shipping Requested",
- "noRequestShip": "(No Request to Shipper)",
- "shippingStarted": "Shipping Started",
- "noDeliveryStart": "(Delivery not Started)",
- "delivered": "Delivered",
- "notDelivered": "(not yet Delivered)",
- "payRequested": "Payment Requested",
- "noRequest": "(no request for payment)",
- "disputed": "Dispute Raised",
- "noDispute": "(not in Dispute)"
+ "index": {"language": "US English",
+ "title": "Z2B Chapter 5",
+ "header": "Chapter 5: Building the Administration User Experience",
+ "titleBar": "Zero to Blockchain Tutorial",
+ "idx_unified": "load Unified User Experience",
+ "idx_buyer": "load Buyer User Experience",
+ "idx_seller": "load Seller User Experience",
+ "idx_provider": "load Provider User Experience",
+ "idx_shipper": "load Shipper User Experience",
+ "idx_financeco": "load Finance Company User Experience",
+ "idx_roles": "Roles",
+ "idx_admin": "Admin",
+ "idx_adminUX": "load Admin User Experience",
+ "idx_preload": "Preload Network"
+ },
+ "admin": {
+ "title": "Zero To Blockchain Chapter 5",
+ "npm": "Network Profile Management",
+ "npm_API": "API",
+ "npm_param": "Parameters",
+ "npm_dp_api": "delete profile",
+ "npm_dp_param": "profile name",
+ "npm_cp_api": "create Profile",
+ "npm_cp_param": "profile object",
+ "npm_ga_api": "get all connection profiles",
+ "npm_ga_param": "(none)",
+ "npm_g1_api": "get a specific network connection profile",
+ "npm_g1_param": "profile name",
+ "bnm": "Business Network Management",
+ "bnm_param": "Parameters",
+ "bnm_api": "API",
+ "bnm_nd_api": "deploy a network",
+ "bnm_nd_param": "network archive file, options",
+ "bnm_ni_api": "install new a network",
+ "bnm_ni_param": "network archive file, options",
+ "bnm_ns_api": "start an installed network",
+ "bnm_ns_param": "network name, options",
+ "bnm_nl_api": "list the deployed business networks",
+ "bnm_nl_param": "(none)",
+ "bnm_np_api": "touch a network, check compatibility",
+ "bnm_np_param": "business network name",
+ "bnm_nu_api": "take a business network off line",
+ "bnm_nu_param": "business network name<",
+ "bnm_nuu_api": "update an existing business network",
+ "bnm_nuu_param": "business network name, archive file",
+ "rm": "Resource Management",
+ "rm_api": "API",
+ "rm_param": "Parameters",
+ "rm_lr_api": "list members of a registry",
+ "rm_la_api": "List Assets in the registry",
+ "rm_la_param": "(none)",
+ "rm_am_api": "Add Member",
+ "rm_am_param": "Co Name, id, Type",
+ "rm_rm_api": "Remove Member",
+ "rm_gs_api": "get Member Secret",
+ "rm_ii_api": "Issue Identity",
+ "rm_cc_api": "Check if card exists",
+ "rm_cc2_api": "Create Card",
+ "bc": "BlockChain",
+ "bc_api": "API",
+ "bc_param": "Parameters",
+ "bc_gi_api": "initiate connection to blockchain",
+ "bc_gi_param": "(none)",
+ "bc_ge_api": "register for blockchain events",
+ "bc_ge_param": "(none)",
+ "bc_gh_api": "get Historian",
+ "bc_gh_param": "(none)"
+ },
+ "buyer": {
+ "title": "Buyer Chapter 5. Select Buyer to see their view: ",
+ "newOrder": "Create New Order",
+ "orderStatus": "Display Order Status"
+ },
+ "createConnectionProfile": {
+ "title": "type the name of the new profile here: ",
+ "cp_type": "type",
+ "cp_orderers": "orderers",
+ "cp_orderers_url": "url",
+ "cp_ca": "ca",
+ "cp_ca_url": "url",
+ "cp_ca_name": "name",
+ "cp_peers": "peers",
+ "cp_peers_event_url": "eventURL",
+ "cp_peers_request_url": "requestURL",
+ "cp_keyValStore": "keyValStore",
+ "cp_channel": "channel",
+ "cp_mspID": "mspID",
+ "cp_timeout": "timeout",
+ "cancel": "Cancel",
+ "submit": "Submit"
+ },
+ "createMember": {
+ "cd_type": "Type",
+ "cd_buyer": "Buyer",
+ "cd_seller": "Seller",
+ "cd_shipper": "Shipper",
+ "cd_provider": "Provider",
+ "cd_financeco": "FinanceCo",
+ "cd_cn": "Company Name",
+ "cd_e": "email Address",
+ "cancel": "Cancel",
+ "submit": "Submit"
+ },
+ "createOrder": {
+ "title": "Create New Order",
+ "selectVendor": "Select Vendor: ",
+ "cn_on": "Order Number",
+ "cn_status": "Status",
+ "cn_date": "Date",
+ "cn_total": "Total",
+ "cn_selectItem": "Select Item",
+ "addItem": "Add Item",
+ "cancelNewOrder": "Cancel",
+ "submitNewOrder": "Submit"
+ },
+ "deleteConnectionProfile": {
+ "title": "Select Profile to delete: ",
+ "cancel": "Cancel",
+ "submit": "Submit"
+ },
+ "financeCo": {
+ "title": "Zero To Blockchain Chapter 5: The Global Financier",
+ "financeCOclear": "Clear Window",
+ "financeCOorderStatus": "Display Order Status"
+ },
+ "getMemberSecret": {
+ "gs_type": "Type",
+ "gs_members": "Members",
+ "gs_company": "Company Name",
+ "gs_email": "email Address",
+ "gs_userID": "userID",
+ "gs_secret": "secret",
+ "cancel": "Cancel",
+ "submit": "Submit"
+ },
+ "provider": {
+ "title": "Provider Chapter 5, Select Provider to see their view: ",
+ "provider_clear": "Clear Window",
+ "providerOrderStatus": "Display Order Status"
+ },
+ "removeMember": {
+ "rm_type": "Type",
+ "rm_members": "Members",
+ "rm_company": "Company Name",
+ "rm_email": "email Address",
+ "rm_userID": "userID",
+ "rm_secret": "secret",
+ "cancel": "Cancel",
+ "submit": "Submit"
+ },
+ "seller": {
+ "title": "Seller Chapter 5, Select Seller to see their view: ",
+ "seller_clear": "Clear Window",
+ "sellerOrderStatus": "Display Order Status"
+ },
+ "shipper": {
+ "title": "Shipper Chapter 5, Select Shipper to see their view: ",
+ "shipper_clear": "Clear Window",
+ "shipperOrderStatus": "Display Order Status "
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"},
+ "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "},
+ "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "},
+ "Purchase": {"select": "Purchase", "message": "Purchase"},
+ "Cancel": {"select": "Cancel", "message": "Cancel"},
+ "Pay": {"select": "Pay", "message": "Pay"},
+ "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"},
+ "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "},
+ "PayRequest": {"select": "PayRequest", "message": "Request Payment"},
+ "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "},
+ "Delivered": {"select": "Delivered", "message": "Delivered"},
+ "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "},
+ "Order": {"select": "Order", "message": "Order From Supplier"},
+ "NoAction": {"select": "NoAction", "message": "Take No Action"},
+ "ex_button": "Execute",
+ "ca_button": "Cancel",
+ "orderno": "Order #",
+ "status": "Status",
+ "total": "Total",
+ "seller": "Seller: ",
+ "itemno": "Item Number",
+ "description": "Description",
+ "qty": "Quantity",
+ "price": "Price",
+ "processing_msg": "Processing {0} request for order number: {1}",
+ "b_no_order_msg": "No orders for this buyer: ",
+ "s_no_order_msg": "No orders for this seller: ",
+ "p_no_order_msg": "No orders for this provider: ",
+ "sh_no_order_msg": "No orders for this shipper: ",
+ "create_msg": "Processing Create Order request",
+ "buyer": "Buyer: "
+ },
+ "financeCoOrder": {
+ "status": "Current Status: ",
+ "action": "Action",
+ "by": "By",
+ "date": "Date",
+ "comments": "Comments",
+ "created": "Created",
+ "cancelled": "Cancelled?",
+ "notCancel": "(not Cancelled)",
+ "purchased": "Purchased",
+ "noPurchase": "(no Purchase Request)",
+ "thirdParty": "3rd Party Order",
+ "nothirdParty": "(not yet sent to 3rd Party)",
+ "backordered": "Backordered?",
+ "notBackordered": "(not Backordered)",
+ "shippingRequested": "Shipping Requested",
+ "noRequestShip": "(No Request to Shipper)",
+ "shippingStarted": "Shipping Started",
+ "noDeliveryStart": "(Delivery not Started)",
+ "delivered": "Delivered",
+ "notDelivered": "(not yet Delivered)",
+ "payRequested": "Payment Requested",
+ "noRequest": "(no request for payment)",
+ "disputed": "Dispute Raised",
+ "noDispute": "(not in Dispute)"
+ }
}
-}
+
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/text/es-LA/prompts.json b/Chapter05/controller/restapi/features/text/es-LA/prompts.json
index 59afa66..ec3dfb4 100644
--- a/Chapter05/controller/restapi/features/text/es-LA/prompts.json
+++ b/Chapter05/controller/restapi/features/text/es-LA/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language":"LA Español",
- "title":"Z2B Capítulo 5",
- "header":"Capítulo 5: Construyendo la experiencia del usuario administrativa",
- "titleBar":"Cero al tutorial de Blockchain",
- "idx_unified":"Cargar experiencia de usuario unificada",
- "idx_buyer":"Cargar la experiencia del usuario del comprador",
- "idx_seller":"Cargar experiencia de usuario del vendedor",
- "idx_provider":"Cargar experiencia de usuario del proveedor",
- "idx_shipper":"Cargar experiencia de usuario del transportista",
- "idx_financeco":"Cargar experiencia de usuario de la compañía financiera",
- "idx_roles":"Roles",
- "idx_admin":"Administrador",
- "idx_adminUX":"Cargar experiencia de usuario del administrador",
- "idx_preload":"Precardar red"
- },
- "admin": {
- "title":"Cero al tutorial de Blockchain Capítulo 05",
- "npm":"Administración del perfil de redes",
- "npm_API":"API",
- "npm_param":"Parámetros",
- "npm_dp_api":"borrar perfil",
- "npm_dp_param":"nombre del perfil ",
- "npm_cp_api":"crear perfil",
- "npm_cp_param":"objeto de perfil",
- "npm_ga_api":"obtener todos los perfiles de conexión",
- "npm_ga_param":"(ninguno)",
- "npm_g1_api":"conseguor un perfil de red de conexión espécífico",
- "npm_g1_param":"nombre del perfil ",
- "bnm":"Administrador de red de negocios",
- "bnm_param":"Parámetros",
- "bnm_api":"API",
- "bnm_nd_api":"desplegar una red",
- "bnm_nd_param":"archivo de red, opciones",
- "bnm_ni_api":"instalar una nueva red",
- "bnm_ni_param":"archivo de red, opciones",
- "bnm_ns_api":"iniciar una red instalada",
- "bnm_ns_param":"nombre de la red, opciones",
- "bnm_nl_api":"enumerar las redes empresariales desplegadas",
- "bnm_nl_param":"(ninguna)",
- "bnm_np_api":"toca una red, comprueba la compatibilidad",
- "bnm_np_param":"nombre de la red comercial",
- "bnm_nu_api":"tomar una red de negocios fuera de línea",
- "bnm_nu_param":"nombre de la red comercial <",
- "bnm_nuu_api":"actualizar una red comercial existente",
- "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento",
- "rm":"Administracion de recursos",
- "rm_api":"API",
- "rm_param":"Parámetros",
- "rm_lr_api":"listar miembros de un registro",
- "rm_la_api":"Lista de activos en el registro",
- "rm_la_param":"(ninguna)",
- "rm_am_api":"Añadir miembro",
- "rm_am_param":"Co Nombre, id, Tipo",
- "rm_rm_api":"Eliminar miembro",
- "rm_gs_api":"obtenerMiembroSecreto",
- "bc":"BlockChain",
- "bc_api":"API",
- "bc_param":"Parámetros",
- "bc_gi_api":"iniciar la conexión a blockchain",
- "bc_gi_param":"(ninguna)",
- "bc_ge_api":"registrarse para eventos blockchain",
- "bc_ge_param":"(ninguna)",
- "bc_gh_api":"obtener un historiador",
- "bc_gh_param":"(ninguna)"
- },
- "buyer": {
- "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:",
- "newOrder":"Crear nuevo orden",
- "orderStatus":"Mostrar estado del pedido"
- },
- "createConnectionProfile": {
- "title":"tipo de nombre para un nuevo perfil aquí:",
- "cp_type":"tipo",
- "cp_orderers":"solicitantes",
- "cp_orderers_url":"Localizador Uniforme de Recursos (url)",
- "cp_ca":"ca",
- "cp_ca_url":"Localizador Uniforme de Recursos (url)",
- "cp_ca_name":"nombre",
- "cp_peers":"semejantes",
- "cp_peers_event_url":"eventoURL",
- "cp_peers_request_url":"requerirURL",
- "cp_keyValStore":"keyValStore",
- "cp_channel":"canal",
- "cp_mspID":"mspID",
- "cp_timeout":"tiempofuera",
- "cancel":"Cancelar",
- "submit":"Someter"
- },
- "createMember": {
- "cd_type":"Tipo",
- "cd_buyer":"Comprador",
- "cd_seller":"Vendedor",
- "cd_shipper":"Expedidor",
- "cd_provider":"Proveedor",
- "cd_financeco":"Compañía financiera",
- "cd_cn":"nombre de empresa",
- "cd_e":"dirección de correo electrónico",
- "cancelNewOrder":"Cancelar",
- "submitNewOrder":"Enviar"
- },
- "createOrder": {
- "title":"Crear nueva orden",
- "selectVendor":"Seleccionar proveedor:",
- "cn_on":"Número de orden",
- "cn_status":"Estado",
- "cn_date":"Fecha",
- "cn_total":"Total",
- "cn_selectItem":"Seleccione un artículo",
- "addItem":"Añadir artículo",
- "cancelNewOrder":"Cancelar",
- "submitNewOrder":"Enviar"
- },
- "deleteConnectionProfile": {
- "title":"Seleccionar perfil para eliminar:",
- "cancel":"Cancelar",
- "submit":"Enviar"
- },
- "financeCo": {
- "title":"Cero a Blockchain Capítulo 10: El financiero global",
- "financeCOclear":"Ventana limpia",
- "financeCOorderStatus":"Mostrar estado del pedido"
- },
- "getMemberSecret": {
- "gs_type":"Tipo",
- "gs_members":"Miembros",
- "gs_company":"nombre de empresa",
- "gs_email":"dirección de correo electrónico",
- "gs_userID":"identidad de usuario",
- "gs_secret":"secreto",
- "cancel":"Cancelar",
- "submit":"Enviar"
- },
- "provider": {
- "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:",
- "provider_clear":"Ventana limpia",
- "providerOrderStatus":"Mostrar estado del pedido"
- },
- "removeMember": {
- "rm_type":"Tipo",
- "rm_members":"Miembros",
- "rm_company":"nombre de empresa",
- "rm_email":"dirección de correo electrónico",
- "rm_userID":"identidad de usuario",
- "rm_secret":"secreto",
- "cancel":"Cancelar",
- "submit":"Enviar"
- },
- "seller": {
- "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:",
- "seller_clear":"Ventana limpia",
- "sellerOrderStatus":"Mostrar estado del pedido"
- },
- "shipper": {
- "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:",
- "shipper_clear":"Ventana limpia",
- "shipperOrderStatus":"Mostrar estado del pedido"
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"},
- "Dispute": {"select": "Disputa","message":"Disputa"},
- "Resolve": {"select": "Resolver","message":"Resolver"},
- "Purchase": {"select": "Compra","message":"Compra"},
- "Cancel": {"select": "Cancelar","message":"Cancelar"},
- "Pay": {"select": "Paga","message":"Paga"},
- "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"},
- "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"},
- "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"},
- "Refund": {"select": "Reembolso","message":"Reembolso"},
- "Delivered": {"select": "Entregado","message":"Entregado"},
- "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"},
- "Order": {"select": "Orden","message":"Ordene del proveedor"},
- "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"},
- "ex_button":"Ejecutar",
- "ca_button":"Cancelar",
- "orderno":"Orden #",
- "status":"Estado",
- "total":"Total",
- "seller":"Vendedor:",
- "itemno":"Número de artículo",
- "description":"Descripción",
- "qty":"Cantidad",
- "price":"Precio",
- "processing_msg":"Procesando {0} solicitud de número de pedido: {1}",
- "b_no_order_msg":"No hay pedidos para este comprador:",
- "s_no_order_msg":"No hay pedidos para este vendedor:",
- "p_no_order_msg":"No hay pedidos para este proveedor:",
- "sh_no_order_msg":"No hay pedidos para este remitente:",
- "create_msg":"Procesando Crear solicitud de pedido",
- "buyer":"Comprador:"
- },
- "financeCoOrder": {
- "status":"Estatus actual",
- "action":"Acción",
- "by":"Por",
- "date":"Fecha",
- "comments":"Comentarios",
- "created":"Creado",
- "cancelled":"Cancelado",
- "notCancel":"(no cancelado)",
- "purchased":"Comprado",
- "noPurchase":"(no hay orden de compra)",
- "thirdParty":"Orden de un tercero",
- "nothirdParty":"(no se ha enviado a un tercero)",
- "backordered":"¿Atrasado?",
- "notBackordered":"(no atrasado)",
- "shippingRequested":"Embarque requerido",
- "noRequestShip":"(No hay requerimiento al transportista)",
- "shippingStarted":"Embarque iniciado",
- "noDeliveryStart":"(No ha comenzado la entrega)",
- "delivered":"Entregado",
- "notDelivered":"(no ha sido entregado)",
- "payRequested":"Pago requerido",
- "noRequest":"(no se ha solicitado el pago)",
- "disputed":"Disputa planteada",
- "noDispute":"(no en disputa)"
- }
- }
\ No newline at end of file
+ "index": {"language":"LA Español",
+ "title":"Z2B Capítulo 5",
+ "header":"Capítulo 5: Construyendo la experiencia del usuario administrativa",
+ "titleBar":"Cero al tutorial de Blockchain",
+ "idx_unified":"Cargar experiencia de usuario unificada",
+ "idx_buyer":"Cargar la experiencia del usuario del comprador",
+ "idx_seller":"Cargar experiencia de usuario del vendedor",
+ "idx_provider":"Cargar experiencia de usuario del proveedor",
+ "idx_shipper":"Cargar experiencia de usuario del transportista",
+ "idx_financeco":"Cargar experiencia de usuario de la compañía financiera",
+ "idx_roles":"Roles",
+ "idx_admin":"Administrador",
+ "idx_adminUX":"Cargar experiencia de usuario del administrador",
+ "idx_preload":"Precardar red"
+ },
+ "admin": {
+ "title":"Cero al tutorial de Blockchain Capítulo 05",
+ "npm":"Administración del perfil de redes",
+ "npm_API":"API",
+ "npm_param":"Parámetros",
+ "npm_dp_api":"borrar perfil",
+ "npm_dp_param":"nombre del perfil ",
+ "npm_cp_api":"crear perfil",
+ "npm_cp_param":"objeto de perfil",
+ "npm_ga_api":"obtener todos los perfiles de conexión",
+ "npm_ga_param":"(ninguno)",
+ "npm_g1_api":"conseguor un perfil de red de conexión espécífico",
+ "npm_g1_param":"nombre del perfil ",
+ "bnm":"Administrador de red de negocios",
+ "bnm_param":"Parámetros",
+ "bnm_api":"API",
+ "bnm_nd_api":"desplegar una red",
+ "bnm_nd_param":"archivo de red, opciones",
+ "bnm_ni_api":"instalar una nueva red",
+ "bnm_ni_param":"archivo de red, opciones",
+ "bnm_ns_api":"iniciar una red instalada",
+ "bnm_ns_param":"nombre de la red, opciones",
+ "bnm_nl_api":"enumerar las redes empresariales desplegadas",
+ "bnm_nl_param":"(ninguna)",
+ "bnm_np_api":"toca una red, comprueba la compatibilidad",
+ "bnm_np_param":"nombre de la red comercial",
+ "bnm_nu_api":"tomar una red de negocios fuera de línea",
+ "bnm_nu_param":"nombre de la red comercial <",
+ "bnm_nuu_api":"actualizar una red comercial existente",
+ "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento",
+ "rm":"Administracion de recursos",
+ "rm_api":"API",
+ "rm_param":"Parámetros",
+ "rm_lr_api":"listar miembros de un registro",
+ "rm_la_api":"Lista de activos en el registro",
+ "rm_la_param":"(ninguna)",
+ "rm_am_api":"Añadir miembro",
+ "rm_am_param":"Co Nombre, id, Tipo",
+ "rm_rm_api":"Eliminar miembro",
+ "rm_gs_api":"obtenerMiembroSecreto",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"verificar si existe una tarjeta de identidad",
+ "rm_cc2_api": "crear una tarjeta de identidad",
+ "bc":"BlockChain",
+ "bc_api":"API",
+ "bc_param":"Parámetros",
+ "bc_gi_api":"iniciar la conexión a blockchain",
+ "bc_gi_param":"(ninguna)",
+ "bc_ge_api":"registrarse para eventos blockchain",
+ "bc_ge_param":"(ninguna)",
+ "bc_gh_api":"obtener un historiador",
+ "bc_gh_param":"(ninguna)"
+ },
+ "buyer": {
+ "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:",
+ "newOrder":"Crear nuevo orden",
+ "orderStatus":"Mostrar estado del pedido"
+ },
+ "createConnectionProfile": {
+ "title":"tipo de nombre para un nuevo perfil aquí:",
+ "cp_type":"tipo",
+ "cp_orderers":"solicitantes",
+ "cp_orderers_url":"Localizador Uniforme de Recursos (url)",
+ "cp_ca":"ca",
+ "cp_ca_url":"Localizador Uniforme de Recursos (url)",
+ "cp_ca_name":"nombre",
+ "cp_peers":"semejantes",
+ "cp_peers_event_url":"eventoURL",
+ "cp_peers_request_url":"requerirURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"canal",
+ "cp_mspID":"mspID",
+ "cp_timeout":"tiempofuera",
+ "cancel":"Cancelar",
+ "submit":"Someter"
+ },
+ "createMember": {
+ "cd_type":"Tipo",
+ "cd_buyer":"Comprador",
+ "cd_seller":"Vendedor",
+ "cd_shipper":"Expedidor",
+ "cd_provider":"Proveedor",
+ "cd_financeco":"Compañía financiera",
+ "cd_cn":"nombre de empresa",
+ "cd_e":"dirección de correo electrónico",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "createOrder": {
+ "title":"Crear nueva orden",
+ "selectVendor":"Seleccionar proveedor:",
+ "cn_on":"Número de orden",
+ "cn_status":"Estado",
+ "cn_date":"Fecha",
+ "cn_total":"Total",
+ "cn_selectItem":"Seleccione un artículo",
+ "addItem":"Añadir artículo",
+ "cancelNewOrder":"Cancelar",
+ "submitNewOrder":"Enviar"
+ },
+ "deleteConnectionProfile": {
+ "title":"Seleccionar perfil para eliminar:",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "financeCo": {
+ "title":"Cero a Blockchain Capítulo 10: El financiero global",
+ "financeCOclear":"Ventana limpia",
+ "financeCOorderStatus":"Mostrar estado del pedido"
+ },
+ "getMemberSecret": {
+ "gs_type":"Tipo",
+ "gs_members":"Miembros",
+ "gs_company":"nombre de empresa",
+ "gs_email":"dirección de correo electrónico",
+ "gs_userID":"identidad de usuario",
+ "gs_secret":"secreto",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "provider": {
+ "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:",
+ "provider_clear":"Ventana limpia",
+ "providerOrderStatus":"Mostrar estado del pedido"
+ },
+ "removeMember": {
+ "rm_type":"Tipo",
+ "rm_members":"Miembros",
+ "rm_company":"nombre de empresa",
+ "rm_email":"dirección de correo electrónico",
+ "rm_userID":"identidad de usuario",
+ "rm_secret":"secreto",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "seller": {
+ "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:",
+ "seller_clear":"Ventana limpia",
+ "sellerOrderStatus":"Mostrar estado del pedido"
+ },
+ "shipper": {
+ "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:",
+ "shipper_clear":"Ventana limpia",
+ "shipperOrderStatus":"Mostrar estado del pedido"
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"},
+ "Dispute": {"select": "Disputa","message":"Disputa"},
+ "Resolve": {"select": "Resolver","message":"Resolver"},
+ "Purchase": {"select": "Compra","message":"Compra"},
+ "Cancel": {"select": "Cancelar","message":"Cancelar"},
+ "Pay": {"select": "Paga","message":"Paga"},
+ "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"},
+ "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"},
+ "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"},
+ "Refund": {"select": "Reembolso","message":"Reembolso"},
+ "Delivered": {"select": "Entregado","message":"Entregado"},
+ "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"},
+ "Order": {"select": "Orden","message":"Ordene del proveedor"},
+ "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"},
+ "ex_button":"Ejecutar",
+ "ca_button":"Cancelar",
+ "orderno":"Orden #",
+ "status":"Estado",
+ "total":"Total",
+ "seller":"Vendedor:",
+ "itemno":"Número de artículo",
+ "description":"Descripción",
+ "qty":"Cantidad",
+ "price":"Precio",
+ "processing_msg":"Procesando {0} solicitud de número de pedido: {1}",
+ "b_no_order_msg":"No hay pedidos para este comprador:",
+ "s_no_order_msg":"No hay pedidos para este vendedor:",
+ "p_no_order_msg":"No hay pedidos para este proveedor:",
+ "sh_no_order_msg":"No hay pedidos para este remitente:",
+ "create_msg":"Procesando Crear solicitud de pedido",
+ "buyer":"Comprador:"
+ },
+ "financeCoOrder": {
+ "status":"Estatus actual",
+ "action":"Acción",
+ "by":"Por",
+ "date":"Fecha",
+ "comments":"Comentarios",
+ "created":"Creado",
+ "cancelled":"Cancelado",
+ "notCancel":"(no cancelado)",
+ "purchased":"Comprado",
+ "noPurchase":"(no hay orden de compra)",
+ "thirdParty":"Orden de un tercero",
+ "nothirdParty":"(no se ha enviado a un tercero)",
+ "backordered":"¿Atrasado?",
+ "notBackordered":"(no atrasado)",
+ "shippingRequested":"Embarque requerido",
+ "noRequestShip":"(No hay requerimiento al transportista)",
+ "shippingStarted":"Embarque iniciado",
+ "noDeliveryStart":"(No ha comenzado la entrega)",
+ "delivered":"Entregado",
+ "notDelivered":"(no ha sido entregado)",
+ "payRequested":"Pago requerido",
+ "noRequest":"(no se ha solicitado el pago)",
+ "disputed":"Disputa planteada",
+ "noDispute":"(no en disputa)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/text/fr/prompts.json b/Chapter05/controller/restapi/features/text/fr/prompts.json
index 646429e..fba1a48 100644
--- a/Chapter05/controller/restapi/features/text/fr/prompts.json
+++ b/Chapter05/controller/restapi/features/text/fr/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language":"Le Français",
- "title":"Z2B Chapitre 05",
- "header":"Chapitre 05 : Construire l'experience de l'administrateur",
- "titleBar":"Zero to Blockchain tutoriel",
- "idx_unified":"Charger l'expérience utilisateur unifiée",
- "idx_buyer":"Charger l'expérience de l'acheteur",
- "idx_seller":"Charger l'expérience du vendeur",
- "idx_provider":"Charger l'expérience du fournisseur",
- "idx_shipper":"Charger l'expérience de lexpéditeur",
- "idx_financeco":"Charger l'expérience du financier",
- "idx_roles":"Roles",
- "idx_admin":"Admin",
- "idx_adminUX":"Charger l'expérience de l'administrateur",
- "idx_preload":"Pré-charger le Réseau"
- },
- "admin": {
- "title":"Zero to Blockchain Chapitre 05",
- "npm":"Gestion profil réseau",
- "npm_API":"API",
- "npm_param":"Paramètres",
- "npm_dp_api":"Effacer le profil",
- "npm_dp_param":"Nom du profil",
- "npm_cp_api":"Créer un profil",
- "npm_cp_param":"Objet du Profil",
- "npm_ga_api":"Obtenir tous les profils de connexion",
- "npm_ga_param":"(aucun)",
- "npm_g1_api":"Obyenir un profil de connexion spécifique",
- "npm_g1_param":"Nom du profil",
- "bnm":"Gestion du Réseau d'affaire",
- "bnm_param":"Paramètres",
- "bnm_api":"API",
- "bnm_nd_api":"Déployer un réseau",
- "bnm_nd_param":"Fichier archive réseau, options",
- "bnm_ni_api":"Installer un nouveau réseau",
- "bnm_ni_param":"Fichier archive réseau, options",
- "bnm_ns_api":"Démarrer un réseau installé",
- "bnm_ns_param":"Nom du réseau, options",
- "bnm_nl_api":"Liste des réseaux d'affaire déployés",
- "bnm_nl_param":"(aucun)",
- "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité",
- "bnm_np_param":"Nom du réseau d'affaire",
- "bnm_nu_api":"Prendre un réseau d'affaire hors ligne",
- "bnm_nu_param":"Nom du réseau d'affaire<",
- "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant",
- "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive",
- "rm":"Gestion des ressources",
- "rm_api":"API",
- "rm_param":"Paramètres",
- "rm_lr_api":"Lister les membres d'un registre",
- "rm_la_api":"Lister les objets d'un registre",
- "rm_la_param":"(aucun)",
- "rm_am_api":"Ajouter un membre",
- "rm_am_param":"Co nom, id, type",
- "rm_rm_api":"Retirer membre",
- "rm_gs_api":"getmembersecret",
- "bc":"Blockchain",
- "bc_api":"API",
- "bc_param":"Paramètres",
- "bc_gi_api":"Initier la connexion à Blockchain",
- "bc_gi_param":"(aucun)",
- "bc_ge_api":"Enregistrer pour les évènements Blockchain",
- "bc_ge_param":"(aucun)",
- "bc_gh_api":"Charger l'historique",
- "bc_gh_param":"(aucun)"
- },
- "buyer": {
+ "index": {"language":"Anglais USA",
+ "title":"Z2B Chapitre 5",
+ "header":"Chapitre 5 : Construire l'experience de l'administrateur",
+ "titleBar":"Zero to Blockchain tutoriel",
+ "idx_unified":"Charger l'expérience utilisateur unifiée",
+ "idx_buyer":"Charger l'expérience de l'acheteur",
+ "idx_seller":"Charger l'expérience du vendeur",
+ "idx_provider":"Charger l'expérience du fournisseur",
+ "idx_shipper":"Charger l'expérience de lexpéditeur",
+ "idx_financeco":"Charger l'expérience du financier",
+ "idx_roles":"Roles",
+ "idx_admin":"Admin",
+ "idx_adminUX":"Charger l'expérience de l'administrateur",
+ "idx_preload":"Pré-charger le Réseau"
+ },
+ "admin": {
+ "title":"Zero to Blockchain Chapitre 05",
+ "npm":"Gestion profil réseau",
+ "npm_API":"API",
+ "npm_param":"Paramètres",
+ "npm_dp_api":"Effacer le profil",
+ "npm_dp_param":"Nom du profil",
+ "npm_cp_api":"Créer un profil",
+ "npm_cp_param":"Objet du Profil",
+ "npm_ga_api":"Obtenir tous les profils de connexion",
+ "npm_ga_param":"(aucun)",
+ "npm_g1_api":"Obyenir un profil de connexion spécifique",
+ "npm_g1_param":"Nom du profil",
+ "bnm":"Gestion du Réseau d'affaire",
+ "bnm_param":"Paramètres",
+ "bnm_api":"API",
+ "bnm_nd_api":"Déployer un réseau",
+ "bnm_nd_param":"Fichier archive réseau, options",
+ "bnm_ni_api":"Installer un nouveau réseau",
+ "bnm_ni_param":"Fichier archive réseau, options",
+ "bnm_ns_api":"Démarrer un réseau installé",
+ "bnm_ns_param":"Nom du réseau, options",
+ "bnm_nl_api":"Liste des réseaux d'affaire déployés",
+ "bnm_nl_param":"(aucun)",
+ "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité",
+ "bnm_np_param":"Nom du réseau d'affaire",
+ "bnm_nu_api":"Prendre un réseau d'affaire hors ligne",
+ "bnm_nu_param":"Nom du réseau d'affaire<",
+ "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant",
+ "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive",
+ "rm":"Gestion des ressources",
+ "rm_api":"API",
+ "rm_param":"Paramètres",
+ "rm_lr_api":"Lister les membres d'un registre",
+ "rm_la_api":"Lister les objets d'un registre",
+ "rm_la_param":"(aucun)",
+ "rm_am_api":"Ajouter un membre",
+ "rm_am_param":"Co nom, id, type",
+ "rm_rm_api":"Retirer membre",
+ "rm_gs_api":"getmembersecret",
+ "rm_ii_api":"émission d'identité",
+ "rm_cc_api":"vérifier si la carte d'identité existe",
+ "rm_cc2_api": "Créér une nouvelle carte d'identité",
+ "bc":"Blockchain",
+ "bc_api":"API",
+ "bc_param":"Paramètres",
+ "bc_gi_api":"Initier la connexion à Blockchain",
+ "bc_gi_param":"(aucun)",
+ "bc_ge_api":"Enregistrer pour les évènements Blockchain",
+ "bc_ge_param":"(aucun)",
+ "bc_gh_api":"Charger l'historique",
+ "bc_gh_param":"(aucun)"
+ },
+ "buyer": {
"title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:",
"newOrder":"Créér une nouvelle commande",
- "orderStatus":"Afficher le status des Commandes"
- },
- "createConnectionProfile": {
- "title":"Entrer le nom du nouveau profil ici:",
- "cp_type":"type",
- "cp_orderers":"Commandes",
- "cp_orderers_url":"url",
- "cp_ca":"ca",
- "cp_ca_url":"url",
- "cp_ca_name":"nom",
- "cp_peers":"pairs",
- "cp_peers_event_url":"eventURL",
- "cp_peers_request_url":"requestURL",
- "cp_keyValStore":"keyValStore",
- "cp_channel":"canal",
- "cp_mspID":"mspID",
- "cp_timeout":"timeout",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "createMember": {
- "cd_type":"Type",
- "cd_buyer":"Acheteur",
- "cd_seller":"Vendeur",
- "cd_shipper":"Expéditeur",
- "cd_provider":"Fournisseur",
- "cd_financeco":"Financeur",
- "cd_cn":"Nom Companie",
- "cd_e":"Adresse email",
- "cancelNewOrder":"Annuler",
- "submitNewOrder":"Soumettre"
- },
- "createOrder": {
- "title":"Créér un nouvel ordre",
- "selectVendor":"Selectionner fournisseur:",
- "cn_on":"Numéro de commande",
- "cn_status":"Status",
- "cn_date":"Date",
- "cn_total":"Total",
- "cn_selectItem":"Selectionner item",
- "addItem":"Ajouter item",
- "cancelNewOrder":"Annuler",
- "submitNewOrder":"Soumettre"
- },
- "deleteConnectionProfile": {
- "title":"Selectionner le profil à annuler",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "financeCo": {
+ "orderStatus":"Afficher le status des Commandes"
+ },
+ "createConnectionProfile": {
+ "title":"Entrer le nom du nouveau profil ici:",
+ "cp_type":"type",
+ "cp_orderers":"Commandes",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"nom",
+ "cp_peers":"pairs",
+ "cp_peers_event_url":"eventURL",
+ "cp_peers_request_url":"requestURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"canal",
+ "cp_mspID":"mspID",
+ "cp_timeout":"timeout",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "createMember": {
+ "cd_type":"Type",
+ "cd_buyer":"Acheteur",
+ "cd_seller":"Vendeur",
+ "cd_shipper":"Expéditeur",
+ "cd_provider":"Fournisseur",
+ "cd_financeco":"Financeur",
+ "cd_cn":"Nom Companie",
+ "cd_e":"Adresse email",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "createOrder": {
+ "title":"Créér un nouvel ordre",
+ "selectVendor":"Selectionner fournisseur:",
+ "cn_on":"Numéro de commande",
+ "cn_status":"Status",
+ "cn_date":"Date",
+ "cn_total":"Total",
+ "cn_selectItem":"Selectionner item",
+ "addItem":"Ajouter item",
+ "cancelNewOrder":"Annuler",
+ "submitNewOrder":"Soumettre"
+ },
+ "deleteConnectionProfile": {
+ "title":"Selectionner le profil à annuler",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "financeCo": {
"title":"Zero to Blockchain Chapitre 10: Le financier mondial",
"financeCOclear":"Effacer le contenu de la fenetre",
- "financeCOorderStatus":"Afficher le status des Commandes"
- },
- "getMemberSecret": {
- "gs_type":"Type",
- "gs_members":"Membres",
- "gs_company":"Nom Companie",
- "gs_email":"Adresse email",
- "gs_userID":"userID",
- "gs_secret":"secret",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "provider": {
+ "financeCOorderStatus":"Afficher le status des Commandes"
+ },
+ "getMemberSecret": {
+ "gs_type":"Type",
+ "gs_members":"Membres",
+ "gs_company":"Nom Companie",
+ "gs_email":"Adresse email",
+ "gs_userID":"userID",
+ "gs_secret":"secret",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "provider": {
"title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:",
"provider_clear":"Effacer le contenu de la fenetre",
- "providerOrderStatus":"Afficher le status des Commandes"
- },
- "removeMember": {
- "rm_type":"",
- "rm_members":"Type",
- "rm_company":"Membres",
- "rm_email":"Adresse email",
- "rm_userID":"userID",
- "rm_secret":"secret",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "seller": {
+ "providerOrderStatus":"Afficher le status des Commandes"
+ },
+ "removeMember": {
+ "rm_type":"",
+ "rm_members":"Type",
+ "rm_company":"Membres",
+ "rm_email":"Adresse email",
+ "rm_userID":"userID",
+ "rm_secret":"secret",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "seller": {
"title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:",
"seller_clear":"Effacer le contenu de la fenetre",
- "sellerOrderStatus":"Afficher le status des Commandes"
- },
- "shipper": {
+ "sellerOrderStatus":"Afficher le status des Commandes"
+ },
+ "shipper": {
"title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:",
"shipper_clear":"Effacer le contenu de la fenetre",
- "shipperOrderStatus":"Afficher le status des Commandes"
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"},
- "Dispute": {"select": "Disputer","message":"Dispute"},
- "Resolve": {"select": "Résoudre","message":"Résoudre"},
- "Purchase": {"select": "Acheter","message":"Acheter"},
- "Cancel": {"select": "Annuler","message":"Annuler"},
- "Pay": {"select": "Payer","message":"Payer"},
- "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"},
- "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"},
- "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"},
- "Refund": {"select": "Remboursement","message":"Rembourser"},
- "Delivered": {"select": "Livré","message":"Livré"},
- "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"},
- "Order": {"select": "Commande","message":"Commande du fournisseur"},
- "NoAction": {"select": "Pas d'action","message":"Pas d'action"},
- "ex_button":"Ecécuter",
- "ca_button":"Annuler",
- "orderno":"# Commande",
- "status":"Status",
- "total":"Total",
- "seller":"Vendeur:",
- "itemno":"Numero item",
- "description":"Description",
- "qty":"Quantité",
- "price":"Prix",
- "processing_msg":"Processer{0} demander le numero de commande:{1}",
- "b_no_order_msg":"Pas de commande pour cet acheteur:",
- "s_no_order_msg":"Pas de commande pour ce vendeur:",
- "p_no_order_msg":"Pas de commande pour ce fournisseur:",
- "sh_no_order_msg":"Pas de commande pour cet expéditeur:",
- "create_msg":"Création demande de commande en cours",
- "buyer":"Acheteur:"
- },
- "financeCoOrder": {
- "status":"Status actuel:",
- "action":"Action",
- "by":"Par",
- "date":"Date",
- "comments":"Commentaires",
- "created":"Créé",
- "cancelled":"Annulé?",
- "notCancel":"(non annulé)",
- "purchased":"Acheté",
- "noPurchase":"(pas de demande de commande)",
- "thirdParty":"Commande de partie tierce",
- "nothirdParty":"(pas encire envoyé à partie tierce)",
- "backordered":"Rupture de stock?",
- "notBackordered":"(pas de rupture de stock)",
- "shippingRequested":"Expédition demandée",
- "noRequestShip":"(pas de demande à l'expéditeur)",
- "shippingStarted":"Expédition en cours",
- "noDeliveryStart":"(expédition en attente)",
- "delivered":"Livré",
- "notDelivered":"(pas encore livré)",
- "payRequested":"Paiement demandé",
- "noRequest":"(paiement pas encore demandé)",
- "disputed":"Dispute lancée",
- "noDispute":"(pas de dispute)"
- }
- }
\ No newline at end of file
+ "shipperOrderStatus":"Afficher le status des Commandes"
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"},
+ "Dispute": {"select": "Disputer","message":"Dispute"},
+ "Resolve": {"select": "Résoudre","message":"Résoudre"},
+ "Purchase": {"select": "Acheter","message":"Acheter"},
+ "Cancel": {"select": "Annuler","message":"Annuler"},
+ "Pay": {"select": "Payer","message":"Payer"},
+ "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"},
+ "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"},
+ "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"},
+ "Refund": {"select": "Remboursement","message":"Rembourser"},
+ "Delivered": {"select": "Livré","message":"Livré"},
+ "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"},
+ "Order": {"select": "Commande","message":"Commande du fournisseur"},
+ "NoAction": {"select": "Pas d'action","message":"Pas d'action"},
+ "ex_button":"Ecécuter",
+ "ca_button":"Annuler",
+ "orderno":"# Commande",
+ "status":"Status",
+ "total":"Total",
+ "seller":"Vendeur:",
+ "itemno":"Numero item",
+ "description":"Description",
+ "qty":"Quantité",
+ "price":"Prix",
+ "processing_msg":"Processer(0) demander le numero de commande:(1)",
+ "b_no_order_msg":"Pas de commande pour cet acheteur:",
+ "s_no_order_msg":"Pas de commande pour ce vendeur:",
+ "p_no_order_msg":"Pas de commande pour ce fournisseur:",
+ "sh_no_order_msg":"Pas de commande pour cet expéditeur:",
+ "create_msg":"Création demande de commande en cours",
+ "buyer":"Acheteur:"
+ },
+ "financeCoOrder": {
+ "status":"Status actuel:",
+ "action":"Action",
+ "by":"Par",
+ "date":"Date",
+ "comments":"Commentaires",
+ "created":"Créé",
+ "cancelled":"Annulé?",
+ "notCancel":"(non annulé)",
+ "purchased":"Acheté",
+ "noPurchase":"(pas de demande de commande)",
+ "thirdParty":"Commande de partie tierce",
+ "nothirdParty":"(pas encire envoyé à partie tierce)",
+ "backordered":"Rupture de stock?",
+ "notBackordered":"(pas de rupture de stock)",
+ "shippingRequested":"Expédition demandée",
+ "noRequestShip":"(pas de demande à l'expéditeur)",
+ "shippingStarted":"Expédition en cours",
+ "noDeliveryStart":"(expédition en attente)",
+ "delivered":"Livré",
+ "notDelivered":"(pas encore livré)",
+ "payRequested":"Paiement demandé",
+ "noRequest":"(paiement pas encore demandé)",
+ "disputed":"Dispute lancée",
+ "noDispute":"(pas de dispute)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/text/jp/prompts.json b/Chapter05/controller/restapi/features/text/jp/prompts.json
index eadeb56..34a6a9e 100644
--- a/Chapter05/controller/restapi/features/text/jp/prompts.json
+++ b/Chapter05/controller/restapi/features/text/jp/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language":"米国英語",
- "title":"Z2B 弟 5章",
- "header":"弟 5章: 管理ユーザー経験の構築",
- "titleBar":"Zero to Blockchainチュートリアル",
- "idx_unified":"統合ユーザー経験のロード",
- "idx_buyer":"購入者ユーザー経験のロード",
- "idx_seller":"販売者ユーザー経験のロード",
- "idx_provider":"プロバイダユーユーザー経験のロード",
- "idx_shipper":"荷送人ユーザー経験のロード",
- "idx_financeco":"財務会社ユーザー経験のロード",
- "idx_roles":"役割",
- "idx_admin":"管理者",
- "idx_adminUX":"管理者ユーザー経験のロード",
- "idx_preload":"事前ロードネットワーク"
- },
- "admin": {
- "title":"Zero To Blockchain 弟05章",
- "npm":"ネットワークプロファイル管理",
- "npm_API":"API",
- "npm_param":"パラメーター",
- "npm_dp_api":"プロフィールの削除",
- "npm_dp_param":"プロフィール名",
- "npm_cp_api":"プロフィールの作成",
- "npm_cp_param":"プロファイルオブジェクト",
- "npm_ga_api":"すべての接続プロファイルの取得",
- "npm_ga_param":"(なし)",
- "npm_g1_api":"特定のネットワーク接続プロファイルの取得",
- "npm_g1_param":"プロフィール名",
- "bnm":"ビジネスネットワーク管理",
- "bnm_param":"パラメーター",
- "bnm_api":"API",
- "bnm_nd_api":"ネットワークの展開",
- "bnm_nd_param":"ネットワークアーカイブファイル、オプション",
- "bnm_ni_api":"新規ネットワークのインストールする",
- "bnm_ni_param":"ネットワークアーカイブファイル、オプション",
- "bnm_ns_api":"インストールされたネットワークの開始",
- "bnm_ns_param":"ネットワーク名、オプション",
- "bnm_nl_api":"展開されたビジネスネットワークの一覧表示",
- "bnm_nl_param":"(なし)",
- "bnm_np_api":"ネットワークに触れる、互換性をチェックする",
- "bnm_np_param":"ビジネスネットワーク名",
- "bnm_nu_api":"ビジネスネットワークをオフラインにする",
- "bnm_nu_param":"ビジネスネットワーク名<",
- "bnm_nuu_api":"既存のビジネスネットワークの更新",
- "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル",
- "rm":"リソース管理",
- "rm_api":"API",
- "rm_param":"パラメーター",
- "rm_lr_api":"レジストリのメンバーの一覧表示",
- "rm_la_api":"レジストリのリストアセット",
- "rm_la_param":"(なし)",
- "rm_am_api":"メンバーの追加",
- "rm_am_param":"Co 名, id, タイプ",
- "rm_rm_api":"メンバーの削除",
- "rm_gs_api":"メンバーシークレットの取得",
- "bc":"ブロックチェーン",
- "bc_api":"API",
- "bc_param":"パラメーター",
- "bc_gi_api":"ブロックチェーンへの接続の開始",
- "bc_gi_param":"(なし)",
- "bc_ge_api":"ブロックチェーンイベントの登録",
- "bc_ge_param":"(なし)",
- "bc_gh_api":"歴史家の取得",
- "bc_gh_param":"(なし)"
- },
- "buyer": {
- "title":"購入者弟06章. 購入者を選択してビューの表示: ",
- "newOrder":"新規発注の作成",
- "orderStatus":"発注状況の表示"
- },
- "createConnectionProfile": {
- "title":"ここに新しいプロファイルの名前を入力してください: ",
- "cp_type":"タイプ",
- "cp_orderers":"発注者",
- "cp_orderers_url":"url",
- "cp_ca":"ca",
- "cp_ca_url":"url",
- "cp_ca_name":"名",
- "cp_peers":"同僚",
- "cp_peers_event_url":"イベントURL",
- "cp_peers_request_url":"依頼URL",
- "cp_keyValStore":"keyValStore",
- "cp_channel":"チャネル",
- "cp_mspID":"mspID",
- "cp_timeout":"タイムアウト",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "createMember": {
- "cd_type":"タイプ",
- "cd_buyer":"購入者",
- "cd_seller":"販売者",
- "cd_shipper":"荷送人",
- "cd_provider":"プロバイダ",
- "cd_financeco":"財務会社",
- "cd_cn":"会社名",
- "cd_e":"e-メールアドレス",
- "cancelNewOrder":"キャンセル",
- "submitNewOrder":"提出"
- },
- "createOrder": {
- "title":"新規発注の作成",
- "selectVendor":"ベンダーの選択: ",
- "cn_on":"発注番号",
- "cn_status":"状態",
- "cn_date":"日付",
- "cn_total":"合計",
- "cn_selectItem":"アイテムの選択",
- "addItem":"アイテムの追加",
- "cancelNewOrder":"キャンセル",
- "submitNewOrder":"提出"
- },
- "deleteConnectionProfile": {
- "title":"削除するプロファイルの選択: ",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "financeCo": {
- "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー",
- "financeCOclear":"ウィンドウのクリア",
- "financeCOorderStatus":"発注状況の表示"
- },
- "getMemberSecret": {
- "gs_type":"タイプ",
- "gs_members":"メンバー",
- "gs_company":"会社名",
- "gs_email":"e-メールアドレス",
- "gs_userID":"ユーザーID",
- "gs_secret":"シークレット",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "provider": {
- "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ",
- "provider_clear":"ウィンドウのクリア",
- "providerOrderStatus":"発注状況の表示"
- },
- "removeMember": {
- "rm_type":"タイプ",
- "rm_members":"メンバー",
- "rm_company":"会社名",
- "rm_email":"e-メールアドレス",
- "rm_userID":"ユーザーID",
- "rm_secret":"シークレット",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "seller": {
- "title":"販売者弟07章, 販売者を選択してビューの表示: ",
- "seller_clear":"ウィンドウのクリア",
- "sellerOrderStatus":"発注状況の表示"
- },
- "shipper": {
- "title":"荷送人弟09章, 荷送人を選択してビューの表示: ",
- "shipper_clear":"ウィンドウのクリア",
- "shipperOrderStatus":"発注状況の表示 "
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"},
- "Dispute": {"select": "紛争","message":"紛争"},
- "Resolve": {"select": "解決","message":"解決"},
- "Purchase": {"select": "購入","message":"購入"},
- "Cancel": {"select": "キャンセル","message":"キャンセル"},
- "Pay": {"select": "支払い","message":"支払い"},
- "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"},
- "BackOrder": {"select": "バックワード","message":"バックワード"},
- "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"},
- "Refund": {"select": "払い戻し","message":"払い戻し"},
- "Delivered": {"select": "配信されました","message":"配信されました"},
- "Delivering": {"select": "配信されています","message":"配信状況の更新"},
- "Order": {"select": "発注","message":"サプライヤからの発注"},
- "NoAction": {"select": "アクションがありません","message":"何もしない"},
- "ex_button":"実行",
- "ca_button":"キャンセル",
- "orderno":"発注 #",
- "status":"状態",
- "total":"合計",
- "seller":"販売者: ",
- "itemno":"アイテム番号",
- "description":"説明",
- "qty":"数量",
- "price":"価格",
- "processing_msg":"発注番号の処理{0}依頼:{1}",
- "b_no_order_msg":"本購入者の発注はありません: ",
- "s_no_order_msg":"本販売者の発注はありません: ",
- "p_no_order_msg":"本プロバイダの発注はありません: ",
- "sh_no_order_msg":"本荷送人の発注はありません: ",
- "create_msg":"発注の作成の処理",
- "buyer":"購入者: "
- },
- "financeCoOrder": {
- "status":"現在の状態: ",
- "action":"アクション",
- "by":"から",
- "date":"日付",
- "comments":"コメント",
- "created":"作成されました",
- "cancelled":"キャンセルされましたか?",
- "notCancel":"(キャンセルされていません)",
- "purchased":"購入されました",
- "noPurchase":"(購入依頼がありません)",
- "thirdParty":"第三者発注",
- "nothirdParty":"(まだ第三者に送られていません)",
- "backordered":"バックワードされていますか?",
- "notBackordered":"(バックワードされていません)",
- "shippingRequested":"出荷の依頼",
- "noRequestShip":"(荷送人への依頼がありません)",
- "shippingStarted":"出荷の開始",
- "noDeliveryStart":"(出荷は開始されていません)",
- "delivered":"配信されました",
- "notDelivered":"(配信されていません)",
- "payRequested":"支払いの依頼",
- "noRequest":"(支払いの依頼がありません)",
- "disputed":"紛争は申請されました",
- "noDispute":"(紛争ではありません)"
- }
- }
\ No newline at end of file
+ "index": {"language":"米国英語",
+ "title":"Z2B 弟 5章",
+ "header":"弟 5章: 管理ユーザー経験の構築",
+ "titleBar":"Zero to Blockchainチュートリアル",
+ "idx_unified":"統合ユーザー経験のロード",
+ "idx_buyer":"購入者ユーザー経験のロード",
+ "idx_seller":"販売者ユーザー経験のロード",
+ "idx_provider":"プロバイダユーユーザー経験のロード",
+ "idx_shipper":"荷送人ユーザー経験のロード",
+ "idx_financeco":"財務会社ユーザー経験のロード",
+ "idx_roles":"役割",
+ "idx_admin":"管理者",
+ "idx_adminUX":"管理者ユーザー経験のロード",
+ "idx_preload":"事前ロードネットワーク"
+ },
+ "admin": {
+ "title":"Zero To Blockchain 弟05章",
+ "npm":"ネットワークプロファイル管理",
+ "npm_API":"API",
+ "npm_param":"パラメーター",
+ "npm_dp_api":"プロフィールの削除",
+ "npm_dp_param":"プロフィール名",
+ "npm_cp_api":"プロフィールの作成",
+ "npm_cp_param":"プロファイルオブジェクト",
+ "npm_ga_api":"すべての接続プロファイルの取得",
+ "npm_ga_param":"(なし)",
+ "npm_g1_api":"特定のネットワーク接続プロファイルの取得",
+ "npm_g1_param":"プロフィール名",
+ "bnm":"ビジネスネットワーク管理",
+ "bnm_param":"パラメーター",
+ "bnm_api":"API",
+ "bnm_nd_api":"ネットワークの展開",
+ "bnm_nd_param":"ネットワークアーカイブファイル、オプション",
+ "bnm_ni_api":"新規ネットワークのインストールする",
+ "bnm_ni_param":"ネットワークアーカイブファイル、オプション",
+ "bnm_ns_api":"インストールされたネットワークの開始",
+ "bnm_ns_param":"ネットワーク名、オプション",
+ "bnm_nl_api":"展開されたビジネスネットワークの一覧表示",
+ "bnm_nl_param":"(なし)",
+ "bnm_np_api":"ネットワークに触れる、互換性をチェックする",
+ "bnm_np_param":"ビジネスネットワーク名",
+ "bnm_nu_api":"ビジネスネットワークをオフラインにする",
+ "bnm_nu_param":"ビジネスネットワーク名<",
+ "bnm_nuu_api":"既存のビジネスネットワークの更新",
+ "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル",
+ "rm":"リソース管理",
+ "rm_api":"API",
+ "rm_param":"パラメーター",
+ "rm_lr_api":"レジストリのメンバーの一覧表示",
+ "rm_la_api":"レジストリのリストアセット",
+ "rm_la_param":"(なし)",
+ "rm_am_api":"メンバーの追加",
+ "rm_am_param":"Co 名, id, タイプ",
+ "rm_rm_api":"メンバーの削除",
+ "rm_gs_api":"メンバーシークレットの取得",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Check if card exists",
+ "rm_cc2_api": "Create Card",
+ "bc":"ブロックチェーン",
+ "bc_api":"API",
+ "bc_param":"パラメーター",
+ "bc_gi_api":"ブロックチェーンへの接続の開始",
+ "bc_gi_param":"(なし)",
+ "bc_ge_api":"ブロックチェーンイベントの登録",
+ "bc_ge_param":"(なし)",
+ "bc_gh_api":"歴史家の取得",
+ "bc_gh_param":"(なし)"
+ },
+ "buyer": {
+ "title":"購入者弟06章. 購入者を選択してビューの表示: ",
+ "newOrder":"新規発注の作成",
+ "orderStatus":"発注状況の表示"
+ },
+ "createConnectionProfile": {
+ "title":"ここに新しいプロファイルの名前を入力してください: ",
+ "cp_type":"タイプ",
+ "cp_orderers":"発注者",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"名",
+ "cp_peers":"同僚",
+ "cp_peers_event_url":"イベントURL",
+ "cp_peers_request_url":"依頼URL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"チャネル",
+ "cp_mspID":"mspID",
+ "cp_timeout":"タイムアウト",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "createMember": {
+ "cd_type":"タイプ",
+ "cd_buyer":"購入者",
+ "cd_seller":"販売者",
+ "cd_shipper":"荷送人",
+ "cd_provider":"プロバイダ",
+ "cd_financeco":"財務会社",
+ "cd_cn":"会社名",
+ "cd_e":"e-メールアドレス",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "createOrder": {
+ "title":"新規発注の作成",
+ "selectVendor":"ベンダーの選択: ",
+ "cn_on":"発注番号",
+ "cn_status":"状態",
+ "cn_date":"日付",
+ "cn_total":"合計",
+ "cn_selectItem":"アイテムの選択",
+ "addItem":"アイテムの追加",
+ "cancelNewOrder":"キャンセル",
+ "submitNewOrder":"提出"
+ },
+ "deleteConnectionProfile": {
+ "title":"削除するプロファイルの選択: ",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "financeCo": {
+ "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー",
+ "financeCOclear":"ウィンドウのクリア",
+ "financeCOorderStatus":"発注状況の表示"
+ },
+ "getMemberSecret": {
+ "gs_type":"タイプ",
+ "gs_members":"メンバー",
+ "gs_company":"会社名",
+ "gs_email":"e-メールアドレス",
+ "gs_userID":"ユーザーID",
+ "gs_secret":"シークレット",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "provider": {
+ "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ",
+ "provider_clear":"ウィンドウのクリア",
+ "providerOrderStatus":"発注状況の表示"
+ },
+ "removeMember": {
+ "rm_type":"タイプ",
+ "rm_members":"メンバー",
+ "rm_company":"会社名",
+ "rm_email":"e-メールアドレス",
+ "rm_userID":"ユーザーID",
+ "rm_secret":"シークレット",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "seller": {
+ "title":"販売者弟07章, 販売者を選択してビューの表示: ",
+ "seller_clear":"ウィンドウのクリア",
+ "sellerOrderStatus":"発注状況の表示"
+ },
+ "shipper": {
+ "title":"荷送人弟09章, 荷送人を選択してビューの表示: ",
+ "shipper_clear":"ウィンドウのクリア",
+ "shipperOrderStatus":"発注状況の表示 "
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"},
+ "Dispute": {"select": "紛争","message":"紛争"},
+ "Resolve": {"select": "解決","message":"解決"},
+ "Purchase": {"select": "購入","message":"購入"},
+ "Cancel": {"select": "キャンセル","message":"キャンセル"},
+ "Pay": {"select": "支払い","message":"支払い"},
+ "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"},
+ "BackOrder": {"select": "バックワード","message":"バックワード"},
+ "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"},
+ "Refund": {"select": "払い戻し","message":"払い戻し"},
+ "Delivered": {"select": "配信されました","message":"配信されました"},
+ "Delivering": {"select": "配信されています","message":"配信状況の更新"},
+ "Order": {"select": "発注","message":"サプライヤからの発注"},
+ "NoAction": {"select": "アクションがありません","message":"何もしない"},
+ "ex_button":"実行",
+ "ca_button":"キャンセル",
+ "orderno":"発注 #",
+ "status":"状態",
+ "total":"合計",
+ "seller":"販売者: ",
+ "itemno":"アイテム番号",
+ "description":"説明",
+ "qty":"数量",
+ "price":"価格",
+ "processing_msg":"発注番号の処理{0}依頼:{1}",
+ "b_no_order_msg":"本購入者の発注はありません: ",
+ "s_no_order_msg":"本販売者の発注はありません: ",
+ "p_no_order_msg":"本プロバイダの発注はありません: ",
+ "sh_no_order_msg":"本荷送人の発注はありません: ",
+ "create_msg":"発注の作成の処理",
+ "buyer":"購入者: "
+ },
+ "financeCoOrder": {
+ "status":"現在の状態: ",
+ "action":"アクション",
+ "by":"から",
+ "date":"日付",
+ "comments":"コメント",
+ "created":"作成されました",
+ "cancelled":"キャンセルされましたか?",
+ "notCancel":"(キャンセルされていません)",
+ "purchased":"購入されました",
+ "noPurchase":"(購入依頼がありません)",
+ "thirdParty":"第三者発注",
+ "nothirdParty":"(まだ第三者に送られていません)",
+ "backordered":"バックワードされていますか?",
+ "notBackordered":"(バックワードされていません)",
+ "shippingRequested":"出荷の依頼",
+ "noRequestShip":"(荷送人への依頼がありません)",
+ "shippingStarted":"出荷の開始",
+ "noDeliveryStart":"(出荷は開始されていません)",
+ "delivered":"配信されました",
+ "notDelivered":"(配信されていません)",
+ "payRequested":"支払いの依頼",
+ "noRequest":"(支払いの依頼がありません)",
+ "disputed":"紛争は申請されました",
+ "noDispute":"(紛争ではありません)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/text/languages.json b/Chapter05/controller/restapi/features/text/languages.json
index 91b0348..8ee6b21 100644
--- a/Chapter05/controller/restapi/features/text/languages.json
+++ b/Chapter05/controller/restapi/features/text/languages.json
@@ -6,6 +6,6 @@
"French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"},
"Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"},
"Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"},
- "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"}
+ "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"}
}
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/features/text/pt/prompts.json b/Chapter05/controller/restapi/features/text/pt/prompts.json
index 4a3c1db..7b6427e 100644
--- a/Chapter05/controller/restapi/features/text/pt/prompts.json
+++ b/Chapter05/controller/restapi/features/text/pt/prompts.json
@@ -1,7 +1,222 @@
{
- "index": {"language": "Português do Brasi",
- "title": "Saiba Bluemix agora!",
- "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app",
- "titleBar": "Zero de déficit cognitivo Tutorial",
- "speech": "Falei a saída vai aqui"}
-}
+ "index": {"language":"Inglês Americano",
+ "title":"Z2B Capítulo 5",
+ "header":"Capítulo 5: Construindo a Experiência de Usuário Administrativo",
+ "titleBar":"Tutorial Zero to Blockchain",
+ "idx_unified":"carregar a Experiência de Usuário Unificado",
+ "idx_buyer":"carregar a Experiência de Usuário Consumidor",
+ "idx_seller":"carregar a Experiência de Usuário Vendedor",
+ "idx_provider":"carregar a Experiência de Usuário Fornecedor",
+ "idx_shipper":"carregar a Experiência de Usuário Transportador",
+ "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira",
+ "idx_roles":"Cargos",
+ "idx_admin":"Administrador ",
+ "idx_adminUX":"carregar a Experiência de Usuário Administrador",
+ "idx_preload":"Carregar previamente a rede"
+ },
+ "admin": {
+ "title":"Zero to Blockchain Capítulo 5",
+ "npm":"Gerenciamento de perfil de rede",
+ "npm_API":"API",
+ "npm_param":"Parametros",
+ "npm_dp_api":"deletar perfil",
+ "npm_dp_param":"nome do perfil",
+ "npm_cp_api":"criar perfil",
+ "npm_cp_param":"objeto de perfil",
+ "npm_ga_api":"obter todos os perfis de conexão",
+ "npm_ga_param":"",
+ "npm_g1_api":"obter um perfil específico de conexão de rede",
+ "npm_g1_param":"nome do perfil",
+ "bnm":"Gerenciamento da rede de negócios",
+ "bnm_param":"Parametros",
+ "bnm_api":"API",
+ "bnm_nd_api":"implantar uma rede",
+ "bnm_nd_param":"arquivar arquivo de rede, opções",
+ "bnm_ni_api":"instalar nova rede",
+ "bnm_ni_param":"arquivar arquivo de rede, opções",
+ "bnm_ns_api":"Iniciar rede instalada",
+ "bnm_ns_param":"nome da rede, opções",
+ "bnm_nl_api":"listas de redes de negócios implantadas",
+ "bnm_nl_param":"",
+ "bnm_np_api":"toque uma rede, verifique a compatibilidade",
+ "bnm_np_param":"nome da rede de negócios",
+ "bnm_nu_api":"pegue uma rede de negócios off line",
+ "bnm_nu_param":"nome da rede de negócios",
+ "bnm_nuu_api":"atualizar rede de negócios existente",
+ "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo",
+ "rm":"Gestão de Recursos",
+ "rm_api":"API",
+ "rm_param":"Parametros",
+ "rm_lr_api":"lista membros de um registro",
+ "rm_la_api":"Lista de ativos no registro",
+ "rm_la_param":"",
+ "rm_am_api":"Adicionar Membro",
+ "rm_am_param":"Co Nome, id, Tipo",
+ "rm_rm_api":"Remover Membro",
+ "rm_gs_api":"getMemberSecret",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Verifique se o cartão de identidade existe",
+ "rm_cc2_api": "criar um documento de identidade",
+ "bc":"BlockChain",
+ "bc_api":"API",
+ "bc_param":"Parametros",
+ "bc_gi_api":"iniciar conexão com Blockchain",
+ "bc_gi_param":"",
+ "bc_ge_api":"Registro para eventos de Blockchain",
+ "bc_ge_param":"",
+ "bc_gh_api":"obter histórico",
+ "bc_gh_param":""
+ },
+ "buyer": {
+ "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:",
+ "newOrder":"Criar novo pedido",
+ "orderStatus":"Exibir Estatus de Pedidos"
+ },
+ "createConnectionProfile": {
+ "title":"Digite o nome de perfil novo aqui:",
+ "cp_type":"tipo",
+ "cp_orderers":"ordenadores",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"nome",
+ "cp_peers":"colegas",
+ "cp_peers_event_url":"eventURL",
+ "cp_peers_request_url":"requestURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"canal",
+ "cp_mspID":"mspID",
+ "cp_timeout":"Tempo Esgotado",
+ "cancel":"cancelar",
+ "submit":"submeter"
+ },
+ "createMember": {
+ "cd_type":"Tipo",
+ "cd_buyer":"Consumidor",
+ "cd_seller":"Vendedor",
+ "cd_shipper":"Transportador",
+ "cd_provider":"Fornecedor",
+ "cd_financeco":"Empresa Financeira",
+ "cd_cn":"Nome da Empresa",
+ "cd_e":"Endereço de email",
+ "cancel":"Cancelar",
+ "submit":"Submeter"
+ },
+ "createOrder": {
+ "title":"Criar novo pedido",
+ "selectVendor":"Selecione Vendedor:",
+ "cn_on":"Numero do Pedido",
+ "cn_status":"Estatus",
+ "cn_date":"Data",
+ "cn_total":"Total",
+ "cn_selectItem":"Selecionar Item",
+ "addItem":"Adicionar Item",
+ "cancelNewOrder":"cancelar",
+ "submitNewOrder":"submeter"
+ },
+ "deleteConnectionProfile": {
+ "title":"Selecionar Perfil para deletar:",
+ "cancel":"cancelar",
+ "submit":"submeter"
+ },
+ "financeCo": {
+ "title":"Zero to Blockchain Capítulo 10: O Financeiro Global",
+ "financeCOclear":"Limpar Janela",
+ "financeCOorderStatus":"Exibir Estatus de Pedidos"
+ },
+ "getMemberSecret": {
+ "gs_type":"Tipo",
+ "gs_members":"Membros",
+ "gs_company":"Nome da Empresa",
+ "gs_email":"Endereço de email",
+ "gs_userID":"userID",
+ "gs_secret":"secret",
+ "cancel":"cancelar",
+ "submit":"submeter"
+ },
+ "provider": {
+ "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:",
+ "provider_clear":"Limpar Janela",
+ "providerOrderStatus":"Exibir Estatus de Pedidos"
+ },
+ "removeMember": {
+ "rm_type":"Tipo",
+ "rm_members":"Membros",
+ "rm_company":"Nome da Empresa",
+ "rm_email":"Endereço de email",
+ "rm_userID":"userID",
+ "rm_secret":"secret",
+ "cancel":"Cancelar",
+ "submit":"Submeter"
+ },
+ "seller": {
+ "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:",
+ "seller_clear":"Limpar Janela",
+ "sellerOrderStatus":"Exibir Estatus de Pedidos"
+ },
+ "shipper": {
+ "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:",
+ "shipper_clear":"Limpar Janela",
+ "shipperOrderStatus":"Exibir Estatus de Pedidos"
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"},
+ "Dispute": {"select": "Disputa","message":"Disputa"},
+ "Resolve": {"select": "Resolver","message":"Resolver"},
+ "Purchase": {"select": "Compra","message":"Compra"},
+ "Cancel": {"select": "Cancelar","message":"Cancelar"},
+ "Pay": {"select": "Pagar","message":"Pagar"},
+ "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"},
+ "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"},
+ "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"},
+ "Refund": {"select": "Reembolsar","message":"Reembolsar"},
+ "Delivered": {"select": "Entregue","message":"Entregue"},
+ "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"},
+ "Order": {"select": "Pedido","message":"Pedido do fornecedor"},
+ "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"},
+ "ex_button":"Executar",
+ "ca_button":"Cancelar",
+ "orderno":"Pedido #",
+ "status":"Estatus",
+ "total":"Total",
+ "seller":"Vendedor:",
+ "itemno":"Numero do Item",
+ "description":"Descrição",
+ "qty":"Quantidade",
+ "price":"Preço",
+ "processing_msg":"Processando {0} solicitação para o número do pedido: {1}",
+ "b_no_order_msg":"Sem pedidos para esse consumidor:",
+ "s_no_order_msg":"Sem pedidos para esse vendedor:",
+ "p_no_order_msg":"Sem pedidos para esse fornecedor:",
+ "sh_no_order_msg":"Sem pedidos para esse transportador:",
+ "create_msg":"Processando requerimento de criar pedido",
+ "buyer":"Consumidor:"
+ },
+ "financeCoOrder": {
+ "status":"Estatus Atual",
+ "action":"Ação",
+ "by":"Por",
+ "date":"Data",
+ "comments":"Comentarios",
+ "created":"Criado",
+ "cancelled":"Cancelado",
+ "notCancel":"(não cancelado)",
+ "purchased":"Comprado",
+ "noPurchase":"(sem solicitação de compra)",
+ "thirdParty":"Pedido de terceiros",
+ "nothirdParty":"(ainda não enviado para terceiros)",
+ "backordered":"Reencaminhado?",
+ "notBackordered":"(não reencaminhado)",
+ "shippingRequested":"Envio Solicitado",
+ "noRequestShip":"(sem solicitação de envio)",
+ "shippingStarted":"Envio Iniciado",
+ "noDeliveryStart":"Entrega não iniciada",
+ "delivered":"Entregue",
+ "notDelivered":"(ainda não entregue)",
+ "payRequested":"Pagamento solicitado",
+ "noRequest":"(sem solicitação de pagamento)",
+ "disputed":"Disputa levantada",
+ "noDispute":"(não em disputa)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter05/controller/restapi/router.js b/Chapter05/controller/restapi/router.js
index 02b3d35..a8e73d8 100644
--- a/Chapter05/controller/restapi/router.js
+++ b/Chapter05/controller/restapi/router.js
@@ -69,7 +69,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds);
router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles);
router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin);
router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries);
-router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin);
router.post('/composer/admin/createProfile*', hlcAdmin.createProfile);
router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile);
@@ -86,3 +85,7 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets);
router.post('/composer/admin/addMember*', hlcAdmin.addMember);
router.post('/composer/admin/removeMember*', hlcAdmin.removeMember);
router.post('/composer/admin/getSecret*', setup.getMemberSecret);
+router.post('/composer/admin/checkCard*', hlcAdmin.checkCard);
+router.post('/composer/admin/createCard*', hlcAdmin.createCard);
+router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity);
+
diff --git a/Chapter05/createArchive.sh b/Chapter05/createArchive.sh
index f7640c6..cb2371a 100755
--- a/Chapter05/createArchive.sh
+++ b/Chapter05/createArchive.sh
@@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent
showStep "creating archive"
cd ./network
-composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
\ No newline at end of file
+composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
+#
+# new create command from tutorial is following:
+# composer archive create -t dir -n .
+#
\ No newline at end of file
diff --git a/Chapter05/deployNetwork.sh b/Chapter05/deployNetwork.sh
index 9c13a36..d9042c9 100755
--- a/Chapter05/deployNetwork.sh
+++ b/Chapter05/deployNetwork.sh
@@ -80,12 +80,38 @@ showStep "deploying network"
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString
#
-# what the documentation implies is required
+# what the v0.14 documentation implies is required
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
#
-# what really works
-composer identity request -p hlfv1 -i admin -s adminpw
-composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# what really works for v0.14
+# composer identity request -p hlfv1 -i admin -s adminpw
+# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# cd network/dist
+# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+#
+# documentation for v0.15
+#
cd network/dist
-composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+showStep "installing PeerAdmin card"
+composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME
+showStep "starting network"
+# change in documentation
+# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card
+# corrected to:
+composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card
+showStep "importing networkadmin card"
+if composer card list -n admin@$NETWORK_NAME > /dev/null; then
+ composer card delete -n admin@$NETWORK_NAME
+fi
+composer card import --file networkadmin.card
+showStep "pinging admin@$NETWORK_NAME card"
+composer network ping --card admin@$NETWORK_NAME
+#
+# creating card for test program
+# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin
+# composer card import --file defaultProfile@hlfv1.card
+# showStep "pinging defaultProfile@hlfv1 card"
+# composer network ping --card defaultProfile@hlfv1
+#
+
diff --git a/Chapter05/favicon.ico b/Chapter05/favicon.ico
index 4126853..fc9e25d 100755
Binary files a/Chapter05/favicon.ico and b/Chapter05/favicon.ico differ
diff --git a/Chapter05/network/package.json b/Chapter05/network/package.json
index be89bc0..5ef56b0 100644
--- a/Chapter05/network/package.json
+++ b/Chapter05/network/package.json
@@ -36,11 +36,11 @@
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-admin": "^0.14.0",
- "composer-cli": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
+ "composer-admin": "^0.16.0",
+ "composer-cli": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
diff --git a/Chapter05/network/test/sample.js b/Chapter05/network/test/sample.js
index 1c3e3e6..4bacd5f 100644
--- a/Chapter05/network/test/sample.js
+++ b/Chapter05/network/test/sample.js
@@ -14,18 +14,11 @@
'use strict';
-const AdminConnection = require('composer-admin').AdminConnection;
-const BrowserFS = require('browserfs/dist/node/index');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
-const path = require('path');
require('chai').should();
-const network = 'zerotoblockchain-network';
-const adminID = 'admin';
-const adminPW = 'adminpw';
-const bfs_fs = BrowserFS.BFSRequire('fs');
+const _timeout = 90000;
const NS = 'org.acme.Z2BTestNetwork';
const orderNo = '12345';
const buyerID = 'billybob@email.com';
@@ -110,30 +103,12 @@ function addItems (_inbound)
return (_inbound);
}
-describe('Finance Network', () => {
-
- // let adminConnection;
+describe('Finance Network', function () {
+ this.timeout(_timeout);
let businessNetworkConnection;
-
- before(() => {
- BrowserFS.initialize(new BrowserFS.FileSystem.InMemory());
- const adminConnection = new AdminConnection({ fs: bfs_fs });
- return adminConnection.createProfile('defaultProfile', {
- type: 'embedded'
- })
- .then(() => {
- return adminConnection.connect('defaultProfile', adminID, adminPW);
- })
- .then(() => {
- return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..'));
- })
- .then((businessNetworkDefinition) => {
- return adminConnection.deploy(businessNetworkDefinition);
- })
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs });
- return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW);
- });
+ before(function () {
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect('admin@zerotoblockchain-network');
});
describe('#createOrder', () => {
diff --git a/Chapter05/package.json b/Chapter05/package.json
index 1d086ff..57535e3 100644
--- a/Chapter05/package.json
+++ b/Chapter05/package.json
@@ -17,7 +17,8 @@
"doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out",
"test-inner": "mocha -t 0 --recursive && cucumber-js",
"test-cover": "nyc npm run test-inner",
- "test": "mocha network/test --recursive -t 4000"
+ "test": "mocha network/test --recursive -t 4000",
+ "start": "node index"
},
"repository": {
"type": "git",
@@ -37,13 +38,13 @@
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
- "composer-admin": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-common": "^0.14.0",
- "composer-runtime": "^0.14.0",
- "composer-runtime-hlfv1": "^0.14.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
+ "composer-admin": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-common": "^0.16.0",
+ "composer-runtime": "^0.16.0",
+ "composer-runtime-hlfv1": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
@@ -100,6 +101,7 @@
"http": "0.0.0",
"https": "^1.0.0",
"mime": "^2.0.2",
+ "os": "^0.1.1",
"path": "^0.12.7",
"sleep": "^5.1.1",
"uuid": "^3.1.0",
diff --git a/Chapter05/startup.sh b/Chapter05/startup.sh
index 33108c7..a4602d8 100755
--- a/Chapter05/startup.sh
+++ b/Chapter05/startup.sh
@@ -1,11 +1,46 @@
#!/bin/bash
-. ../common_OSX.sh
+ YELLOW='\033[1;33m'
+ RED='\033[1;31m'
+ GREEN='\033[1;32m'
+ RESET='\033[0m'
+
+# indent text on echo
+function indent() {
+ c='s/^/ /'
+ case $(uname) in
+ Darwin) sed -l "$c";;
+ *) sed -u "$c";;
+ esac
+}
+
+# Grab the current directory
+function getCurrent()
+ {
+ showStep "getting current directory"
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+ THIS_SCRIPT=`basename "$0"`
+ showStep "Running '${THIS_SCRIPT}'"
+ }
+
+# displays where we are, uses the indent function (above) to indent each line
+function showStep ()
+ {
+ echo -e "${YELLOW}=====================================================" | indent
+ echo -e "${RESET}-----> $*" | indent
+ echo -e "${YELLOW}=====================================================${RESET}" | indent
+ }
showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}"
cd "${HLF_INSTALL_PATH}"
showStep "starting fabric"
-./startFabric.sh
-showStep "creating new composer profile (required with each restart)"
-./createComposerProfile.sh
+~/fabric-tools/startFabric.sh
+#
+# no longer required with hyperledger composer V0.15
+# showStep "creating new composer profile (required with each restart)"
+# ~/fabric-tools/createComposerProfile.sh
+#
+showStep "creating new PeerAdmin card (required with each restart)"
+~/fabric-tools/createPeerAdminCard.sh
+composer card list --name PeerAdmin@hlfv1
showStep "start up complete"
\ No newline at end of file
diff --git a/Chapter05/z2c_login b/Chapter05/z2c_login
index 9743fc0..b8aba8a 100755
--- a/Chapter05/z2c_login
+++ b/Chapter05/z2c_login
@@ -1,6 +1,5 @@
#!/bin/bash
-ded_URL="https://api.w3ibm.bluemix.net"
pub_URL="https://api.ng.bluemix.net"
gb_URL="https://api.eu-gb.bluemix.net"
de_URL="https://api.eu-de.bluemix.net"
@@ -18,7 +17,7 @@ then targetURL=$de_URL
elif [[ $2 == "sydney" ]]
then targetURL=$au_URL
else
- echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:"
+ echo "Parameter 2 is required to be one of the following public designations:"
echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'"
echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'"
exit -1
diff --git a/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf
index 2f58874..9dfa9a0 100644
Binary files a/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf and b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf differ
diff --git a/Chapter06/Documentation/Chinese/Z2B_Chapter06.pptx b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pptx
new file mode 100644
index 0000000..3630baf
Binary files /dev/null and b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pptx differ
diff --git a/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf
index a8d82db..74689e3 100644
Binary files a/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf and b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf differ
diff --git a/Chapter06/Documentation/Espanol/Z2B_Chapter06.pptx b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pptx
new file mode 100644
index 0000000..fa4edc1
Binary files /dev/null and b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pptx differ
diff --git a/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf
index 8167b45..333f236 100644
Binary files a/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf and b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf differ
diff --git a/Chapter06/Documentation/Japanese/Z2B_Chapter06.pptx b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pptx
new file mode 100644
index 0000000..97e3365
Binary files /dev/null and b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pptx differ
diff --git a/Chapter06/Documentation/Z2B Chapter06.pdf b/Chapter06/Documentation/Z2B Chapter06.pdf
index eaee625..3dab8b9 100644
Binary files a/Chapter06/Documentation/Z2B Chapter06.pdf and b/Chapter06/Documentation/Z2B Chapter06.pdf differ
diff --git a/Chapter06/Documentation/answers/composer/hlcClient_complete.js b/Chapter06/Documentation/answers/composer/hlcClient_complete.js
index 401bf01..00e58c9 100644
--- a/Chapter06/Documentation/answers/composer/hlcClient_complete.js
+++ b/Chapter06/Documentation/answers/composer/hlcClient_complete.js
@@ -14,15 +14,14 @@
'use strict';
-var fs = require('fs');
-var path = require('path');
+let fs = require('fs');
+let path = require('path');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
-const config = require('../../../env.json');
+// const config = require('../../../env.json');
const NS = 'org.acme.Z2BTestNetwork';
let itemTable = null;
const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
const financeCoID = 'easymoney@easymoneyinc.com';
/**
@@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com';
* @param {express.req} req - the inbound request object from the client
* req.body.id - the id of the buyer making the request
* req.body.userID - the user id of the buyer in the identity table making this request
- * req.body.secret - the pw of this user.
+ * req.body.secret - the pw of this user.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.getMyOrders = function (req, res, next) {
// connect to the network
- let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json')));
+ let method = 'getMyOrders';
+ console.log(method+' req.body.userID is: '+req.body.userID );
let allOrders = new Array();
let businessNetworkConnection;
- let factory;
- if (svc.m_connection == null) {svc.createMessageSocket();}
+ if (svc.m_connection === null) {svc.createMessageSocket();}
let ser;
let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
businessNetworkConnection = new BusinessNetworkConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((bnd) => {
ser = bnd.getSerializer();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
- .then(() => {
- return businessNetworkConnection.query('selectOrders')
- .then((orders) => {
- let jsn;
- let allOrders = new Array();
- for (let each in orders)
- { (function (_idx, _arr)
- {
- let _jsn = ser.toJSON(_arr[_idx]);
- _jsn.id = _arr[_idx].orderNumber;
- allOrders.push(_jsn);
- })(each, orders)
- }
- res.send({'result': 'success', 'orders': allOrders});
- })
- .catch((error) => {console.log('selectOrders failed ', error);
- res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});
- });
- })
- .catch((error) => {console.log('businessNetwork connect failed ', error);
- res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
+ //
+ // v0.15
+ console.log(method+' req.body.userID is: '+req.body.userID );
+ return businessNetworkConnection.connect(req.body.userID)
+ .then(() => {
+ return businessNetworkConnection.query('selectOrders')
+ .then((orders) => {
+ allOrders = new Array();
+ for (let each in orders)
+ { (function (_idx, _arr)
+ {
+ let _jsn = ser.toJSON(_arr[_idx]);
+ _jsn.id = _arr[_idx].orderNumber;
+ allOrders.push(_jsn);
+ })(each, orders);
+ }
+ res.send({'result': 'success', 'orders': allOrders});
+ })
+ .catch((error) => {console.log('selectOrders failed ', error);
+ res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});
});
})
- .catch((error) => {console.log('create bnd from archive failed ', error);
+ .catch((error) => {console.log('businessNetwork connect failed ', error);
+ res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('create bnd from archive failed ', error);
res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message});
});
-}
+};
/**
@@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) {
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * return {Array} an array of assets
* @function
*/
exports.getItemTable = function (req, res, next)
{
- if (itemTable == null)
+ if (itemTable === null)
{
- let options = { flag : 'w' };
let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt');
itemTable = JSON.parse(fs.readFileSync(newFile));
}
res.send(itemTable);
-}
+};
+
/**
* orderAction - act on an order for a buyer
* @param {express.req} req - the inbound request object from the client
* req.body.action - string with buyer requested action
- * buyer available actions are:
+ * buyer available actions are:
* Pay - approve payment for an order
* Dispute - dispute an existing order. requires a reason
* Purchase - submit created order to seller for execution
@@ -111,155 +115,130 @@ exports.getItemTable = function (req, res, next)
* req.body.reason - reason for dispute, required for dispute processing to proceed
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.orderAction = function (req, res, next) {
- if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) )
- {let reason = req.body.reason;}
+ let method = 'orderAction';
+ console.log(method+' req.body.participant is: '+req.body.participant );
+ if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) )
+ {/*let reason = req.body.reason;*/}
else {
- if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) ))
- res.send({'result': 'failed', 'error': 'no reason provided for dispute'});
+ if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) ))
+ {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});}
}
- if (svc.m_connection == null) {svc.createMessageSocket();}
+ if (svc.m_connection === null) {svc.createMessageSocket();}
let businessNetworkConnection;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let updateOrder;
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.get(req.body.orderNo)
- .then((order) => {
- let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- order.status = req.body.action;
- switch (req.body.action)
- {
- case 'Pay':
- console.log('Pay entered');
- updateOrder = factory.newTransaction(NS, 'Pay');
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Dispute':
- console.log('Dispute entered');
- updateOrder = factory.newTransaction(NS, 'Dispute');
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.dispute = req.body.reason;
- break;
- case 'Purchase':
- console.log('Purchase entered');
- updateOrder = factory.newTransaction(NS, 'Buy');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Order From Supplier':
- console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier);
- updateOrder = factory.newTransaction(NS, 'OrderFromSupplier');
- updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Request Payment':
- console.log('Request Payment entered');
- updateOrder = factory.newTransaction(NS, 'RequestPayment');
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- break;
- case 'Refund':
- console.log('Refund Payment entered');
- updateOrder = factory.newTransaction(NS, 'Refund');
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.refund = req.body.reason;
- break;
- case 'Resolve':
- console.log('Resolve entered');
- updateOrder = factory.newTransaction(NS, 'Resolve');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier);
- updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.resolve = req.body.reason;
- break;
- case 'Request Shipping':
- console.log('Request Shipping entered');
- updateOrder = factory.newTransaction(NS, 'RequestShipping');
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper);
- updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
- break;
- case 'Update Delivery Status':
- console.log('Update Delivery Status');
- updateOrder = factory.newTransaction(NS, 'Delivering');
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant);
- updateOrder.deliveryStatus = req.body.delivery;
- break;
- case 'Delivered':
- console.log('Delivered entered');
- updateOrder = factory.newTransaction(NS, 'Deliver');
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant);
- break;
- case 'BackOrder':
- console.log('BackOrder entered');
- updateOrder = factory.newTransaction(NS, 'BackOrder');
- updateOrder.backorder = req.body.reason;
- updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
- updateOrder.backorder = req.body.reason;
- break;
- case 'Authorize Payment':
- console.log('Authorize Payment entered');
- updateOrder = factory.newTransaction(NS, 'AuthorizePayment');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- break;
- case 'Cancel':
- console.log('Cancel entered');
- updateOrder = factory.newTransaction(NS, 'OrderCancel');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- default :
- console.log('default entered for action: '+req.body.action);
- res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
- }
- updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
- return businessNetworkConnection.submitTransaction(updateOrder)
- .then(() => {
- console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action);
- res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action});
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(" retrying assetRegistry.update for: "+req.body.orderNo);
- svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
- }
- else
- {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);}
- });
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.participant)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.get(req.body.orderNo)
+ .then((order) => {
+ let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ order.status = req.body.action;
+ switch (req.body.action)
+ {
+ case 'Pay':
+
+ break;
+ case 'Dispute':
+ console.log('Dispute entered');
+ updateOrder = factory.newTransaction(NS, 'Dispute');
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.dispute = req.body.reason;
+ break;
+ case 'Purchase':
+ console.log('Purchase entered');
+ updateOrder = factory.newTransaction(NS, 'Buy');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ case 'Order From Supplier':
+
+ break;
+ case 'Request Payment':
+
+ break;
+ case 'Refund':
+
+ break;
+ case 'Resolve':
+ console.log('Resolve entered');
+ updateOrder = factory.newTransaction(NS, 'Resolve');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier);
+ updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.resolve = req.body.reason;
+ break;
+ case 'Request Shipping':
+ break;
+ case 'Update Delivery Status':
+ break;
+ case 'Delivered':
+
+ break;
+ case 'BackOrder':
+
+ break;
+ case 'Authorize Payment':
+ console.log('Authorize Payment entered');
+ updateOrder = factory.newTransaction(NS, 'AuthorizePayment');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ break;
+ case 'Cancel':
+ console.log('Cancel entered');
+ updateOrder = factory.newTransaction(NS, 'OrderCancel');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ default :
+ console.log('default entered for action: '+req.body.action);
+ res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
+ }
+ updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
+ return businessNetworkConnection.submitTransaction(updateOrder)
+ .then(() => {
+ console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action);
+ res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action});
})
.catch((error) => {
- console.log('Registry Get Order failed: '+error.message);
- res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(' retrying assetRegistry.update for: '+req.body.orderNo);
+ svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
+ }
+ else
+ {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);}
});
+
})
- .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
+ .catch((error) => {
+ console.log('Registry Get Order failed: '+error.message);
+ res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
- })
- .catch((error) => {console.log('Business Network Connect failed: '+error.message);
+ })
+ .catch((error) => {console.log('Business Network Connect failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
-}
+};
+
/**
* adds an order to the blockchain
* @param {express.req} req - the inbound request object from the client
@@ -268,85 +247,87 @@ exports.orderAction = function (req, res, next) {
* req.body.items - array with items for order
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.addOrder = function (req, res, next) {
+ let method = 'addOrder';
+ console.log(method+' req.body.buyer is: '+req.body.buyer );
let businessNetworkConnection;
let factory;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let ts = Date.now();
- let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
- if (svc.m_connection == null) {svc.createMessageSocket();}
-
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- let order = factory.newResource(NS, 'Order', orderNo);
- order = svc.createOrderTemplate(order);
- order.amount = 0;
- order.orderNumber = orderNo;
- order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
- order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
- order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- for (let each in req.body.items)
- {(function(_idx, _arr)
- { _arr[_idx].description = _arr[_idx].itemDescription;
- order.items.push(JSON.stringify(_arr[_idx]));
- order.amount += parseInt(_arr[_idx].extendedPrice);
- })(each, req.body.items)
- }
- // create the buy transaction
- const createNew = factory.newTransaction(NS, 'CreateOrder');
-
- createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
- createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- createNew.amount = order.amount;
- // add the order to the asset registry.
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.add(order)
- .then(() => {
- return businessNetworkConnection.submitTransaction(createNew)
- .then(() => {console.log(' order '+orderNo+" successfully added");
- res.send({'result': ' order '+orderNo+' successfully added'});
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- else
- {console.log(orderNo+" submitTransaction failed with text: ",error.message);}
- });
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- else
- {console.log(orderNo+" assetRegistry.add failed: ",error.message);}
- });
- })
- .catch((error) => {
- console.log(orderNo+" getAssetRegistry failed: ",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
- });
- })
- .catch((error) => {
- console.log(orderNo+" business network connection failed: text",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
- });
+ let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
+ if (svc.m_connection === null) {svc.createMessageSocket();}
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.buyer)
+ .then(() => {
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ let order = factory.newResource(NS, 'Order', orderNo);
+ order = svc.createOrderTemplate(order);
+ order.amount = 0;
+ order.orderNumber = orderNo;
+ order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
+ order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
+ order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
+ order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
+ order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ for (let each in req.body.items)
+ {(function(_idx, _arr)
+ { _arr[_idx].description = _arr[_idx].itemDescription;
+ order.items.push(JSON.stringify(_arr[_idx]));
+ order.amount += parseInt(_arr[_idx].extendedPrice);
+ })(each, req.body.items);
}
+ // create the buy transaction
+ const createNew = factory.newTransaction(NS, 'CreateOrder');
+
+ createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
+ createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
+ createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
+ createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ createNew.amount = order.amount;
+ // add the order to the asset registry.
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.add(order)
+ .then(() => {
+ return businessNetworkConnection.submitTransaction(createNew)
+ .then(() => {console.log(' order '+orderNo+' successfully added');
+ res.send({'result': ' order '+orderNo+' successfully added'});
+ })
+ .catch((error) => {
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo);
+ svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
+ }
+ else
+ {console.log(orderNo+' submitTransaction failed with text: ',error.message);}
+ });
+ })
+ .catch((error) => {
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo);
+ svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
+ }
+ else
+ {
+ console.log(orderNo+' assetRegistry.add failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ }
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' getAssetRegistry failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' business network connection failed: text',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
+ });
+};
diff --git a/Chapter06/Documentation/answers/js/z2b-buyer_complete.js b/Chapter06/Documentation/answers/js/z2b-buyer_complete.js
index 37f4b2c..535f938 100644
--- a/Chapter06/Documentation/answers/js/z2b-buyer_complete.js
+++ b/Chapter06/Documentation/answers/js/z2b-buyer_complete.js
@@ -14,166 +14,173 @@
// z2c-buyer.js
-var orderDiv = "orderDiv";
-var itemTable = {};
-var newItems = [];
-var totalAmount = 0;
+'use strict';
+
+let orderDiv = 'orderDiv';
+let itemTable = {};
+let newItems = [];
+let totalAmount = 0;
/**
- * load the administration User Experience
+ * load the Buyer User Experience
*/
function loadBuyerUX ()
{
- // get the html page to load
- toLoad = "buyer.html";
- // get the port to use for web socket communications with the server
- getPort();
- // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero
- // assume user has run autoLoad and rebuild member list
- // if autoLoad not yet run, then member list length will still be zero
- if (buyers.length === 0)
- { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res)
- {setupBuyer(page[0], port[0]);});
-}
- else{
- $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port)
+ // get the html page to load
+ let toLoad = 'buyer.html';
+ // get the port to use for web socket communications with the server
+ getPort();
+ // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero
+ // assume user has run autoLoad and rebuild member list
+ // if autoLoad not yet run, then member list length will still be zero
+ if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0))
+ { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res)
{setupBuyer(page[0], port[0]);});
- }
+ }
+ else{
+ $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port)
+ {setupBuyer(page[0], port[0]);});
+ }
}
function setupBuyer(page, port)
{
- // empty the hetml element that will hold this page
- $("#body").empty();
- $("#body").append(page);
- // update the text on the page using the prompt data for the selected language
- updatePage("buyer");
- msgPort = port.port;
- // connect to the web socket and tell the web socket where to display messages
- wsDisplay('buyer_messages', msgPort);
- // enable the buttons to process an onClick event
- var _create = $("#newOrder");
- var _list = $("#orderStatus");
- var _orderDiv = $("#"+orderDiv);
- _create.on('click', function(){displayOrderForm();});
- _list.on('click', function(){listOrders()});
- $("#buyer").empty();
- // build the buer select HTML element
- for (each in buyers)
- {(function(_idx, _arr){
- $("#buyer").append('');;
- })(each, buyers)}
+ // empty the hetml element that will hold this page
+ $('#body').empty();
+ $('#body').append(page);
+ // update the text on the page using the prompt data for the selected language
+ updatePage('buyer');
+ msgPort = port.port;
+ // connect to the web socket and tell the web socket where to display messages
+ wsDisplay('buyer_messages', msgPort);
+ // enable the buttons to process an onClick event
+ let _create = $('#newOrder');
+ let _list = $('#orderStatus');
+ let _orderDiv = $('#'+orderDiv);
+ _create.on('click', function(){displayOrderForm();});
+ _list.on('click', function(){listOrders();});
+ $('#buyer').empty();
+ // build the buer select HTML element
+ for (let each in buyers)
+ {(function(_idx, _arr)
+ {$('#buyer').append('');})(each, buyers);
+ }
// display the name of the current buyer
- $("#company")[0].innerText = buyers[0].companyName;
- // create a function to execute when the user selects a different buyer
- $("#buyer").on('change', function() { _orderDiv.empty(); $("#buyer_messages").empty(); $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; });
+ $('#company')[0].innerText = buyers[0].companyName;
+ // create a function to execute when the user selects a different buyer
+ $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; });
}
/**
* Displays the create order form for the selected buyer
*/
-
function displayOrderForm()
-{ toLoad = "createOrder.html";
-totalAmount = 0;
-newItems = [];
-// get the order creation web page and also get all of the items that a user can select
-$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items)
- {
- itemTable = _items[0].items;
- let _orderDiv = $("#"+orderDiv);
- _orderDiv.empty();
- _orderDiv.append(page[0]);
- // update the page with the appropriate text for the selected language
- updatePage('createOrder');
- $('#seller').empty();
- // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call
- $('#seller').append(s_string);
- $('#seller').val($("#seller option:first").val());
- $('#orderNo').append('xxx');
- $('#status').append('New Order');
- $('#today').append(new Date().toISOString());
- $('#amount').append('$'+totalAmount+'.00');
- // build a select list for the items
- var _str = "";
- for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)}
- $('#items').empty();
- $('#items').append(_str);
- $('#cancelNewOrder').on('click', function (){_orderDiv.empty();});
- // hide the submit new order function until an item has been selected
- $('#submitNewOrder').hide();
- $('#submitNewOrder').on('click', function ()
- { let options = {};
- options.buyer = $("#buyer").find(":selected").val();
- options.seller = $("#seller").find(":selected").val();
- options.items = newItems;
- console.log(options);
- _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg));
- $.when($.post('/composer/client/addOrder', options)).done(function(_res)
- { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);});
- });
- // function to call when an item has been selected
- $('#addItem').on('click', function ()
- { let _ptr = $("#items").find(":selected").val();
- // remove the just selected item so that it cannot be added twice.
- $('#items').find(':selected').remove();
- // build a new item detail row in the display window
- let _item = itemTable[_ptr];
- let len = newItems.length;
- _str = '
'+_item.itemNo+'
'+_item.itemDescription+'
'
- $('#itemTable').append(_str);
- // set the initial item count to 1
- $('#count'+len).val(1);
- // set the initial price to the price of one item
- $('#price'+len).append("$"+_item.unitPrice+".00");
- // add an entry into an array for this newly added item
- let _newItem = _item;
- _newItem.extendedPrice = _item.unitPrice;
- newItems[len] = _newItem;
- newItems[len].quantity=1;
- totalAmount += _newItem.extendedPrice;
- // update the order amount with this new item
- $('#amount').empty();
- $('#amount').append('$'+totalAmount+'.00');
- // function to update item detail row and total amount if itemm count is changed
- $('#count'+len).on('change', function ()
- {let len = this.id.substring(5);
- let qty = $('#count'+len).val();
- let price = newItems[len].unitPrice*qty;
- let delta = price - newItems[len].extendedPrice;
- totalAmount += delta;
- $('#amount').empty();
+{ let toLoad = 'createOrder.html';
+ totalAmount = 0;
+ newItems = [];
+ // get the order creation web page and also get all of the items that a user can select
+ $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items)
+ {
+ itemTable = _items[0].items;
+ let _orderDiv = $('#'+orderDiv);
+ _orderDiv.empty();
+ _orderDiv.append(page[0]);
+ // update the page with the appropriate text for the selected language
+ updatePage('createOrder');
+ $('#seller').empty();
+ // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call
+ $('#seller').append(s_string);
+ $('#seller').val($('#seller option:first').val());
+ $('#orderNo').append('xxx');
+ $('#status').append('New Order');
+ $('#today').append(new Date().toISOString());
$('#amount').append('$'+totalAmount+'.00');
- newItems[len].extendedPrice = price;
- newItems[len].quantity=qty;
- $('#price'+len).empty(); $('#price'+len).append("$"+price+".00");
- });
- $('#submitNewOrder').show();
- });
- });
+ // build a select list for the items
+ let _str = '';
+ for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)}
+ $('#items').empty();
+ $('#items').append(_str);
+ $('#cancelNewOrder').on('click', function (){_orderDiv.empty();});
+ // hide the submit new order function until an item has been selected
+ $('#submitNewOrder').hide();
+ $('#submitNewOrder').on('click', function ()
+ { let options = {};
+ options.buyer = $('#buyer').find(':selected').val();
+ options.seller = $('#seller').find(':selected').val();
+ options.items = newItems;
+ console.log(options);
+ _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg));
+ $.when($.post('/composer/client/addOrder', options)).done(function(_res)
+ { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);});
+ });
+ // function to call when an item has been selected
+ $('#addItem').on('click', function ()
+ { let _ptr = $('#items').find(':selected').val();
+ // remove the just selected item so that it cannot be added twice.
+ $('#items').find(':selected').remove();
+ // build a new item detail row in the display window
+ let _item = itemTable[_ptr];
+ let len = newItems.length;
+ _str = '
'+_item.itemNo+'
'+_item.itemDescription+'
';
+ $('#itemTable').append(_str);
+ // set the initial item count to 1
+ $('#count'+len).val(1);
+ // set the initial price to the price of one item
+ $('#price'+len).append('$'+_item.unitPrice+'.00');
+ // add an entry into an array for this newly added item
+ let _newItem = _item;
+ _newItem.extendedPrice = _item.unitPrice;
+ newItems[len] = _newItem;
+ newItems[len].quantity=1;
+ totalAmount += _newItem.extendedPrice;
+ // update the order amount with this new item
+ $('#amount').empty();
+ $('#amount').append('$'+totalAmount+'.00');
+ // function to update item detail row and total amount if itemm count is changed
+ $('#count'+len).on('change', function ()
+ {let len = this.id.substring(5);
+ let qty = $('#count'+len).val();
+ let price = newItems[len].unitPrice*qty;
+ let delta = price - newItems[len].extendedPrice;
+ totalAmount += delta;
+ $('#amount').empty();
+ $('#amount').append('$'+totalAmount+'.00');
+ newItems[len].extendedPrice = price;
+ newItems[len].quantity=qty;
+ $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00');
+ });
+ $('#submitNewOrder').show();
+ });
+ });
}
/**
* lists all orders for the selected buyer
*/
function listOrders()
{
- var options = {};
- // get the users email address
- options.id = $("#buyer").find(":selected").text();
- // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily
- $.when($.post('/composer/admin/getSecret', options)).done(function(_mem)
- {
+ let options = {};
+ // get the users email address
+ options.id = $('#buyer').find(':selected').text();
+ // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily
+ // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem)
+ // {
// get their orders
- options.userID = _mem.userID; options.secret = _mem.secret;
+ options.userID = options.id;
+ // options.userID = _mem.userID; options.secret = _mem.secret;
$.when($.post('/composer/client/getMyOrders', options)).done(function(_results)
- {
- // if they have no orders, then display a message to that effect
- if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));}
- // if they have orders, format and display the orders.
- else{formatOrders($("#orderDiv"), _results.orders)}
- });
- });
+ {
+ if ((typeof(_results.orders) === 'undefined') || (_results.orders === null))
+ {console.log('error getting orders: ', _results);}
+ else
+ {// if they have no orders, then display a message to that effect
+ if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));}
+ // if they have orders, format and display the orders.
+ else{formatOrders($('#orderDiv'), _results.orders);}
+ }
+ });
+ // });
}
+
/**
* used by the listOrders() function
* formats the orders for a buyer. Orders to be formatted are provided in the _orders array
@@ -183,113 +190,114 @@ function listOrders()
*/
function formatOrders(_target, _orders)
{
- _target.empty();
- let _str = ""; let _date = "";
- for (let each in _orders)
- {(function(_idx, _arr)
- { _action = '
';
-//
-// each order can have different states and the action that a buyer can take is directly dependent on the state of the order.
-// this switch/case table displays selected order information based on its current status and displays selected actions, which
-// are limited by the sate of the order.
-//
-// Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)'
-// These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file
-// associated with the language selected by the web user.
-//
- switch (JSON.parse(_arr[_idx].status).code)
- {
+ _target.empty();
+ let _str = ''; let _date = '';
+ for (let each in _orders)
+ {(function(_idx, _arr)
+ {let _action = '
';
+ //
+ // each order can have different states and the action that a buyer can take is directly dependent on the state of the order.
+ // this switch/case table displays selected order information based on its current status and displays selected actions, which
+ // are limited by the sate of the order.
+ //
+ // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)'
+ // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file
+ // associated with the language selected by the web user.
+ //
+ switch (JSON.parse(_arr[_idx].status).code)
+ {
case orderStatus.PayRequest.code:
- _date = _arr[_idx].paymentRequested;
- _action += '';
- _action += '';
- r_string = ' '+textPrompts.orderProcess.Dispute.prompt+'';
- break;
+ _date = _arr[_idx].paymentRequested;
+ _action += '';
+ _action += '';
+ r_string = ' '+textPrompts.orderProcess.Dispute.prompt+'';
+ break;
case orderStatus.Delivered.code:
- _date = _arr[_idx].delivered;
- _action += '';
- r_string = ' '+textPrompts.orderProcess.Dispute.prompt+'';
- break;
+ _date = _arr[_idx].delivered;
+ _action += '';
+ r_string = ' '+textPrompts.orderProcess.Dispute.prompt+'';
+ break;
case orderStatus.Dispute.code:
- _date = _arr[_idx].disputeOpened + ' '+_arr[_idx].dispute;
- _action += '';
- r_string = ' '+textPrompts.orderProcess.Resolve.prompt+'';
- break;
+ _date = _arr[_idx].disputeOpened + ' '+_arr[_idx].dispute;
+ _action += '';
+ r_string = ' '+textPrompts.orderProcess.Resolve.prompt+'';
+ break;
case orderStatus.Resolve.code:
- _date = _arr[_idx].disputeResolved + ' '+_arr[_idx].resolve;
- _action += '';
- break;
+ _date = _arr[_idx].disputeResolved + ' '+_arr[_idx].resolve;
+ _action += '';
+ break;
case orderStatus.Created.code:
- _date = _arr[_idx].created;
- _action += ''
- _action += ''
- break;
+ _date = _arr[_idx].created;
+ _action += ''
+ _action += ''
+ break;
case orderStatus.Backordered.code:
- _date = _arr[_idx].dateBackordered + ' '+_arr[_idx].backorder;
- _action += ''
- break;
+ _date = _arr[_idx].dateBackordered + ' '+_arr[_idx].backorder;
+ _action += ''
+ break;
case orderStatus.ShipRequest.code:
- _date = _arr[_idx].requestShipment;
- break;
+ _date = _arr[_idx].requestShipment;
+ break;
case orderStatus.Authorize.code:
- _date = _arr[_idx].approved;
- break;
+ _date = _arr[_idx].approved;
+ break;
case orderStatus.Bought.code:
- _date = _arr[_idx].bought;
- _action += ''
- break;
+ _date = _arr[_idx].bought;
+ _action += ''
+ break;
case orderStatus.Delivering.code:
- _date = _arr[_idx].delivering;
- break;
+ _date = _arr[_idx].delivering;
+ break;
case orderStatus.Ordered.code:
- _date = _arr[_idx].ordered;
- _action += ''
- break;
+ _date = _arr[_idx].ordered;
+ _action += ''
+ break;
case orderStatus.Cancelled.code:
- _date = _arr[_idx].cancelled;
- break;
+ _date = _arr[_idx].cancelled;
+ break;
case orderStatus.Paid.code:
- _date = _arr[_idx].paid;
- break;
+ _date = _arr[_idx].paid;
+ break;
default:
- break;
- }
- _button = '
'
- for (let every in _arr[_idx].items)
- {(function(_idx2, _arr2)
- { let _item = JSON.parse(_arr2[_idx2]);
- _str += '
'+_item.itemNo+'
'+_item.description+'
'+_item.quantity+'
$'+_item.extendedPrice+'.00
';
- })(every, _arr[_idx].items)
- }
- _str += '
';
- })(each, _orders)
- }
- // append the newly built order table to the web page
- _target.append(_str);
- //
- // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced.
- // iterate through the page and make all of the different parts of the page active.
- //
- for (let each in _orders)
- {(function(_idx, _arr)
- { $("#b_btn_"+_idx).on('click', function ()
+ break;
+ }
+ let _button = '
';
+ })(each, _orders);
+ }
+ // append the newly built order table to the web page
+ _target.append(_str);
+ //
+ // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced.
+ // iterate through the page and make all of the different parts of the page active.
+ //
+ for (let each in _orders)
+ {(function(_idx, _arr)
+ { $('#b_btn_'+_idx).on('click', function ()
+ {
+ let options = {};
+ options.action = $('#b_action'+_idx).find(':selected').text();
+ options.orderNo = $('#b_order'+_idx).text();
+ options.participant = $('#buyer').val();
+ if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();}
+ $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo));
+ $.when($.post('/composer/client/orderAction', options)).done(function (_results)
+ { $('#buyer_messages').prepend(formatMessage(_results.result)); });
+ });
+ })(each, _orders)
+ }
}
\ No newline at end of file
diff --git a/Chapter06/HTML/CSS/pageStyles.css b/Chapter06/HTML/CSS/pageStyles.css
index d6d67bf..6038b35 100755
--- a/Chapter06/HTML/CSS/pageStyles.css
+++ b/Chapter06/HTML/CSS/pageStyles.css
@@ -47,6 +47,17 @@ body {height: 100%}
overflow: auto;
}
}
+.strike {
+ position: relative;
+}
+.strike::before {
+ content: '';
+ border-bottom: 2px solid rgb(232, 235, 65);
+ width: 100%;
+ position: absolute;
+ right: 0;
+ top: 50%;
+}
.buyer { background-color: #CBCFD0; }
.seller { background-color: #5DC15D;}
.provider { background-color: #8A99D3;}
@@ -72,14 +83,14 @@ p.message{
}
.scrollingPaneLeft{
position: fixed;
- height: 85%;
+ height: 80%;
margin-left: 1%;
width: 45%;
overflow: auto;
}
.scrollingPaneRight{
position: fixed;
- height: 85%;
+ height: 80%;
margin-left: 50%;
width: 45%;
overflow: auto;
@@ -87,10 +98,10 @@ p.message{
.blockchain {
background-color: black;
position: fixed;
- height: 9%;
+ height: 8%;
margin-left: 1%;
width: 95%;
- top: 90%;
+ top: 92%;
padding: 4px;
overflow-x: auto;
overflow-y: hidden;
diff --git a/Chapter06/HTML/admin.html b/Chapter06/HTML/admin.html
index a010464..53b3a2d 100644
--- a/Chapter06/HTML/admin.html
+++ b/Chapter06/HTML/admin.html
@@ -1,41 +1,45 @@
-
-
-
-
-
-
(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
y
-
-
-
-
+
Why All The Changes?
+
+
+
+
+
+
(
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
Result
-
-
+
+
+
y
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/Chapter06/HTML/adminHelp.html b/Chapter06/HTML/adminHelp.html
new file mode 100644
index 0000000..f1cf21c
--- /dev/null
+++ b/Chapter06/HTML/adminHelp.html
@@ -0,0 +1,29 @@
+
Why All The Changes?
+
HyperLedger Composer has gone through two significant changes in 4Q2017.
+ The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and
+the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did
+change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change
+is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant
+change required adding two statements to the permissions.acl file.
+
+
Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method)
+ to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh),
+ required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin
+ interface. You'll see a number of items which have a yellow strikethrough, indicating that they
+ are no longer available.
+
+
We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful.
+ Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each
+ Member. so that is deactivated.
+
+
We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need
+ the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new
+ functions in the Resource Management part of the administrative user interface, along with a feature which will
+ check to see if an idCard already exists for a specific member.
+
+
An Identity can only be issued for an existing Member, so the process is to:
Add a Member
+
Issue an Identity
Create an idCard
+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these
+ functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard
+ process, so that you don't have to remember to copy the generated secret and type it into the createCard page.
+
\ No newline at end of file
diff --git a/Chapter06/HTML/createOrder.html b/Chapter06/HTML/createOrder.html
index cc1a0dc..e5e57bd 100644
--- a/Chapter06/HTML/createOrder.html
+++ b/Chapter06/HTML/createOrder.html
@@ -2,10 +2,11 @@
-
+
+
-
+
diff --git a/Chapter06/HTML/favicon.ico b/Chapter06/HTML/favicon.ico
index 4126853..fc9e25d 100755
Binary files a/Chapter06/HTML/favicon.ico and b/Chapter06/HTML/favicon.ico differ
diff --git a/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf
index 1413fc6..1f85312 100644
Binary files a/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/Chapter06/HTML/icons/Search.ico b/Chapter06/HTML/icons/Search.ico
index e1d39ae..fd437a0 100755
Binary files a/Chapter06/HTML/icons/Search.ico and b/Chapter06/HTML/icons/Search.ico differ
diff --git a/Chapter06/HTML/js/z2b-admin.js b/Chapter06/HTML/js/z2b-admin.js
index c716cb8..67f421a 100644
--- a/Chapter06/HTML/js/z2b-admin.js
+++ b/Chapter06/HTML/js/z2b-admin.js
@@ -14,57 +14,53 @@
// z2b-admin.js
-var creds;
-var connection;
-var connectionProfileName = 'z2b-test-profile';
-var networkFile = 'zerotoblockchain-network.bna'
-var businessNetwork = 'zerotoblockchain-network';
-var msgPort = null;
-var _blctr = 0;
+'use strict';
+
+let creds;
+let connection;
+let msgPort = null;
+let _blctr = 0;
/**
* load the administration User Experience
*/
function loadAdminUX ()
{
- toLoad = 'admin.html';
- $.when($.get(toLoad)).done(function (page)
- {$('#body').empty();
- $('#body').append(page);
- updatePage("admin");
- listMemRegistries();
- });
+ let toLoad = 'admin.html';
+ $.when($.get(toLoad)).done(function (page)
+ {$('#body').empty();
+ $('#body').append(page);
+ updatePage('admin');
+ listMemRegistries();
+ });
}
/**
* connect to the provided web socket
- * @param {loc} - _target location to post messages
- * @param {port} - web socket port #
+ * @param {String} _target - location to post messages
+ * @param {Integer} _port - web socket port #
*/
function wsDisplay(_target, _port)
{
- var content = $('#'+_target);
- var wsSocket = new WebSocket('ws://localhost:'+_port);
- wsSocket.onopen = function () {wsSocket.send('connected to client');};
-
- wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));};
-
- wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);};
-
+ let content = $('#'+_target);
+ let wsSocket = new WebSocket('ws://localhost:'+_port);
+ wsSocket.onopen = function () {wsSocket.send('connected to client');};
+ wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));};
+ wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);};
}
/**
* list the available business networks
*/
function adminList()
{
- var _url = '/composer/admin/listAsAdmin';
- $.when($.get(_url)).done(function (_connection)
- { var _str = '
Current Active Business Networks
';
- for (each in _connection)
- {(function(_idx, _arr){_str += '
';
+ for (let each in _profiles) {_str += displayProfile(_profiles[each], each);}
+ _str += '
';
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+
+ });
}
/**
* gather and list all of the current network connection profiles
- * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button.
- * This allows the same routine to be used for display or delete processing
+ * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button.
+ * This allows the same routine to be used for display or delete processing
*/
function listProfiles(_state)
{
- $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page)
- {
- $('#admin-forms').empty();
- $('#admin-forms').append(page);
- updatePage("deleteConnectionProfile");
- $('#connection_profiles').on('change',function()
- { var name = $('#connection_profiles').find(':selected').text();
- var profile = connection_profiles[name];
- var _str = displayProfile(profile,name);
- $('#selected_profile').empty();
- $('#selected_profile').append(_str);
+ $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page)
+ {
+ $('#admin-forms').empty();
+ $('#admin-forms').append(page);
+ updatePage('deleteConnectionProfile');
+ $('#connection_profiles').on('change',function()
+ { let name = $('#connection_profiles').find(':selected').text();
+ let profile = connection_profiles[name];
+ let _str = displayProfile(profile,name);
+ $('#selected_profile').empty();
+ $('#selected_profile').append(_str);
+ });
+ let connection_profiles = _profiles[0];
+ for (let each in connection_profiles)
+ { (function (_idx, _arr)
+ { $('#connection_profiles').append(''); })(each, connection_profiles); }
+ let first = $('#connection_profiles').find(':first').text();
+ let _str = displayProfile(connection_profiles[first],first);
+ $('#selected_profile').empty();
+ $('#selected_profile').append(_str);
+ let _cancel = $('#cancel');
+ let _submit = $('#submit');
+ _cancel.on('click', function (){$('#admin-forms').empty();});
+ if (_state === 0)
+ {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});}
+ else
+ {_submit.hide();}
});
- var connection_profiles = _profiles[0];
- for (each in connection_profiles)
- { (function (_idx, _arr)
- { $('#connection_profiles').append(''); })(each, connection_profiles); }
- var first = $('#connection_profiles').find(':first').text();
- var _str = displayProfile(connection_profiles[first],first);
- $('#selected_profile').empty();
- $('#selected_profile').append(_str);
- var _cancel = $('#cancel');
- var _submit = $('#submit');
- _cancel.on('click', function (){$('#admin-forms').empty();});
- if (_state == 0)
- {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});}
- else
- {_submit.hide();}
- });
}
/**
@@ -186,15 +181,15 @@ function listProfiles(_state)
*/
function networkDeploy()
{
- var options = {};
- options.myArchive = networkFile;
- $.when($.post('/composer/admin/deploy', options)).done(function (_results)
- { var _str = '';
- _str +='
';
+ for (let each in _results.ping){(function(_idx, _arr){_str+='
'+_idx+'
'+_arr[_idx]+'
';})(each, _results.ping);}
+ _str+='
';
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
});
}
@@ -277,25 +272,23 @@ function ping()
*/
function networkUndeploy()
{
-
- var options = {};
- options.businessNetwork = businessNetwork;
- if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true)
- {
- $.when($.post('/composer/admin/undeploy', options)).done(function(_results)
+ let options = {};
+ options.businessNetwork = businessNetwork;
+ if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true)
{
- var _str = '';
- _str +='
';
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
}
-/*
-* get member in a registry
-*/
+/**
+ * get member in a registry
+ */
function listRegistry()
{
- var options = {};
- options.registry = $('#registryName').find(':selected').text();
- $.when($.post('/composer/admin/getMembers', options)).done(function (_results)
- {
- var _str = '';
- _str +='
Registry List
';
- _str += '
Network update results: '+_results.result+'
';
- _str += '
Type
Company
email
';
- for (each in _results.members)
- {(function(_idx, _arr){
- _str += '
Get Chain events requested. Sending to port: '+_res.port+'
';
- var content = $('#blockchain');
- var csSocket = new WebSocket('ws://localhost:'+_res.port);
- csSocket.onopen = function () {csSocket.send('connected to client');};
- csSocket.onmessage = function (message) {
- _blctr ++;
- if (message.data != 'connected')
- {$('#blockchain').append('block '+JSON.parse(message.data).header.number+' Hash: '+JSON.parse(message.data).header.data_hash+'');
- if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);}
- }
- };
- csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);};
- $("#admin-forms").empty();
- $("#admin-forms").append(_str);
- });
+ $.when($.get('fabric/getChainEvents')).done(function(_res)
+ { let _str = '
Get Chain events requested. Sending to port: '+_res.port+'
';
+ let content = $('#blockchain');
+ let csSocket = new WebSocket('ws://localhost:'+_res.port);
+ csSocket.onopen = function () {csSocket.send('connected to client');};
+ csSocket.onmessage = function (message) {
+ _blctr ++;
+ if (message.data !== 'connected')
+ {$(content).append('block '+JSON.parse(message.data).header.number+' Hash: '+JSON.parse(message.data).header.data_hash+'');
+ if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);}
+ }
+ };
+ csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);};
+ $('#admin-forms').empty();
+ $('#admin-forms').append(_str);
+ });
+}
+/**
+ * display blockchain updates
+ */
+function displayAdminUpdate()
+{
+ let toLoad = 'adminHelp.html';
+ $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);});
}
\ No newline at end of file
diff --git a/Chapter06/HTML/js/z2b-buyer.js b/Chapter06/HTML/js/z2b-buyer.js
index 31007b3..c91fdd5 100644
--- a/Chapter06/HTML/js/z2b-buyer.js
+++ b/Chapter06/HTML/js/z2b-buyer.js
@@ -14,142 +14,179 @@
// z2c-buyer.js
-var orderDiv = "orderDiv";
-var itemTable = {};
-var newItems = [];
-var totalAmount = 0;
+'use strict';
+
+let orderDiv = 'orderDiv';
+let itemTable = {};
+let newItems = [];
+let totalAmount = 0;
/**
- * load the administration User Experience
+ * load the Buyer User Experience
*/
function loadBuyerUX ()
{
- // get the html page to load
- toLoad = "buyer.html";
- // get the port to use for web socket communications with the server
- getPort();
- // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero
- // assume user has run autoLoad and rebuild member list
- // if autoLoad not yet run, then member list length will still be zero
- if (buyers.length === 0)
- { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res)
- {setupBuyer(page[0], port[0]);});
-}
- else{
- $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port)
+ // get the html page to load
+ let toLoad = 'buyer.html';
+ // get the port to use for web socket communications with the server
+ getPort();
+ // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero
+ // assume user has run autoLoad and rebuild member list
+ // if autoLoad not yet run, then member list length will still be zero
+ if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0))
+ { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res)
{setupBuyer(page[0], port[0]);});
- }
+ }
+ else{
+ $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port)
+ {setupBuyer(page[0], port[0]);});
+ }
}
function setupBuyer(page, port)
{
- // empty the hetml element that will hold this page
- $("#body").empty();
- $("#body").append(page);
- // update the text on the page using the prompt data for the selected language
-
- // connect to the web socket and tell the web socket where to display messages
+ // empty the hetml element that will hold this page
- // enable the buttons to process an onClick event
+ // update the text on the page using the prompt data for the selected language
+ updatePage('buyer');
+ msgPort = port.port;
+ // connect to the web socket and tell the web socket where to display messages
- // build the buer select HTML element
+ // enable the buttons to process an onClick event
- // display the name of the current buyer
+ // build the buyer select HTML element
+ for (let each in buyers)
+ {(function(_idx, _arr)
+ {$('#buyer').append('');})(each, buyers);
+ }
+ // display the name of the current buyer
- // create a function to execute when the user selects a different buyer
+ // create a function to execute when the user selects a different buyer
+ $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; });
-
}
/**
* Displays the create order form for the selected buyer
*/
-
function displayOrderForm()
-{ toLoad = "createOrder.html";
-totalAmount = 0;
-newItems = [];
-// get the order creation web page and also get all of the items that a user can select
-$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items)
- {
- itemTable = _items[0].items;
- let _orderDiv = $("#"+orderDiv);
- _orderDiv.empty();
- _orderDiv.append(page[0]);
- // update the page with the appropriate text for the selected language
-
- // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call
-
- // build a select list for the items
-
- // hide the submit new order function until an item has been selected
-
- // create a new function to create an order when the order button is clicked
-
- // function to call when an item has been selected
-
- // remove the just selected item so that it cannot be added twice.
-
- // build a new item detail row in the display window
-
- // set the initial item count to 1
-
- // set the initial price to the price of one item
-
- // add an entry into an array for this newly added item
-
- // update the order amount with this new item
-
- // function to update item detail row and total amount if itemm count is changed
- });
-
- }
+{ let toLoad = 'createOrder.html';
+ totalAmount = 0;
+ newItems = [];
+ // get the order creation web page and also get all of the items that a user can select
+ $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items)
+ {
+
+ // update the page with the appropriate text for the selected language
+
+ // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call
+
+ // build a select list for the items
+
+ // hide the submit new order function until an item has been selected
+ $('#submitNewOrder').hide();
+ $('#submitNewOrder').on('click', function ()
+ { let options = {};
+ options.buyer = $('#buyer').find(':selected').val();
+ options.seller = $('#seller').find(':selected').val();
+ options.items = newItems;
+ console.log(options);
+ _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg));
+ $.when($.post('/composer/client/addOrder', options)).done(function(_res)
+ { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);});
+ });
+ // function to call when an item has been selected
+ $('#addItem').on('click', function ()
+ {
+ // remove the just selected item so that it cannot be added twice.
+
+ // build a new item detail row in the display window
+
+ // set the initial item count to 1
+
+ // set the initial price to the price of one item
+
+ // add an entry into an array for this newly added item
+
+ // update the order amount with this new item
+
+ // function to update item detail row and total amount if itemm count is changed
+ $('#count'+len).on('change', function ()
+ {let len = this.id.substring(5);
+ let qty = $('#count'+len).val();
+ let price = newItems[len].unitPrice*qty;
+ let delta = price - newItems[len].extendedPrice;
+ totalAmount += delta;
+ $('#amount').empty();
+ $('#amount').append('$'+totalAmount+'.00');
+ newItems[len].extendedPrice = price;
+ newItems[len].quantity=qty;
+ $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00');
+ });
+ $('#submitNewOrder').show();
+ });
+ });
+}
/**
* lists all orders for the selected buyer
*/
function listOrders()
{
- var options = {};
- // get the users email address
-
- // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily
-
- // get their orders
-
- // if they have no orders, then display a message to that effect
-
- // if they have orders, format and display the orders.
-
+ let options = {};
+ // get the users email address
+
+ // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily
+ // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem)
+ // {
+ // get their orders
+ options.userID = options.id;
+ // options.userID = _mem.userID; options.secret = _mem.secret;
+ $.when($.post('/composer/client/getMyOrders', options)).done(function(_results)
+ {
+ if ((typeof(_results.orders) === 'undefined') || (_results.orders === null))
+ {console.log('error getting orders: ', _results);}
+ else
+ {// if they have no orders, then display a message to that effect
+ if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));}
+ // if they have orders, format and display the orders.
+ else{formatOrders($('#orderDiv'), _results.orders);}
+ }
+ });
+ // });
}
+
/**
* used by the listOrders() function
* formats the orders for a buyer. Orders to be formatted are provided in the _orders array
* output replaces the current contents of the html element identified by _target
- * @param _target - string with div id prefaced by #
- * @param _orders - array with order objects
+ * @param {String} _target - string with div id prefaced by #
+ * @param {Array} _orders - array with order objects
*/
function formatOrders(_target, _orders)
{
- _target.empty();
- let _str = ""; let _date = "";
- for (let each in _orders)
- {(function(_idx, _arr)
- { _action = '
';
-//
-// each order can have different states and the action that a buyer can take is directly dependent on the state of the order.
-// this switch/case table displays selected order information based on its current status and displays selected actions, which
-// are limited by the sate of the order.
-//
-// Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)'
-// These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file
-// associated with the language selected by the web user.
-//
- switch (JSON.parse(_arr[_idx].status).code)
- {
+ _target.empty();
+ let _str = ''; let _date = '';
+ for (let each in _orders)
+ {(function(_idx, _arr)
+ {let _action = '
';
+ //
+ // each order can have different states and the action that a buyer can take is directly dependent on the state of the order.
+ // this switch/case table displays selected order information based on its current status and displays selected actions, which
+ // are limited by the sate of the order.
+ //
+ // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)'
+ // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file
+ // associated with the language selected by the web user.
+ //
+ switch (JSON.parse(_arr[_idx].status).code)
+ {
case orderStatus.PayRequest.code:
-
- break;
+ _date = _arr[_idx].paymentRequested;
+ _action += '';
+ _action += '';
+ r_string = ' '+textPrompts.orderProcess.Dispute.prompt+'';
+ break;
case orderStatus.Delivered.code:
break;
@@ -187,35 +224,43 @@ function formatOrders(_target, _orders)
break;
default:
- break;
- }
- _button = '
'
- for (let every in _arr[_idx].items)
- {(function(_idx2, _arr2)
- { let _item = JSON.parse(_arr2[_idx2]);
- _str += '
'+_item.itemNo+'
'+_item.description+'
'+_item.quantity+'
$'+_item.extendedPrice+'.00
';
- })(every, _arr[_idx].items)
- }
- _str += '
';
- })(each, _orders)
- }
- // append the newly built order table to the web page
- _target.append(_str);
- //
- // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced.
- // iterate through the page and make all of the different parts of the page active.
- //
- for (let each in _orders)
- {(function(_idx, _arr)
- { $("#b_btn_"+_idx).on('click', function ()
+ break;
+ }
+ let _button = '
'
+ for (let every in _arr[_idx].items)
{
-
+ (function(_idx2, _arr2)
+ { let _item = JSON.parse(_arr2[_idx2]);
+ _str += '
'+_item.itemNo+'
'+_item.description+'
'+_item.quantity+'
$'+_item.extendedPrice+'.00
';
+ })(every, _arr[_idx].items);
+ }
+ _str += '
';
+ })(each, _orders);
+ }
+ // append the newly built order table to the web page
+ _target.append(_str);
+ //
+ // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced.
+ // iterate through the page and make all of the different parts of the page active.
+ //
+ for (let each in _orders)
+ {(function(_idx, _arr)
+ { $('#b_btn_'+_idx).on('click', function ()
+ {
+ let options = {};
+ options.action = $('#b_action'+_idx).find(':selected').text();
+ options.orderNo = $('#b_order'+_idx).text();
+ options.participant = $('#buyer').val();
+ if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();}
+ $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo));
+ $.when($.post('/composer/client/orderAction', options)).done(function (_results)
+ { $('#buyer_messages').prepend(formatMessage(_results.result)); });
});
- })(each, _orders)
- }
+ })(each, _orders)
+ }
}
\ No newline at end of file
diff --git a/Chapter06/HTML/js/z2b-events.js b/Chapter06/HTML/js/z2b-events.js
index f93de96..1b67217 100644
--- a/Chapter06/HTML/js/z2b-events.js
+++ b/Chapter06/HTML/js/z2b-events.js
@@ -58,6 +58,7 @@ function deferredMemberLoad()
$.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2),
$.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers)
{
+ console.log('buyers: ',_buyers);
buyers = _buyers[0].members;
sellers = _sellers[0].members;
s_string = _getMembers(sellers);
diff --git a/Chapter06/HTML/js/z2b-initiate.js b/Chapter06/HTML/js/z2b-initiate.js
index b566a28..290ef03 100644
--- a/Chapter06/HTML/js/z2b-initiate.js
+++ b/Chapter06/HTML/js/z2b-initiate.js
@@ -46,7 +46,7 @@ var orderStatus = {
{
// goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English
goMultiLingual("US_English", "index");
- // memberLoad loads the members already present in the network
+ // singleUX loads the members already present in the network
memberLoad();
// goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring
getChainEvents();
diff --git a/Chapter06/HTML/removeMember.html b/Chapter06/HTML/removeMember.html
index 718b809..63adcf5 100644
--- a/Chapter06/HTML/removeMember.html
+++ b/Chapter06/HTML/removeMember.html
@@ -5,7 +5,7 @@
-
+
diff --git a/Chapter06/buildAndDeploy b/Chapter06/buildAndDeploy
index fad9c34..83c72bb 100755
--- a/Chapter06/buildAndDeploy
+++ b/Chapter06/buildAndDeploy
@@ -51,6 +51,4 @@ showStep "creating archive"
showStep "starting network"
./startup.sh
showStep "deploying network"
-./deployNetwork.sh -n $NETWORK_NAME
-showStep "copying credentials"
-cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store
\ No newline at end of file
+./deployNetwork.sh -n $NETWORK_NAME
\ No newline at end of file
diff --git a/Chapter06/controller/env.json b/Chapter06/controller/env.json
index 0afea4b..dd1c45d 100644
--- a/Chapter06/controller/env.json
+++ b/Chapter06/controller/env.json
@@ -7,7 +7,9 @@
"adminPW": "adminpw",
"PeerAdmin": "PeerAdmin",
"PeerPW": "randomString",
- "NS": "org.acme.Z2BTestNetwork"
+ "NS": "org.acme.Z2BTestNetwork",
+ "adminCard": "admin@zerotoblockchain-network",
+ "PeerCard": "PeerAdmin@hlfv1"
},
"fabric":
{
@@ -21,5 +23,24 @@
"peerEventURL": "grpc://localhost:7053",
"ordererURL" : "grpc://localhost:7050",
"caURL": "http://localhost:7054"
+ },
+ "metaData":
+ { "version": 1,
+ "userName": "temp",
+ "roles": [ ],
+ "businessNetwork":"",
+ "enrollmentSecret": "temp"
+ },
+ "connectionProfile":
+ {
+ "name": "hlfv1",
+ "type": "hlfv1",
+ "orderers": [ { "url": "grpc://localhost:7050" } ],
+ "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" },
+ "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ],
+ "keyValStore": "/.composer-credentials",
+ "channel": "composerchannel",
+ "mspID": "Org1MSP",
+ "timeout": 300
}
}
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/features/composer/autoLoad.js b/Chapter06/controller/restapi/features/composer/autoLoad.js
index 1f5214f..ce3d81b 100644
--- a/Chapter06/controller/restapi/features/composer/autoLoad.js
+++ b/Chapter06/controller/restapi/features/composer/autoLoad.js
@@ -14,62 +14,57 @@
/**
* This file is used to automatically populate the network with Order assets and members
- * The opening section loads node modules required for this set of nodejs services
- * to work. Most of these are from the hyperledger composer SDK. This module also
+ * The opening section loads node modules required for this set of nodejs services
+ * to work. Most of these are from the hyperledger composer SDK. This module also
* uses services created specifically for this tutorial, in the Z2B_Services.js
- * and Z2B_Utilities.js modules.
+ * and Z2B_Utilities.js modules.
*/
'use strict';
-const BrowserFS = require('browserfs/dist/node/index');
-const network = 'zerotoblockchain-network';
-var fs = require('fs');
-var path = require('path');
+const fs = require('fs');
+const path = require('path');
+const _home = require('os').homedir();
+const hlc_idCard = require('composer-common').IdCard;
-const composerAdmin = require('composer-admin');
const AdminConnection = require('composer-admin').AdminConnection;
-const composerClient = require('composer-client');
-const composerCommon = require('composer-common');
-const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
const financeCoID = 'easymoney@easymoneyinc.com';
const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
const config = require('../../../env.json');
-const NS = 'org.acme.Z2BTestNetwork';
/**
- * itemTable and memberTable are used by the server to reduce load time requests
+ * itemTable and memberTable are used by the server to reduce load time requests
* for member secrets and item information
*/
let itemTable = new Array();
let memberTable = new Array();
-let orderStatus = svc.orderStatus;
+let socketAddr;
+
+
-let connection; let socketAddr;
/**
- * getPort is used to return the port number for socket interactions so that
- * the browser can receive asynchronous notifications of work in process.
- * This helps the user understand the current status of the auto load process.
+ * getPort is used to return the port number for socket interactions so that
+ * the browser can receive asynchronous notifications of work in process.
+ * This helps the user understand the current status of the auto load process.
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- *
+ *
* @function
*/
exports.getPort = function(req, res, next) {
let _conn = svc.createMessageSocket();
res.send({'port': _conn.socket});
-}
+};
/**
- * autoLoad reads the memberList.json file from the Startup folder and adds members,
+ * autoLoad reads the memberList.json file from the Startup folder and adds members,
* executes the identity process, and then loads orders
- *
+ *
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
@@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) {
let businessNetworkConnection;
let factory; let participant;
svc.createMessageSocket();
- connection = svc.m_connection;
socketAddr = svc.m_socketAddr;
let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {
+ // a businessNetworkConnection is required to add members
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- // a businessNetworkConnection is required to add members
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- // a factory is required to build the member object
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- //iterate through the list of members in the memberList.json file and
- // first add the member to the network, then create an identity for
- // them. This generates the memberList.txt file later used for
- // retrieving member secrets.
- for (let each in startupFile.members)
- {(function(_idx, _arr)
- {
- // the participant registry is where member information is first stored
- // there are individual registries for each type of participant, or member.
- // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type)
- .then(function(participantRegistry){
- return participantRegistry.get(_arr[_idx].id)
- .then((_res) => {
- console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- })
- .catch((error) => {
- participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id);
- participant.companyName = _arr[_idx].companyName;
- participantRegistry.add(participant)
- .then(() => {
- console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added");
- svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added");
- })
- .then(() => {
- // an identity is required before a member can take action in the network.
- return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw)
- .then((result) => {
- let _mem = _arr[_idx];
- _mem.secret = result.userSecret;
- _mem.userID = result.userID;
- memberTable.push(_mem);
- svc.saveMemberTable(memberTable);
- })
- .catch((error) => {
- console.error('create id for '+_arr[_idx].id+'failed.',error.message);
- });
- })
- .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);});
- });
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error.message)});
- })(each, startupFile.members)
- }
- // iterate through the order objects in the memberList.json file.
- for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)}
- svc.saveItemTable(itemTable);
- for (let each in startupFile.assets)
- {(function(_idx, _arr)
- {
- // each type of asset, like each member, gets it's own registry. Our application
- // has only one type of asset: "Order"
- return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type)
- .then((assetRegistry) => {
- return assetRegistry.get(_arr[_idx].id)
- .then((_res) => {
- console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type);
- })
- .catch((error) => {
- // first, an Order Object is created
- let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id);
- order = svc.createOrderTemplate(order);
- let _tmp = svc.addItems(_arr[_idx], itemTable);
- order.items = _tmp.items;
- order.amount = _tmp.amount;
- order.orderNumber = _arr[_idx].id;
- // then the buy transaction is created
- const createNew = factory.newTransaction(NS, 'CreateOrder');
- order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer);
- order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller);
- order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
- order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
- order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
- createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer);
- createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller);
- createNew.amount = order.amount;
- // then the order is added to the asset registry.
- return assetRegistry.add(order)
- .then(() => {
- // then a createOrder transaction is processed which uses the chaincode
- // establish the order with it's initial transaction state.
- svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection);
- })
+ // a factory is required to build the member object
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ //iterate through the list of members in the memberList.json file and
+ // first add the member to the network, then create an identity for
+ // them. This generates the memberList.txt file later used for
+ // retrieving member secrets.
+ for (let each in startupFile.members)
+ {(function(_idx, _arr)
+ {
+ // the participant registry is where member information is first stored
+ // there are individual registries for each type of participant, or member.
+ // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo
+ return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type)
+ .then(function(participantRegistry){
+ return participantRegistry.get(_arr[_idx].id)
+ .then((_res) => {
+ console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ })
+ .catch((error) => {
+ participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id);
+ participant.companyName = _arr[_idx].companyName;
+ participantRegistry.add(participant)
+ .then(() => {
+ console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added');
+ svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added');
+ })
+ .then(() => {
+ // an identity is required before a member can take action in the network.
+ // V0.14
+ // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw)
+ // V0.15
+ console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id);
+ return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id)
+ .then((result) => {
+ console.log('_arr[_idx].id: '+_arr[_idx].id);
+ console.log('result.userID: '+result.userID);
+ let _mem = _arr[_idx];
+ _mem.secret = result.userSecret;
+ _mem.userID = result.userID;
+ memberTable.push(_mem);
+ // svc.saveMemberTable(memberTable);
+ let _meta = {};
+ for (each in config.composer.metaData)
+ {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); }
+ _meta.businessNetwork = config.composer.network;
+ _meta.userName = result.userID;
+ _meta.enrollmentSecret = result.userSecret;
+ config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore;
+ let tempCard = new hlc_idCard(_meta, config.connectionProfile);
+ return adminConnection.importCard(result.userID, tempCard)
+ .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} })
.catch((error) => {
- // in the development environment, because of how timing is set up, it is normal to
- // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a
- // logical transaction error.
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id);
- svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection);
- }
- else {console.log('error with assetRegistry.add', error.message)}
+ console.error('adminConnection.importCard failed. ',error.message);
});
- });
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error.message)});
- })(each, startupFile.assets)
- }
+ })
+ .catch((error) => {
+ console.error('create id for '+_arr[_idx].id+'failed. ',error.message);
+ });
+ })
+ .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);});
+ });
+ })
+ .catch((error) => {console.log('error with getParticipantRegistry', error.message);});
+ })(each, startupFile.members);
+ }
+ // iterate through the order objects in the memberList.json file.
+ for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);}
+ svc.saveItemTable(itemTable);
+ for (let each in startupFile.assets)
+ {(function(_idx, _arr)
+ {
+ // each type of asset, like each member, gets it's own registry. Our application
+ // has only one type of asset: 'Order'
+ return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type)
+ .then((assetRegistry) => {
+ return assetRegistry.get(_arr[_idx].id)
+ .then((_res) => {
+ console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type);
+ })
+ .catch((error) => {
+ // first, an Order Object is created
+ let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id);
+ order = svc.createOrderTemplate(order);
+ let _tmp = svc.addItems(_arr[_idx], itemTable);
+ order.items = _tmp.items;
+ order.amount = _tmp.amount;
+ order.orderNumber = _arr[_idx].id;
+ // then the buy transaction is created
+ const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder');
+ order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer);
+ order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller);
+ order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy');
+ order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy');
+ order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID);
+ createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID);
+ createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier);
+ createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer);
+ createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller);
+ createNew.amount = order.amount;
+ // then the order is added to the asset registry.
+ return assetRegistry.add(order)
+ .then(() => {
+ // then a createOrder transaction is processed which uses the chaincode
+ // establish the order with it's initial transaction state.
+ svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection);
+ })
+ .catch((error) => {
+ // in the development environment, because of how timing is set up, it is normal to
+ // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a
+ // logical transaction error.
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id);
+ svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection);
+ }
+ else {console.log('error with assetRegistry.add', error.message);}
+ });
+ });
})
- .catch((error) => {console.log('error with business network Connect', error.message)});
+ .catch((error) => {console.log('error with getParticipantRegistry', error.message);});
+ })(each, startupFile.assets);
+ }
})
- .catch((error) => {console.log('error with adminConnect', error.message)});
- res.send({'port': socketAddr});
-}
+ .catch((error) => {console.log('error with business network Connect', error.message);});
+ })
+ .catch((error) => {console.log('error with adminConnect', error.message);});
+ res.send({'port': socketAddr});
+};
/**
* get member secret from member table. In normal production, the use would be responsible
* for knowing their member secret. Because this is a demo, we're managing that informaiton
* on the server and this routine gets that information for us so that we can successfully
- * execute transactions.
+ * execute transactions.
* @param {express.req} req - the inbound request object from the client
* req.body.id - the id of the member to find
* @param {express.res} res - the outbound response object for communicating back to client
@@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next)
{
let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
let _table = JSON.parse(fs.readFileSync(newFile));
- let bFound = false;
+ let bFound = false;
for (let each in _table.members)
- { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}}
- if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});}
-}
\ No newline at end of file
+ { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}}
+ if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});}
+};
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/features/composer/hlcAdmin.js b/Chapter06/controller/restapi/features/composer/hlcAdmin.js
index 27b12a3..8e9e8b9 100644
--- a/Chapter06/controller/restapi/features/composer/hlcAdmin.js
+++ b/Chapter06/controller/restapi/features/composer/hlcAdmin.js
@@ -16,19 +16,16 @@
'use strict';
const fs = require('fs');
const path = require('path');
+const _home = require('os').homedir();
+const hlc_idCard = require('composer-common').IdCard;
const composerAdmin = require('composer-admin');
const AdminConnection = require('composer-admin').AdminConnection;
-const composerClient = require('composer-client');
-const composerCommon = require('composer-common');
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const Serializer = require('composer-common').Serializer;
const config = require('../../../env.json');
const NS = 'org.acme.Z2BTestNetwork';
-const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
-var orderStatus = svc.orderStatus;
-
+// const svc = require('./Z2B_Services');
+// const mod = 'hlcAdmin.js';
/**
* display the admin and network info
@@ -56,7 +53,10 @@ exports.adminNew = function() {
*/
exports.adminConnect = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(function(){
console.log('create connection successful ');
res.send({connection: 'succeeded'});
@@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) {
* @function
*/
exports.createProfile = function(req, res, next) {
- let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL',
- 'keyValStore', 'channel', 'mspID', 'timeout'];
-
let adminOptions = {
type: req.body.type,
keyValStore: req.body.keyValStore,
@@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) {
peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}]
};
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.createProfile(req.body.profileName, adminOptions)
- .then(function(result){
- console.log('create profile successful: ');
- res.send({profile: 'succeeded'});
- })
- .catch(function(error){
- console.log('create profile failed: ',error);
- res.send({profile: error});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.createProfile(req.body.profileName, adminOptions)
+ .then(function(result){
+ console.log('create profile successful: ');
+ res.send({profile: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('create profile failed: ',error);
+ res.send({profile: error});
+ });
+ });
};
/**
* Deletes the specified connection profile from the profile store being used by this AdminConnection.
@@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) {
*/
exports.deleteProfile = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.deleteProfile(req.body.profileName)
- .then(function(result){
- console.log('delete profile successful: ',result);
- res.send({profile: 'succeeded'});
- })
- .catch(function(error){
- console.log('delete profile failed: ',error);
- res.send({profile: error});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.deleteProfile(req.body.profileName)
+ .then(function(result){
+ console.log('delete profile successful: ',result);
+ res.send({profile: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('delete profile failed: ',error);
+ res.send({profile: error});
+ });
+ });
};
+
/**
* Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
* @param {express.req} req - the inbound request object from the client
@@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.deploy = function(req, res, next) {
- let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
- let adminConnection = new composerAdmin.AdminConnection();
+ let adminConnection = new composerAdmin.AdminConnection();
- return BusinessNetworkDefinition.fromArchive(archiveFile)
- .then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.deploy(archive)
- .then(function(){
- console.log('business network '+req.body.myArchive+' deployed successful: ');
- res.send({deploy: req.body.myArchive+' deploy succeeded'});
- })
- .catch(function(error){
- console.log('business network '+req.body.myArchive+' deploy failed: ',error);
- res.send({deploy: error});
- });
+ return BusinessNetworkDefinition.fromArchive(archiveFile)
+ .then(function(archive) {
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.deploy(archive)
+ .then(function(){
+ console.log('business network '+req.body.myArchive+' deployed successful: ');
+ res.send({deploy: req.body.myArchive+' deploy succeeded'});
+ })
+ .catch(function(error){
+ console.log('business network '+req.body.myArchive+' deploy failed: ',error);
+ res.send({deploy: error});
});
- });
- };
+ });
+ });
+};
/**
* Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
* @param {express.req} req - the inbound request object from the client
@@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.networkInstall = function(req, res, next) {
@@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((businessNetworkDefinition) => {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(() => {
return adminConnection.install(businessNetworkDefinition.getName())
.then(() => {
@@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) {
.catch((error) => {
console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message);
res.send({install: error.message});
- });
- })
- .catch((error) => {console.log('error with adminConnection.connect', error.message)
- res.send({install: error.message});
});
- })
- .catch((error) => {console.log('error with fromArchive', error.message)});
+ })
+ .catch((error) => {console.log('error with adminConnection.connect', error.message);
+ res.send({install: error.message});
+ });
+ })
+ .catch((error) => {console.log('error with fromArchive', error.message);
res.send({install: error.message});
- }
+ });
+};
/**
* Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
@@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) {
* req.body.deployOptions: _object - string name of object
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.networkStart = function(req, res, next) {
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive));
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
.then(function(){
adminConnection.start(archive)
.then(function(){
@@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) {
.catch(function(error){
console.log('business network '+req.body.myArchive+' install failed: ',error);
res.send({install: error});
- });
- });
+ });
});
- };
+ });
+};
/**
* disconnects this connection
@@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) {
*/
exports.disconnect = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.disconnect()
- .then(function(result){
- console.log('network disconnect successful: ');
- res.send({disconnect: 'succeeded'});
- })
- .catch(function(error){
- console.log('network disconnect failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.disconnect()
+ .then(function(result){
+ console.log('network disconnect successful: ');
+ res.send({disconnect: 'succeeded'});
+ })
+ .catch(function(error){
+ console.log('network disconnect failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* Retrieve all connection profiles from the profile store being used by this AdminConnection.
@@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) {
*/
exports.getAllProfiles = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.getAllProfiles()
- .then((profiles) => {
- res.send(profiles);
- })
- .catch(function(error){
- console.log('network disconnect failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.getAllProfiles()
+ .then((profiles) => {
+ res.send(profiles);
+ })
+ .catch(function(error){
+ console.log('network disconnect failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* Retrieve the specified connection profile from the profile store being used by this AdminConnection.
@@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) {
*/
exports.getProfile = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.getProfile(req.body.connectionProfile)
- .then((profile) => {
- console.log('get profile Succeeded: ',profile);
- res.send(profile);
- })
- .catch(function(error){
- console.log('get profile failed: ',error);
- res.send(error);
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.getProfile(req.body.connectionProfile)
+ .then((profile) => {
+ console.log('get profile Succeeded: ',profile);
+ res.send(profile);
+ })
+ .catch(function(error){
+ console.log('get profile failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* List all of the deployed business networks. The connection must be connected for this method to succeed.
@@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) {
*/
exports.listAsAdmin = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- util.displayObjectValuesRecursive(adminConnection);
// updated to use PeerAdmin, PeerPW to work with V0.14
- adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW)
- .then(function(){
- adminConnection.list()
- .then((businessNetworks) => {
- // Connection has been tested
- businessNetworks.forEach((businessNetwork) => {
- console.log('Deployed business network', businessNetwork);
- });
- res.send(businessNetworks);
- })
- .catch(function(_error){
- let error = _error;
- console.log('get business networks failed: ',error);
- res.send(error);
- });
- });
-};
-/**
- * List all of the deployed business networks. The connection must be connected for this method to succeed.
- * @param {express.req} req - the inbound request object from the client
- * @param {express.res} res - the outbound response object for communicating back to client
- * @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
- * @function
- */
-exports.listAsPeerAdmin = function(req, res, next) {
- let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(function(){
- adminConnection.list()
- .then((businessNetworks) => {
- // Connection has been tested
- businessNetworks.forEach((businessNetwork) => {
- console.log('Deployed business network', businessNetwork);
- });
- res.send(businessNetworks);
- })
- .catch(function(_error){
- let error = _error;
- console.log('get business networks failed: ',error);
- res.send(error);
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ console.log('config.composer.PeerCard: '+config.composer.PeerCard);
+ adminConnection.connect(config.composer.PeerCard)
+ .then(function(){
+ adminConnection.list()
+ .then((businessNetworks) => {
+ // Connection has been tested
+ businessNetworks.forEach((businessNetwork) => {
+ console.log('Deployed business network', businessNetwork);
});
- });
+ res.send(businessNetworks);
+ })
+ .catch(function(_error){
+ let error = _error;
+ console.log('get business networks failed: ',error);
+ res.send(error);
+ });
+ });
};
/**
* Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module.
@@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) {
*/
exports.ping = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork)
- .then(function(){
- adminConnection.ping()
- .then(function(result){
- console.log('network ping successful: ',result);
- res.send({ping: result});
- })
- .catch(function(error){
- let _error = error;
- console.log('network ping failed: '+_error);
- res.send({ping: _error.toString()});
- });
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.ping()
+ .then(function(result){
+ console.log('network ping successful: ',result);
+ res.send({ping: result});
+ })
+ .catch(function(error){
+ let _error = error;
+ console.log('network ping failed: '+_error);
+ res.send({ping: _error.toString()});
+ });
+ });
};
/**
* Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions.
@@ -388,19 +391,22 @@ exports.ping = function(req, res, next) {
*/
exports.undeploy = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork)
- .then(function(){
- adminConnection.undeploy(req.body.businessNetwork)
- .then(function(result){
- console.log(req.body.businessNetwork+' network undeploy successful ');
- res.send({undeploy: req.body.businessNetwork+' network undeploy successful '});
- })
- .catch(function(error){
- let _error = error;
- console.log(req.body.businessNetwork+' network undeploy failed: '+_error);
- res.send({undeploy: _error.toString()});
- });
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.undeploy(req.body.businessNetwork)
+ .then(function(result){
+ console.log(req.body.businessNetwork+' network undeploy successful ');
+ res.send({undeploy: req.body.businessNetwork+' network undeploy successful '});
+ })
+ .catch(function(error){
+ let _error = error;
+ console.log(req.body.businessNetwork+' network undeploy failed: '+_error);
+ res.send({undeploy: _error.toString()});
});
+ });
};
/**
* Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed.
@@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) {
* req.body.myArchive: _string - name of archive to deploy
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns composerAdmin.connection - either an error or a connection object
+ * @returns {composerAdmin.connection} - either an error or a connection object
* @function
*/
exports.update = function(req, res, next) {
@@ -419,21 +425,24 @@ exports.update = function(req, res, next) {
let adminConnection = new composerAdmin.AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
- .then(function(archive) {
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName)
- .then(function(){
- adminConnection.update(archive)
- .then(function(){
- console.log(netName+' network update successful: ');
- res.send({update: req.body.myArchive+' network update successful '});
- })
- .catch(function(error){
- let _error = error;
- console.log(req.body.myArchive+' network update failed: '+_error);
- res.send({update: _error.toString()});
- });
- });
+ .then(function(archive) {
+ // connection prior to V0.15
+ // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ adminConnection.connect(config.composer.adminCard)
+ .then(function(){
+ adminConnection.update(archive)
+ .then(function(){
+ console.log(netName+' network update successful: ');
+ res.send({update: req.body.myArchive+' network update successful '});
+ })
+ .catch(function(error){
+ let _error = error;
+ console.log(req.body.myArchive+' network update failed: '+_error);
+ res.send({update: _error.toString()});
+ });
});
+ });
};
/**
@@ -441,7 +450,7 @@ exports.update = function(req, res, next) {
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns array of registries
+ * @returns {Object} array of registries
* @function
*/
exports.getRegistries = function(req, res, next)
@@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next)
// connect to the network
let allRegistries = new Array();
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getAllParticipantRegistries()
- .then(function(participantRegistries){
- for (let each in participantRegistries)
- { (function (_idx, _arr)
- { let r_type = _arr[_idx].name.split('.');
- allRegistries.push([r_type[r_type.length-1]]);
- })(each, participantRegistries)
- }
- res.send({'result': 'success', 'registries': allRegistries});
- })
- .catch((error) => {console.log('error with getAllRegistries', error)});
- })
- .catch((error) => {console.log('error with business network Connect', error)});
+ return businessNetworkConnection.getAllParticipantRegistries()
+ .then(function(participantRegistries){
+ for (let each in participantRegistries)
+ { (function (_idx, _arr)
+ {
+ let r_type = _arr[_idx].name.split('.');
+ allRegistries.push([r_type[r_type.length-1]]);
+ })(each, participantRegistries);
+ }
+ res.send({'result': 'success', 'registries': allRegistries});
+ })
+ .catch((error) => {console.log('error with getAllRegistries', error);});
})
- .catch((error) => {console.log('error with admin network Connect', error)});
-}
+ .catch((error) => {console.log('error with business network Connect', error);});
+};
/**
* retrieve array of members from specified registry type
@@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next)
* req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of members
+ * @returns {Object} an array of members
* @function
*/
exports.getMembers = function(req, res, next) {
// connect to the network
+ // let method = 'getMembers';
let allMembers = new Array();
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
- .then(function(registry){
- return registry.getAll()
- .then ((members) => {
- for (let each in members)
- { (function (_idx, _arr)
- { let _jsn = {};
- _jsn.type = req.body.registry;
- _jsn.companyName = _arr[_idx].companyName;
- switch (req.body.registry)
- {
- case 'Buyer':
- _jsn.id = _arr[_idx].buyerID;
- break;
- case 'Seller':
- _jsn.id = _arr[_idx].sellerID;
- break;
- case 'Provider':
- _jsn.id = _arr[_idx].providerID;
- break;
- case 'Shipper':
- _jsn.id = _arr[_idx].shipperID;
- break;
- case 'FinanceCo':
- _jsn.id = _arr[_idx].financeCoID;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allMembers.push(_jsn); })(each, members)
- }
- res.send({'result': 'success', 'members': allMembers});
- })
- .catch((error) => {console.log('error with getAllMembers', error);
- res.send({'result': 'failed '+error.message, 'members': []});});
- })
- .catch((error) => {console.log('error with getRegistry', error);
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
+ .then(function(registry){
+ return registry.getAll()
+ .then ((members) => {
+ for (let each in members)
+ { (function (_idx, _arr)
+ { let _jsn = {};
+ _jsn.type = req.body.registry;
+ _jsn.companyName = _arr[_idx].companyName;
+ switch (req.body.registry)
+ {
+ case 'Buyer':
+ _jsn.id = _arr[_idx].buyerID;
+ break;
+ case 'Seller':
+ _jsn.id = _arr[_idx].sellerID;
+ break;
+ case 'Provider':
+ _jsn.id = _arr[_idx].providerID;
+ break;
+ case 'Shipper':
+ _jsn.id = _arr[_idx].shipperID;
+ break;
+ case 'FinanceCo':
+ _jsn.id = _arr[_idx].financeCoID;
+ break;
+ default:
+ _jsn.id = _arr[_idx].id;
+ }
+ allMembers.push(_jsn); })(each, members);
+ }
+ res.send({'result': 'success', 'members': allMembers});
+ })
+ .catch((error) => {console.log('error with getAllMembers', error);
res.send({'result': 'failed '+error.message, 'members': []});});
- })
- .catch((error) => {console.log('error with business network Connect', error.message);
- res.send({'result': 'failed '+error.message, 'members': []});});
+ })
+ .catch((error) => {console.log('error with getRegistry', error);
+ res.send({'result': 'failed '+error.message, 'members': []});});
})
- .catch((error) => {console.log('error with admin network Connect', error);
- res.send({'result': 'failed '+error.message, 'members': []});});
+ .catch((error) => {console.log('error with business network Connect', error.message);
+ res.send({'result': 'failed '+error.message, 'members': []});});
+};
-}
+/**
+ * Checks to see if the provided id already has a card issued for it
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * returns {object} - a JSON object
+ * @function
+ */
+exports.checkCard = function(req, res, next) {
+ let adminConnection = new AdminConnection();
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {adminConnection.hasCard(req.body.id)
+ .then((_res) => {
+ let cardState = ((_res) ? 'exists' : 'does not exist');
+ res.send({'result': 'success', 'card': cardState});
+ })
+ .catch((error) => {
+ res.send({'result': 'failed', 'message': error.message});
+ });
+ })
+ .catch((error) => {
+ res.send({'result': 'admin Connect failed', 'message': error.message});
+ });
+};
+
+/**
+ * Creates a card for an existing member
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * req.body.pw - the pw of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * returns {object} - a JSON object
+ * @function
+ */
+exports.createCard = function(req, res, next) {
+ let adminConnection = new AdminConnection();
+ let _meta = {};
+ for (let each in config.composer.metaData)
+ {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); }
+ _meta.businessNetwork = config.composer.network;
+ _meta.userName = req.body.id;
+ _meta.enrollmentSecret = req.body.secret;
+ config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore;
+ let tempCard = new hlc_idCard(_meta, config.connectionProfile);
+ adminConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return adminConnection.importCard(req.body.id, tempCard)
+ .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported');
+ console.log('create Card succeeded:'+_msg);
+ res.send({'result': 'success', 'card': _msg});
+ })
+ .catch((error) => {
+ console.error('adminConnection.importCard failed. ',error.message);
+ res.send({'result': 'failed', 'error': error.message});
+ });
+ })
+ .catch((error) => {
+ console.error('adminConnection.connect failed. ',error.message);
+ res.send({'result': 'failed', 'error': error.message});
+ });
+};
+
+/**
+ * creates an identity for a member already created in a member registry
+ * @param {express.req} req - the inbound request object from the client
+ * req.body.id - the id of the individual making the request
+ * req.body.type - the member type of the individual making the request
+ * @param {express.res} res - the outbound response object for communicating back to client
+ * @param {express.next} next - an express service to enable post processing prior to responding to the client
+ * @returns {object} - a JSON object
+ * @function
+ */
+exports.issueIdentity = function(req, res, next) {
+ let businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id);
+ return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id)
+ .then((result) => {
+ console.log('result.userID: '+result.userID);
+ console.log('result.userSecret: '+result.userSecret);
+ res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret});
+ })
+ .catch((error) => {
+ res.send({'result': 'failed', 'message': error.message});
+ });
+ })
+ .catch((error) => {
+ res.send({'result': 'business network Connect failed', 'message': error.message});
+ });
+};
/**
* gets the assets from the order registry
@@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) {
* req.body.id - the id of the individual making the request
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} - an array of assets
* @function
*/
exports.getAssets = function(req, res, next) {
- // connect to the network
- let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json')));
- let allOrders = new Array();
- let businessNetworkConnection;
- let factory;
- let serializer;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
+ // connect to the network
+ let allOrders = new Array();
+ let businessNetworkConnection;
+ let serializer;
+ let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return BusinessNetworkDefinition.fromArchive(archiveFile)
+ .then((bnd) => {
+ serializer = bnd.getSerializer();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
.then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
-// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON);
-// retry this with fromArchive when time allows
-// serializer = bnd.getSerializer();
- return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry)
- .then(function(registry){
- return registry.getAll()
- .then ((members) => {
- console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace);
- for (let each in members)
- { (function (_idx, _arr)
+ return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry)
+ .then(function(registry){
+ return registry.getAll()
+ .then ((members) => {
+ console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace);
+ for (let each in members)
+ { (function (_idx, _arr)
+ {
+ switch(req.body.type)
+ {
+ case 'Buyer':
+ if (req.body.id === _arr[_idx].buyer.$identifier)
{
- switch(req.body.type)
+ let _jsn = serializer.toJSON(_arr[_idx]);
+ _jsn.type = req.body.registry;
+ switch (req.body.registry)
{
- case 'Buyer':
- if (req.body.id == _arr[_idx].buyer.$identifier)
- {
- let _jsn = svc.getOrderData(_arr[_idx]);
- _jsn.type = req.body.registry;
- switch (req.body.registry)
- {
- case 'Order':
- _jsn.id = _arr[_idx].orderNumber;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allOrders.push(_jsn);
- }
- break;
- case 'admin':
- let _jsn = svc.getOrderData(_arr[_idx]);
- _jsn.type = req.body.registry;
- switch (req.body.registry)
- {
- case 'Order':
- _jsn.id = _arr[_idx].orderNumber;
- break;
- default:
- _jsn.id = _arr[_idx].id;
- }
- allOrders.push(_jsn);
- break;
- default:
+ case 'Order':
+ _jsn.id = _arr[_idx].orderNumber;
break;
+ default:
+ _jsn.id = _arr[_idx].id;
}
- })(each, members)
+ allOrders.push(_jsn);
+ }
+ break;
+ case 'admin':
+ let _jsn = serializer.toJSON(_arr[_idx]);
+ _jsn.type = req.body.registry;
+ switch (req.body.registry)
+ {
+ case 'Order':
+ _jsn.id = _arr[_idx].orderNumber;
+ break;
+ default:
+ _jsn.id = _arr[_idx].id;
+ }
+ allOrders.push(_jsn);
+ break;
+ default:
+ break;
}
- res.send({'result': 'success', 'orders': allOrders});
- })
- .catch((error) => {console.log('error with getAllOrders', error)
- res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message});
- });
- })
- .catch((error) => {console.log('error with getRegistry', error)
- res.send({'result': 'failed', 'error': 'getRegistry: '+error.message});
- });
+ })(each, members);
+ }
+ res.send({'result': 'success', 'orders': allOrders});
})
- .catch((error) => {console.log('error with business network Connect', error)
- res.send({'result': 'failed', 'error': 'business network Connect: '+error.message});
+ .catch((error) => {console.log('error with getAllOrders', error);
+ res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('error with getRegistry', error);
+ res.send({'result': 'failed', 'error': 'getRegistry: '+error.message});
});
- })
- .catch((error) => {console.log('error with admin network Connect', error)
- res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message});
- });
-}
+ })
+ .catch((error) => {console.log('error with business network Connect', error);
+ res.send({'result': 'failed', 'error': 'business network Connect: '+error.message});
+ });
+ });
+};
/**
* Adds a new member to the specified registry
@@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) {
* req.body.id: _string - id of member to add (email address)
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns JSON object with success or error results
+ * @returns {JSON} object with success or error results
* @function
*/
exports.addMember = function(req, res, next) {
let businessNetworkConnection;
let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type)
- .then(function(participantRegistry){
- return participantRegistry.get(req.body.id)
- .then((_res) => { res.send('member already exists. add cancelled');})
- .catch((_res) => {
- console.log(req.body.id+' not in '+req.body.type+' registry. ');
- let participant = factory.newResource(NS, req.body.type,req.body.id);
- participant.companyName = req.body.companyName;
- participantRegistry.add(participant)
- .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");})
- .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);});
- });
- })
- .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);});
- })
- .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);});
- })
- .catch((error) => {console.log('error with adminConnection', error); res.send(error);});
-}
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type)
+ .then(function(participantRegistry){
+ return participantRegistry.get(req.body.id)
+ .then((_res) => { res.send('member already exists. add cancelled');})
+ .catch((_res) => {
+ console.log(req.body.id+' not in '+req.body.type+' registry. ');
+ let participant = factory.newResource(NS, req.body.type,req.body.id);
+ participant.companyName = req.body.companyName;
+ participantRegistry.add(participant)
+ .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');})
+ .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);});
+ });
+ })
+ .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);});
+ })
+ .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);});
+};
/**
* Removes a member from a registry.
@@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) {
* req.body.id: _string - id of member to delete
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns JSON object with success or error results
+ * @returns {JSON} object with success or error results
* @function
*/
exports.removeMember = function(req, res, next) {
let businessNetworkConnection;
- let factory;
- let adminConnection = new AdminConnection();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
- .then(function(participantRegistry){
- return participantRegistry.get(req.body.id)
- .then((_res) => {
- return participantRegistry.remove(req.body.id)
- .then((_res) => {
- res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.');
- })
- .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
- res.send('member already exists. add cancelled');
- })
- .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry)
+ .then(function(participantRegistry){
+ return participantRegistry.get(req.body.id)
+ .then((_res) => {
+ return participantRegistry.remove(req.body.id)
+ .then((_res) => {
+ res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.');
})
- .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);});
+ .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');
+ res.send('member already exists. add cancelled');
+ });
})
- .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);});
+ .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');});
})
- .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);});
-}
+ .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);});
+ })
+ .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);});
+};
/**
* get Historian Records
@@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) {
* req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of members
+ * @returns {Array} an array of members
* @function
*/
exports.getHistory = function(req, res, next) {
let allHistory = new Array();
let businessNetworkConnection;
- let factory;
let ser;
let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
- let adminConnection = new AdminConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((bnd) => {
ser = bnd.getSerializer();
- adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
- .then(() => {
- return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord')
- .then(function(registry){
- return registry.getAll()
- .then ((history) => {
- for (let each in history)
- { (function (_idx, _arr)
- { let _jsn = _arr[_idx];
- allHistory.push(ser.toJSON(_jsn));
- })(each, history)
- }
- res.send({'result': 'success', 'history': allHistory});
- })
- .catch((error) => {console.log('error with getAll History', error)});
- })
- .catch((error) => {console.log('error with getRegistry', error)});
+ businessNetworkConnection = new BusinessNetworkConnection();
+ // connection prior to V0.15
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
+ // connection in v0.15
+ return businessNetworkConnection.connect(config.composer.adminCard)
+ .then(() => {
+ return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord')
+ .then(function(registry){
+ return registry.getAll()
+ .then ((history) => {
+ for (let each in history)
+ { (function (_idx, _arr)
+ { let _jsn = _arr[_idx];
+ allHistory.push(ser.toJSON(_jsn));
+ })(each, history);
+ }
+ res.send({'result': 'success', 'history': allHistory});
})
- .catch((error) => {console.log('error with business network Connect', error)});
- })
- .catch((error) => {console.log('error with admin network Connect', error)});
+ .catch((error) => {console.log('error with getAll History', error);});
+ })
+ .catch((error) => {console.log('error with getRegistry', error);});
+ })
+ .catch((error) => {console.log('error with business network Connect', error);});
})
- .catch((error) => {console.log('error with business network definition', error)});
-}
+ .catch((error) => {console.log('error with admin network Connect', error);});
+};
diff --git a/Chapter06/controller/restapi/features/composer/hlcClient.js b/Chapter06/controller/restapi/features/composer/hlcClient.js
index d5df87c..0438465 100644
--- a/Chapter06/controller/restapi/features/composer/hlcClient.js
+++ b/Chapter06/controller/restapi/features/composer/hlcClient.js
@@ -14,15 +14,14 @@
'use strict';
-var fs = require('fs');
-var path = require('path');
+let fs = require('fs');
+let path = require('path');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
-const config = require('../../../env.json');
+// const config = require('../../../env.json');
const NS = 'org.acme.Z2BTestNetwork';
let itemTable = null;
const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
const financeCoID = 'easymoney@easymoneyinc.com';
/**
@@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com';
* @param {express.req} req - the inbound request object from the client
* req.body.id - the id of the buyer making the request
* req.body.userID - the user id of the buyer in the identity table making this request
- * req.body.secret - the pw of this user.
+ * req.body.secret - the pw of this user.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.getMyOrders = function (req, res, next) {
// connect to the network
- let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json')));
+ let method = 'getMyOrders';
+ console.log(method+' req.body.userID is: '+req.body.userID );
let allOrders = new Array();
let businessNetworkConnection;
- let factory;
- if (svc.m_connection == null) {svc.createMessageSocket();}
+ if (svc.m_connection === null) {svc.createMessageSocket();}
let ser;
let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
businessNetworkConnection = new BusinessNetworkConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((bnd) => {
ser = bnd.getSerializer();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
- .then(() => {
- return businessNetworkConnection.query('selectOrders')
- .then((orders) => {
- let jsn;
- let allOrders = new Array();
- for (let each in orders)
- { (function (_idx, _arr)
- {
- let _jsn = ser.toJSON(_arr[_idx]);
- _jsn.id = _arr[_idx].orderNumber;
- allOrders.push(_jsn);
- })(each, orders)
- }
- res.send({'result': 'success', 'orders': allOrders});
- })
- .catch((error) => {console.log('selectOrders failed ', error);
- res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});
- });
- })
- .catch((error) => {console.log('businessNetwork connect failed ', error);
- res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
+ //
+ // v0.15
+ console.log(method+' req.body.userID is: '+req.body.userID );
+ return businessNetworkConnection.connect(req.body.userID)
+ .then(() => {
+ return businessNetworkConnection.query('selectOrders')
+ .then((orders) => {
+ allOrders = new Array();
+ for (let each in orders)
+ { (function (_idx, _arr)
+ {
+ let _jsn = ser.toJSON(_arr[_idx]);
+ _jsn.id = _arr[_idx].orderNumber;
+ allOrders.push(_jsn);
+ })(each, orders);
+ }
+ res.send({'result': 'success', 'orders': allOrders});
+ })
+ .catch((error) => {console.log('selectOrders failed ', error);
+ res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});
});
})
- .catch((error) => {console.log('create bnd from archive failed ', error);
+ .catch((error) => {console.log('businessNetwork connect failed ', error);
+ res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('create bnd from archive failed ', error);
res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message});
});
-}
+};
/**
@@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) {
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * return {Array} an array of assets
* @function
*/
exports.getItemTable = function (req, res, next)
{
- if (itemTable == null)
+ if (itemTable === null)
{
- let options = { flag : 'w' };
let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt');
itemTable = JSON.parse(fs.readFileSync(newFile));
}
res.send(itemTable);
-}
+};
+
/**
* orderAction - act on an order for a buyer
* @param {express.req} req - the inbound request object from the client
* req.body.action - string with buyer requested action
- * buyer available actions are:
+ * buyer available actions are:
* Pay - approve payment for an order
* Dispute - dispute an existing order. requires a reason
* Purchase - submit created order to seller for execution
@@ -111,90 +115,91 @@ exports.getItemTable = function (req, res, next)
* req.body.reason - reason for dispute, required for dispute processing to proceed
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.orderAction = function (req, res, next) {
- if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) )
- {let reason = req.body.reason;}
+ let method = 'orderAction';
+ console.log(method+' req.body.participant is: '+req.body.participant );
+ if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) )
+ {/*let reason = req.body.reason;*/}
else {
- if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) ))
- res.send({'result': 'failed', 'error': 'no reason provided for dispute'});
+ if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) ))
+ {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});}
}
- if (svc.m_connection == null) {svc.createMessageSocket();}
+ if (svc.m_connection === null) {svc.createMessageSocket();}
let businessNetworkConnection;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let updateOrder;
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.get(req.body.orderNo)
- .then((order) => {
- let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- order.status = req.body.action;
- switch (req.body.action)
- {
- case 'Dispute':
- console.log('Dispute entered');
-
- break;
- case 'Purchase':
- console.log('Purchase entered');
-
- break;
- case 'Resolve':
- console.log('Resolve entered');
-
- break;
- case 'Authorize Payment':
- console.log('Authorize Payment entered');
-
- break;
- case 'Cancel':
- console.log('Cancel entered');
-
- break;
- default :
- console.log('default entered for action: '+req.body.action);
- res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
- }
- updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
- return businessNetworkConnection.submitTransaction(updateOrder)
- .then(() => {
- console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action);
- res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action});
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(" retrying assetRegistry.update for: "+req.body.orderNo);
- svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
- }
- else
- {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);}
- });
-
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.participant)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.get(req.body.orderNo)
+ .then((order) => {
+ let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ order.status = req.body.action;
+ switch (req.body.action)
+ {
+ case 'Dispute':
+ console.log('Dispute entered');
+ // ========> Your Code Goes Here <=========
+ break;
+ case 'Purchase':
+ console.log('Purchase entered');
+ // ========> Your Code Goes Here <=========
+ break;
+ case 'Resolve':
+ console.log('Resolve entered');
+ // ========> Your Code Goes Here <=========
+ break;
+ case 'Authorize Payment':
+ console.log('Authorize Payment entered');
+ // ========> Your Code Goes Here <=========
+ break;
+ case 'Cancel':
+ console.log('Cancel entered');
+ // ========> Your Code Goes Here <=========
+ break;
+ default :
+ console.log('default entered for action: '+req.body.action);
+ res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
+ }
+ updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
+ return businessNetworkConnection.submitTransaction(updateOrder)
+ .then(() => {
+ console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action);
+ res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action});
})
.catch((error) => {
- console.log('Registry Get Order failed: '+error.message);
- res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(' retrying assetRegistry.update for: '+req.body.orderNo);
+ svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
+ }
+ else
+ {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);}
});
+
})
- .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
+ .catch((error) => {
+ console.log('Registry Get Order failed: '+error.message);
+ res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
- })
- .catch((error) => {console.log('Business Network Connect failed: '+error.message);
+ })
+ .catch((error) => {console.log('Business Network Connect failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
-}
+};
+
/**
* adds an order to the blockchain
* @param {express.req} req - the inbound request object from the client
@@ -203,85 +208,70 @@ exports.orderAction = function (req, res, next) {
* req.body.items - array with items for order
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.addOrder = function (req, res, next) {
+ let method = 'addOrder';
+ console.log(method+' req.body.buyer is: '+req.body.buyer );
let businessNetworkConnection;
let factory;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let ts = Date.now();
- let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
- if (svc.m_connection == null) {svc.createMessageSocket();}
-
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- let order = factory.newResource(NS, 'Order', orderNo);
- order = svc.createOrderTemplate(order);
- order.amount = 0;
- order.orderNumber = orderNo;
- order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
- order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
- order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- for (let each in req.body.items)
- {(function(_idx, _arr)
- { _arr[_idx].description = _arr[_idx].itemDescription;
- order.items.push(JSON.stringify(_arr[_idx]));
- order.amount += parseInt(_arr[_idx].extendedPrice);
- })(each, req.body.items)
- }
- // create the buy transaction
- const createNew = factory.newTransaction(NS, 'CreateOrder');
-
- createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
- createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- createNew.amount = order.amount;
- // add the order to the asset registry.
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.add(order)
- .then(() => {
- return businessNetworkConnection.submitTransaction(createNew)
- .then(() => {console.log(' order '+orderNo+" successfully added");
- res.send({'result': ' order '+orderNo+' successfully added'});
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- else
- {console.log(orderNo+" submitTransaction failed with text: ",error.message);}
- });
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- else
- {console.log(orderNo+" assetRegistry.add failed: ",error.message);}
- });
- })
- .catch((error) => {
- console.log(orderNo+" getAssetRegistry failed: ",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
- });
- })
- .catch((error) => {
- console.log(orderNo+" business network connection failed: text",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
- });
+ let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
+ if (svc.m_connection === null) {svc.createMessageSocket();}
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.buyer)
+ .then(() => {
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ let order = factory.newResource(NS, 'Order', orderNo);
+ order = svc.createOrderTemplate(order);
+ order.amount = 0;
+ order.orderNumber = orderNo;
+ order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
+ order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
+ order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
+ order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
+ order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ for (let each in req.body.items)
+ {(function(_idx, _arr)
+ { _arr[_idx].description = _arr[_idx].itemDescription;
+ order.items.push(JSON.stringify(_arr[_idx]));
+ order.amount += parseInt(_arr[_idx].extendedPrice);
+ })(each, req.body.items);
}
+ // create the buy transaction
+
+ // add the order to the asset registry.
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.add(order)
+ .then(() => {
+ // ========> Your Code Goes Here <=========
+ })
+ .catch((error) => {
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo);
+ svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
+ }
+ else
+ {
+ console.log(orderNo+' assetRegistry.add failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ }
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' getAssetRegistry failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' business network connection failed: text',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
+ });
+};
diff --git a/Chapter06/controller/restapi/features/text/ch/prompts.json b/Chapter06/controller/restapi/features/text/ch/prompts.json
index b9f6a49..97cabf4 100644
--- a/Chapter06/controller/restapi/features/text/ch/prompts.json
+++ b/Chapter06/controller/restapi/features/text/ch/prompts.json
@@ -54,6 +54,9 @@
"rm_am_param":"Co 名字,ID, 类型",
"rm_rm_api":"删除成员",
"rm_gs_api":"获取成员秘密",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Check if card exists",
+ "rm_cc2_api": "Create Card",
"bc":"区块链",
"bc_api":"API",
"bc_param":"参数",
@@ -96,8 +99,8 @@
"cd_financeco":"FinanceCo",
"cd_cn":"公司名称",
"cd_e":"电子邮箱地址",
- "cancelNewOrder":"取消",
- "submitNewOrder":"提交"
+ "cancel":"取消",
+ "submit":"提交"
},
"createOrder": {
"title":"创建新订单",
diff --git a/Chapter06/controller/restapi/features/text/en-UK/prompts.json b/Chapter06/controller/restapi/features/text/en-UK/prompts.json
index d6ef84f..f8cd2b2 100644
--- a/Chapter06/controller/restapi/features/text/en-UK/prompts.json
+++ b/Chapter06/controller/restapi/features/text/en-UK/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language": "UK English",
- "title": "Z2B Chapter 6",
- "header": "Chapter 6: Building the Buyer User Experience",
- "titleBar": "Zero to Blockchain Tutorial",
- "idx_unified": "load Unified User Experience",
- "idx_buyer": "load Buyer User Experience",
- "idx_seller": "load Seller User Experience",
- "idx_provider": "load Provider User Experience",
- "idx_shipper": "load Shipper User Experience",
- "idx_financeco": "load Finance Company User Experience",
- "idx_roles": "Roles",
- "idx_admin": "Admin",
- "idx_adminUX": "load Admin User Experience",
- "idx_preload": "Preload Network"
- },
- "admin": {
- "title": "Zero To Blockchain Chapter 6",
- "npm": "Network Profile Management",
- "npm_API": "API",
- "npm_param": "Parameters",
- "npm_dp_api": "delete profile",
- "npm_dp_param": "profile name",
- "npm_cp_api": "create Profile",
- "npm_cp_param": "profile object",
- "npm_ga_api": "get all connection profiles",
- "npm_ga_param": "(none)",
- "npm_g1_api": "get a specific network connection profile",
- "npm_g1_param": "profile name",
- "bnm": "Business Network Management",
- "bnm_param": "Parameters",
- "bnm_api": "API",
- "bnm_nd_api": "deploy a network",
- "bnm_nd_param": "network archive file, options",
- "bnm_ni_api": "install new a network",
- "bnm_ni_param": "network archive file, options",
- "bnm_ns_api": "start an installed network",
- "bnm_ns_param": "network name, options",
- "bnm_nl_api": "list the deployed business networks",
- "bnm_nl_param": "(none)",
- "bnm_np_api": "touch a network, check compatibility",
- "bnm_np_param": "business network name",
- "bnm_nu_api": "take a business network off line",
- "bnm_nu_param": "business network name<",
- "bnm_nuu_api": "update an existing business network",
- "bnm_nuu_param": "business network name, archive file",
- "rm": "Resource Management",
- "rm_api": "API",
- "rm_param": "Parameters",
- "rm_lr_api": "list members of a registry",
- "rm_la_api": "List Assets in the registry",
- "rm_la_param": "(none)",
- "rm_am_api": "Add Member",
- "rm_am_param": "Co Name, id, Type",
- "rm_rm_api": "Remove Member",
- "rm_gs_api": "getMemberSecret",
- "bc": "BlockChain",
- "bc_api": "API",
- "bc_param": "Parameters",
- "bc_gi_api": "initiate connection to blockchain",
- "bc_gi_param": "(none)",
- "bc_ge_api": "register for blockchain events",
- "bc_ge_param": "(none)",
- "bc_gh_api": "get Historian",
- "bc_gh_param": "(none)"
- },
- "buyer": {
- "title": "Buyer Chapter 6. Select Buyer to see their view: ",
- "newOrder": "Create New Order",
- "orderStatus": "Display Order Status"
- },
- "createConnectionProfile": {
- "title": "type the name of the new profile here: ",
- "cp_type": "type",
- "cp_orderers": "orderers",
- "cp_orderers_url": "url",
- "cp_ca": "ca",
- "cp_ca_url": "url",
- "cp_ca_name": "name",
- "cp_peers": "peers",
- "cp_peers_event_url": "eventURL",
- "cp_peers_request_url": "requestURL",
- "cp_keyValStore": "keyValStore",
- "cp_channel": "channel",
- "cp_mspID": "mspID",
- "cp_timeout": "timeout",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "createMember": {
- "cd_type": "Type",
- "cd_buyer": "Buyer",
- "cd_seller": "Seller",
- "cd_shipper": "Shipper",
- "cd_provider": "Provider",
- "cd_financeco": "FinanceCo",
- "cd_cn": "Company Name",
- "cd_e": "email Address",
- "cancelNewOrder": "Cancel",
- "submitNewOrder": "Submit"
- },
- "createOrder": {
- "title": "Create New Order",
- "selectVendor": "Select Vendor: ",
- "cn_on": "Order Number",
- "cn_status": "Status",
- "cn_date": "Date",
- "cn_total": "Total",
- "cn_selectItem": "Select Item",
- "addItem": "Add Item",
- "cancelNewOrder": "Cancel",
- "submitNewOrder": "Submit"
- },
- "deleteConnectionProfile": {
- "title": "Select Profile to delete: ",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "financeCo": {
- "title": "Zero To Blockchain Chapter 6: The Global Financier",
- "financeCOclear": "Clear Window",
- "financeCOorderStatus": "Display Order Status"
- },
- "getMemberSecret": {
- "gs_type": "Type",
- "gs_members": "Members",
- "gs_company": "Company Name",
- "gs_email": "email Address",
- "gs_userID": "userID",
- "gs_secret": "secret",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "provider": {
- "title": "Provider Chapter 6, Select Provider to see their view: ",
- "provider_clear": "Clear Window",
- "providerOrderStatus": "Display Order Status"
- },
- "removeMember": {
- "rm_type": "Type",
- "rm_members": "Members",
- "rm_company": "Company Name",
- "rm_email": "email Address",
- "rm_userID": "userID",
- "rm_secret": "secret",
- "cancel": "Cancel",
- "submit": "Submit"
- },
- "seller": {
- "title": "Seller Chapter 6, Select Seller to see their view: ",
- "seller_clear": "Clear Window",
- "sellerOrderStatus": "Display Order Status"
- },
- "shipper": {
- "title": "Shipper Chapter 6, Select Shipper to see their view: ",
- "shipper_clear": "Clear Window",
- "shipperOrderStatus": "Display Order Status "
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"},
- "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "},
- "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "},
- "Purchase": {"select": "Purchase", "message": "Purchase"},
- "Cancel": {"select": "Cancel", "message": "Cancel"},
- "Pay": {"select": "Pay", "message": "Pay"},
- "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"},
- "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "},
- "PayRequest": {"select": "PayRequest", "message": "Request Payment"},
- "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "},
- "Delivered": {"select": "Delivered", "message": "Delivered"},
- "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "},
- "Order": {"select": "Order", "message": "Order From Supplier"},
- "NoAction": {"select": "NoAction", "message": "Take No Action"},
- "ex_button": "Execute",
- "ca_button": "Cancel",
- "orderno": "Order #",
- "status": "Status",
- "total": "Total",
- "seller": "Seller: ",
- "itemno": "Item Number",
- "description": "Description",
- "qty": "Quantity",
- "price": "Price",
- "processing_msg": "Processing {0} request for order number: {1}",
- "b_no_order_msg": "No orders for this buyer: ",
- "s_no_order_msg": "No orders for this seller: ",
- "p_no_order_msg": "No orders for this provider: ",
- "sh_no_order_msg": "No orders for this shipper: ",
- "create_msg": "Processing Create Order request",
- "buyer": "Buyer: "
- },
- "financeCoOrder": {
- "status": "Current Status: ",
- "action": "Action",
- "by": "By",
- "date": "Date",
- "comments": "Comments",
- "created": "Created",
- "cancelled": "Cancelled?",
- "notCancel": "(not Cancelled)",
- "purchased": "Purchased",
- "noPurchase": "(no Purchase Request)",
- "thirdParty": "3rd Party Order",
- "nothirdParty": "(not yet sent to 3rd Party)",
- "backordered": "Backordered?",
- "notBackordered": "(not Backordered)",
- "shippingRequested": "Shipping Requested",
- "noRequestShip": "(No Request to Shipper)",
- "shippingStarted": "Shipping Started",
- "noDeliveryStart": "(Delivery not Started)",
- "delivered": "Delivered",
- "notDelivered": "(not yet Delivered)",
- "payRequested": "Payment Requested",
- "noRequest": "(no request for payment)",
- "disputed": "Dispute Raised",
- "noDispute": "(not in Dispute)"
- }
-}
+ "index": {"language":"US English",
+ "title":"Z2B Chapter 6",
+ "header":"Chapter 6: Building the Buyer User Experience",
+ "titleBar":"Zero to Blockchain Tutorial",
+ "idx_unified":"load Unified User Experience",
+ "idx_buyer":"load Buyer User Experience",
+ "idx_seller":"load Seller User Experience",
+ "idx_provider":"load Provider User Experience",
+ "idx_shipper":"load Shipper User Experience",
+ "idx_financeco":"load Finance Company User Experience",
+ "idx_roles":"Roles",
+ "idx_admin":"Admin",
+ "idx_adminUX":"load Admin User Experience",
+ "idx_preload":"Preload Network"
+ },
+ "admin": {
+ "title":"Zero To Blockchain Chapter 05",
+ "npm":"Network Profile Management",
+ "npm_API":"API",
+ "npm_param":"Parameters",
+ "npm_dp_api":"delete profile",
+ "npm_dp_param":"profile name",
+ "npm_cp_api":"create Profile",
+ "npm_cp_param":"profile object",
+ "npm_ga_api":"get all connection profiles",
+ "npm_ga_param":"(none)",
+ "npm_g1_api":"get a specific network connection profile",
+ "npm_g1_param":"profile name",
+ "bnm":"Business Network Management",
+ "bnm_param":"Parameters",
+ "bnm_api":"API",
+ "bnm_nd_api":"deploy a network",
+ "bnm_nd_param":"network archive file, options",
+ "bnm_ni_api":"install new a network",
+ "bnm_ni_param":"network archive file, options",
+ "bnm_ns_api":"start an installed network",
+ "bnm_ns_param":"network name, options",
+ "bnm_nl_api":"list the deployed business networks",
+ "bnm_nl_param":"(none)",
+ "bnm_np_api":"touch a network, check compatibility",
+ "bnm_np_param":"business network name",
+ "bnm_nu_api":"take a business network off line",
+ "bnm_nu_param":"business network name<",
+ "bnm_nuu_api":"update an existing business network",
+ "bnm_nuu_param":"business network name, archive file",
+ "rm":"Resource Management",
+ "rm_api":"API",
+ "rm_param":"Parameters",
+ "rm_lr_api":"list members of a registry",
+ "rm_la_api":"List Assets in the registry",
+ "rm_la_param":"(none)",
+ "rm_am_api":"Add Member",
+ "rm_am_param":"Co Name, id, Type",
+ "rm_rm_api":"Remove Member",
+ "rm_gs_api":"getMemberSecret",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Check if card exists",
+ "rm_cc2_api": "Create Card",
+ "bc":"BlockChain",
+ "bc_api":"API",
+ "bc_param":"Parameters",
+ "bc_gi_api":"initiate connection to blockchain",
+ "bc_gi_param":"(none)",
+ "bc_ge_api":"register for blockchain events",
+ "bc_ge_param":"(none)",
+ "bc_gh_api":"get Historian",
+ "bc_gh_param":"(none)"
+ },
+ "buyer": {
+ "title":"Buyer Chapter 06. Select Buyer to see their view: ",
+ "newOrder":"Create New Order",
+ "orderStatus":"Display Order Status"
+ },
+ "createConnectionProfile": {
+ "title":"type the name of the new profile here: ",
+ "cp_type":"type",
+ "cp_orderers":"orderers",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"name",
+ "cp_peers":"peers",
+ "cp_peers_event_url":"eventURL",
+ "cp_peers_request_url":"requestURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"channel",
+ "cp_mspID":"mspID",
+ "cp_timeout":"timeout",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "createMember": {
+ "cd_type":"Type",
+ "cd_buyer":"Buyer",
+ "cd_seller":"Seller",
+ "cd_shipper":"Shipper",
+ "cd_provider":"Provider",
+ "cd_financeco":"FinanceCo",
+ "cd_cn":"Company Name",
+ "cd_e":"email Address",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "createOrder": {
+ "title":"Create New Order",
+ "selectVendor":"Select Vendor: ",
+ "cn_on":"Order Number",
+ "cn_status":"Status",
+ "cn_date":"Date",
+ "cn_total":"Total",
+ "cn_selectItem":"Select Item",
+ "addItem":"Add Item",
+ "cancelNewOrder":"Cancel",
+ "submitNewOrder":"Submit"
+ },
+ "deleteConnectionProfile": {
+ "title":"Select Profile to delete: ",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "financeCo": {
+ "title":"Zero To Blockchain Chapter 10: The Global Financier",
+ "financeCOclear":"Clear Window",
+ "financeCOorderStatus":"Display Order Status"
+ },
+ "getMemberSecret": {
+ "gs_type":"Type",
+ "gs_members":"Members",
+ "gs_company":"Company Name",
+ "gs_email":"email Address",
+ "gs_userID":"userID",
+ "gs_secret":"secret",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "provider": {
+ "title":"Provider Chapter 08, Select Provider to see their view: ",
+ "provider_clear":"Clear Window",
+ "providerOrderStatus":"Display Order Status"
+ },
+ "removeMember": {
+ "rm_type":"Type",
+ "rm_members":"Members",
+ "rm_company":"Company Name",
+ "rm_email":"email Address",
+ "rm_userID":"userID",
+ "rm_secret":"secret",
+ "cancel":"Cancel",
+ "submit":"Submit"
+ },
+ "seller": {
+ "title":"Seller Chapter 07, Select Seller to see their view: ",
+ "seller_clear":"Clear Window",
+ "sellerOrderStatus":"Display Order Status"
+ },
+ "shipper": {
+ "title":"Shipper Chapter 09, Select Shipper to see their view: ",
+ "shipper_clear":"Clear Window",
+ "shipperOrderStatus":"Display Order Status "
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"},
+ "Dispute": {"select": "Dispute","message":"Dispute"},
+ "Resolve": {"select": "Resolve","message":"Resolve"},
+ "Purchase": {"select": "Purchase","message":"Purchase"},
+ "Cancel": {"select": "Cancel","message":"Cancel"},
+ "Pay": {"select": "Pay","message":"Pay"},
+ "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"},
+ "BackOrder": {"select": "BackOrder","message":"BackOrder"},
+ "PayRequest": {"select": "PayRequest","message":"Request Payment"},
+ "Refund": {"select": "Refund","message":"Refund"},
+ "Delivered": {"select": "Delivered","message":"Delivered"},
+ "Delivering": {"select": "Delivering","message":"Update Delivery Status"},
+ "Order": {"select": "Order","message":"Order From Supplier"},
+ "NoAction": {"select": "NoAction","message":"Take No Action"},
+ "ex_button":"Execute",
+ "ca_button":"Cancel",
+ "orderno":"Order #",
+ "status":"Status",
+ "total":"Total",
+ "seller":"Seller: ",
+ "itemno":"Item Number",
+ "description":"Description",
+ "qty":"Quantity",
+ "price":"Price",
+ "processing_msg":"Processing {0} request for order number: {1}",
+ "b_no_order_msg":"No orders for this buyer: ",
+ "s_no_order_msg":"No orders for this seller: ",
+ "p_no_order_msg":"No orders for this provider: ",
+ "sh_no_order_msg":"No orders for this shipper: ",
+ "create_msg":"Processing Create Order request",
+ "buyer":"Buyer: "
+ },
+ "financeCoOrder": {
+ "status":"Current Status: ",
+ "action":"Action",
+ "by":"By",
+ "date":"Date",
+ "comments":"Comments",
+ "created":"Created",
+ "cancelled":"Cancelled?",
+ "notCancel":"(not Cancelled)",
+ "purchased":"Purchased",
+ "noPurchase":"(no Purchase Request)",
+ "thirdParty":"3rd Party Order",
+ "nothirdParty":"(not yet sent to 3rd Party)",
+ "backordered":"Backordered?",
+ "notBackordered":"(not Backordered)",
+ "shippingRequested":"Shipping Requested",
+ "noRequestShip":"(No Request to Shipper)",
+ "shippingStarted":"Shipping Started",
+ "noDeliveryStart":"(Delivery not Started)",
+ "delivered":"Delivered",
+ "notDelivered":"(not yet Delivered)",
+ "payRequested":"Payment Requested",
+ "noRequest":"(no request for payment)",
+ "disputed":"Dispute Raised",
+ "noDispute":"(not in Dispute)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/features/text/en-US/prompts.json b/Chapter06/controller/restapi/features/text/en-US/prompts.json
index 1026a23..e8418e8 100644
--- a/Chapter06/controller/restapi/features/text/en-US/prompts.json
+++ b/Chapter06/controller/restapi/features/text/en-US/prompts.json
@@ -53,7 +53,10 @@
"rm_am_api": "Add Member",
"rm_am_param": "Co Name, id, Type",
"rm_rm_api": "Remove Member",
- "rm_gs_api": "getMemberSecret",
+ "rm_gs_api": "get Member Secret",
+ "rm_ii_api": "Issue Identity",
+ "rm_cc_api": "Check if card exists",
+ "rm_cc2_api": "Create Card",
"bc": "BlockChain",
"bc_api": "API",
"bc_param": "Parameters",
@@ -96,8 +99,8 @@
"cd_financeco": "FinanceCo",
"cd_cn": "Company Name",
"cd_e": "email Address",
- "cancelNewOrder": "Cancel",
- "submitNewOrder": "Submit"
+ "cancel": "Cancel",
+ "submit": "Submit"
},
"createOrder": {
"title": "Create New Order",
diff --git a/Chapter06/controller/restapi/features/text/es-LA/prompts.json b/Chapter06/controller/restapi/features/text/es-LA/prompts.json
index e8b5220..0f915ae 100644
--- a/Chapter06/controller/restapi/features/text/es-LA/prompts.json
+++ b/Chapter06/controller/restapi/features/text/es-LA/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language":"LA Español",
- "title":"Z2B Capítulo 6",
- "header":"Capítulo 6: Construyendo la experiencia del usuario del comprador",
- "titleBar":"Cero al tutorial de Blockchain",
- "idx_unified":"Cargar experiencia de usuario unificada",
- "idx_buyer":"Cargar la experiencia del usuario del comprador",
- "idx_seller":"Cargar experiencia de usuario del vendedor",
- "idx_provider":"Cargar experiencia de usuario del proveedor",
- "idx_shipper":"Cargar experiencia de usuario del transportista",
- "idx_financeco":"Cargar experiencia de usuario de la compañía financiera",
- "idx_roles":"Roles",
- "idx_admin":"Administrador",
- "idx_adminUX":"Cargar experiencia de usuario del administrador",
- "idx_preload":"Precardar red"
- },
- "admin": {
- "title":"Cero al tutorial de Blockchain Capítulo 05",
- "npm":"Administración del perfil de redes",
- "npm_API":"API",
- "npm_param":"Parámetros",
- "npm_dp_api":"borrar perfil",
- "npm_dp_param":"nombre del perfil ",
- "npm_cp_api":"crear perfil",
- "npm_cp_param":"objeto de perfil",
- "npm_ga_api":"obtener todos los perfiles de conexión",
- "npm_ga_param":"(ninguno)",
- "npm_g1_api":"conseguor un perfil de red de conexión espécífico",
- "npm_g1_param":"nombre del perfil ",
- "bnm":"Administrador de red de negocios",
- "bnm_param":"Parámetros",
- "bnm_api":"API",
- "bnm_nd_api":"desplegar una red",
- "bnm_nd_param":"archivo de red, opciones",
- "bnm_ni_api":"instalar una nueva red",
- "bnm_ni_param":"archivo de red, opciones",
- "bnm_ns_api":"iniciar una red instalada",
- "bnm_ns_param":"nombre de la red, opciones",
- "bnm_nl_api":"enumerar las redes empresariales desplegadas",
- "bnm_nl_param":"(ninguna)",
- "bnm_np_api":"toca una red, comprueba la compatibilidad",
- "bnm_np_param":"nombre de la red comercial",
- "bnm_nu_api":"tomar una red de negocios fuera de línea",
- "bnm_nu_param":"nombre de la red comercial <",
- "bnm_nuu_api":"actualizar una red comercial existente",
- "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento",
- "rm":"Administracion de recursos",
- "rm_api":"API",
- "rm_param":"Parámetros",
- "rm_lr_api":"listar miembros de un registro",
- "rm_la_api":"Lista de activos en el registro",
- "rm_la_param":"(ninguna)",
- "rm_am_api":"Añadir miembro",
- "rm_am_param":"Co Nombre, id, Tipo",
- "rm_rm_api":"Eliminar miembro",
- "rm_gs_api":"obtenerMiembroSecreto",
- "bc":"BlockChain",
- "bc_api":"API",
- "bc_param":"Parámetros",
- "bc_gi_api":"iniciar la conexión a blockchain",
- "bc_gi_param":"(ninguna)",
- "bc_ge_api":"registrarse para eventos blockchain",
- "bc_ge_param":"(ninguna)",
- "bc_gh_api":"obtener un historiador",
- "bc_gh_param":"(ninguna)"
- },
- "buyer": {
- "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:",
- "newOrder":"Crear nuevo orden",
- "orderStatus":"Mostrar estado del pedido"
- },
- "createConnectionProfile": {
- "title":"tipo de nombre para un nuevo perfil aquí:",
- "cp_type":"tipo",
- "cp_orderers":"solicitantes",
- "cp_orderers_url":"Localizador Uniforme de Recursos (url)",
- "cp_ca":"ca",
- "cp_ca_url":"Localizador Uniforme de Recursos (url)",
- "cp_ca_name":"nombre",
- "cp_peers":"semejantes",
- "cp_peers_event_url":"eventoURL",
- "cp_peers_request_url":"requerirURL",
- "cp_keyValStore":"keyValStore",
- "cp_channel":"canal",
- "cp_mspID":"mspID",
- "cp_timeout":"tiempofuera",
- "cancel":"Cancelar",
- "submit":"Someter"
- },
- "createMember": {
- "cd_type":"Tipo",
- "cd_buyer":"Comprador",
- "cd_seller":"Vendedor",
- "cd_shipper":"Expedidor",
- "cd_provider":"Proveedor",
- "cd_financeco":"Compañía financiera",
- "cd_cn":"nombre de empresa",
- "cd_e":"dirección de correo electrónico",
- "cancelNewOrder":"Cancelar",
- "submitNewOrder":"Enviar"
- },
- "createOrder": {
- "title":"Crear nueva orden",
- "selectVendor":"Seleccionar proveedor:",
- "cn_on":"Número de orden",
- "cn_status":"Estado",
- "cn_date":"Fecha",
- "cn_total":"Total",
- "cn_selectItem":"Seleccione un artículo",
- "addItem":"Añadir artículo",
- "cancelNewOrder":"Cancelar",
- "submitNewOrder":"Enviar"
- },
- "deleteConnectionProfile": {
- "title":"Seleccionar perfil para eliminar:",
- "cancel":"Cancelar",
- "submit":"Enviar"
- },
- "financeCo": {
- "title":"Cero a Blockchain Capítulo 10: El financiero global",
- "financeCOclear":"Ventana limpia",
- "financeCOorderStatus":"Mostrar estado del pedido"
- },
- "getMemberSecret": {
- "gs_type":"Tipo",
- "gs_members":"Miembros",
- "gs_company":"nombre de empresa",
- "gs_email":"dirección de correo electrónico",
- "gs_userID":"identidad de usuario",
- "gs_secret":"secreto",
- "cancel":"Cancelar",
- "submit":"Enviar"
- },
- "provider": {
- "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:",
- "provider_clear":"Ventana limpia",
- "providerOrderStatus":"Mostrar estado del pedido"
- },
- "removeMember": {
- "rm_type":"Tipo",
- "rm_members":"Miembros",
- "rm_company":"nombre de empresa",
- "rm_email":"dirección de correo electrónico",
- "rm_userID":"identidad de usuario",
- "rm_secret":"secreto",
- "cancel":"Cancelar",
- "submit":"Enviar"
- },
- "seller": {
- "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:",
- "seller_clear":"Ventana limpia",
- "sellerOrderStatus":"Mostrar estado del pedido"
- },
- "shipper": {
- "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:",
- "shipper_clear":"Ventana limpia",
- "shipperOrderStatus":"Mostrar estado del pedido"
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"},
- "Dispute": {"select": "Disputa","message":"Disputa"},
- "Resolve": {"select": "Resolver","message":"Resolver"},
- "Purchase": {"select": "Compra","message":"Compra"},
- "Cancel": {"select": "Cancelar","message":"Cancelar"},
- "Pay": {"select": "Paga","message":"Paga"},
- "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"},
- "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"},
- "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"},
- "Refund": {"select": "Reembolso","message":"Reembolso"},
- "Delivered": {"select": "Entregado","message":"Entregado"},
- "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"},
- "Order": {"select": "Orden","message":"Ordene del proveedor"},
- "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"},
- "ex_button":"Ejecutar",
- "ca_button":"Cancelar",
- "orderno":"Orden #",
- "status":"Estado",
- "total":"Total",
- "seller":"Vendedor:",
- "itemno":"Número de artículo",
- "description":"Descripción",
- "qty":"Cantidad",
- "price":"Precio",
- "processing_msg":"Procesando {0} solicitud de número de pedido: {1}",
- "b_no_order_msg":"No hay pedidos para este comprador:",
- "s_no_order_msg":"No hay pedidos para este vendedor:",
- "p_no_order_msg":"No hay pedidos para este proveedor:",
- "sh_no_order_msg":"No hay pedidos para este remitente:",
- "create_msg":"Procesando Crear solicitud de pedido",
- "buyer":"Comprador:"
- },
- "financeCoOrder": {
- "status":"Estatus actual",
- "action":"Acción",
- "by":"Por",
- "date":"Fecha",
- "comments":"Comentarios",
- "created":"Creado",
- "cancelled":"Cancelado",
- "notCancel":"(no cancelado)",
- "purchased":"Comprado",
- "noPurchase":"(no hay orden de compra)",
- "thirdParty":"Orden de un tercero",
- "nothirdParty":"(no se ha enviado a un tercero)",
- "backordered":"¿Atrasado?",
- "notBackordered":"(no atrasado)",
- "shippingRequested":"Embarque requerido",
- "noRequestShip":"(No hay requerimiento al transportista)",
- "shippingStarted":"Embarque iniciado",
- "noDeliveryStart":"(No ha comenzado la entrega)",
- "delivered":"Entregado",
- "notDelivered":"(no ha sido entregado)",
- "payRequested":"Pago requerido",
- "noRequest":"(no se ha solicitado el pago)",
- "disputed":"Disputa planteada",
- "noDispute":"(no en disputa)"
- }
- }
\ No newline at end of file
+ "index": {"language":"LA Español",
+ "title":"Z2B Capítulo 6",
+ "header":"Capítulo 6: Construyendo la experiencia del usuario del comprador",
+ "titleBar":"Cero al tutorial de Blockchain",
+ "idx_unified":"Cargar experiencia de usuario unificada",
+ "idx_buyer":"Cargar la experiencia del usuario del comprador",
+ "idx_seller":"Cargar experiencia de usuario del vendedor",
+ "idx_provider":"Cargar experiencia de usuario del proveedor",
+ "idx_shipper":"Cargar experiencia de usuario del transportista",
+ "idx_financeco":"Cargar experiencia de usuario de la compañía financiera",
+ "idx_roles":"Roles",
+ "idx_admin":"Administrador",
+ "idx_adminUX":"Cargar experiencia de usuario del administrador",
+ "idx_preload":"Precardar red"
+ },
+ "admin": {
+ "title":"Cero al tutorial de Blockchain Capítulo 05",
+ "npm":"Administración del perfil de redes",
+ "npm_API":"API",
+ "npm_param":"Parámetros",
+ "npm_dp_api":"borrar perfil",
+ "npm_dp_param":"nombre del perfil ",
+ "npm_cp_api":"crear perfil",
+ "npm_cp_param":"objeto de perfil",
+ "npm_ga_api":"obtener todos los perfiles de conexión",
+ "npm_ga_param":"(ninguno)",
+ "npm_g1_api":"conseguor un perfil de red de conexión espécífico",
+ "npm_g1_param":"nombre del perfil ",
+ "bnm":"Administrador de red de negocios",
+ "bnm_param":"Parámetros",
+ "bnm_api":"API",
+ "bnm_nd_api":"desplegar una red",
+ "bnm_nd_param":"archivo de red, opciones",
+ "bnm_ni_api":"instalar una nueva red",
+ "bnm_ni_param":"archivo de red, opciones",
+ "bnm_ns_api":"iniciar una red instalada",
+ "bnm_ns_param":"nombre de la red, opciones",
+ "bnm_nl_api":"enumerar las redes empresariales desplegadas",
+ "bnm_nl_param":"(ninguna)",
+ "bnm_np_api":"toca una red, comprueba la compatibilidad",
+ "bnm_np_param":"nombre de la red comercial",
+ "bnm_nu_api":"tomar una red de negocios fuera de línea",
+ "bnm_nu_param":"nombre de la red comercial <",
+ "bnm_nuu_api":"actualizar una red comercial existente",
+ "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento",
+ "rm":"Administracion de recursos",
+ "rm_api":"API",
+ "rm_param":"Parámetros",
+ "rm_lr_api":"listar miembros de un registro",
+ "rm_la_api":"Lista de activos en el registro",
+ "rm_la_param":"(ninguna)",
+ "rm_am_api":"Añadir miembro",
+ "rm_am_param":"Co Nombre, id, Tipo",
+ "rm_rm_api":"Eliminar miembro",
+ "rm_gs_api":"obtenerMiembroSecreto",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"verificar si existe una tarjeta de identidad",
+ "rm_cc2_api": "crear una tarjeta de identidad",
+ "bc":"BlockChain",
+ "bc_api":"API",
+ "bc_param":"Parámetros",
+ "bc_gi_api":"iniciar la conexión a blockchain",
+ "bc_gi_param":"(ninguna)",
+ "bc_ge_api":"registrarse para eventos blockchain",
+ "bc_ge_param":"(ninguna)",
+ "bc_gh_api":"obtener un historiador",
+ "bc_gh_param":"(ninguna)"
+ },
+ "buyer": {
+ "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:",
+ "newOrder":"Crear nuevo orden",
+ "orderStatus":"Mostrar estado del pedido"
+ },
+ "createConnectionProfile": {
+ "title":"tipo de nombre para un nuevo perfil aquí:",
+ "cp_type":"tipo",
+ "cp_orderers":"solicitantes",
+ "cp_orderers_url":"Localizador Uniforme de Recursos (url)",
+ "cp_ca":"ca",
+ "cp_ca_url":"Localizador Uniforme de Recursos (url)",
+ "cp_ca_name":"nombre",
+ "cp_peers":"semejantes",
+ "cp_peers_event_url":"eventoURL",
+ "cp_peers_request_url":"requerirURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"canal",
+ "cp_mspID":"mspID",
+ "cp_timeout":"tiempofuera",
+ "cancel":"Cancelar",
+ "submit":"Someter"
+ },
+ "createMember": {
+ "cd_type":"Tipo",
+ "cd_buyer":"Comprador",
+ "cd_seller":"Vendedor",
+ "cd_shipper":"Expedidor",
+ "cd_provider":"Proveedor",
+ "cd_financeco":"Compañía financiera",
+ "cd_cn":"nombre de empresa",
+ "cd_e":"dirección de correo electrónico",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "createOrder": {
+ "title":"Crear nueva orden",
+ "selectVendor":"Seleccionar proveedor:",
+ "cn_on":"Número de orden",
+ "cn_status":"Estado",
+ "cn_date":"Fecha",
+ "cn_total":"Total",
+ "cn_selectItem":"Seleccione un artículo",
+ "addItem":"Añadir artículo",
+ "cancelNewOrder":"Cancelar",
+ "submitNewOrder":"Enviar"
+ },
+ "deleteConnectionProfile": {
+ "title":"Seleccionar perfil para eliminar:",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "financeCo": {
+ "title":"Cero a Blockchain Capítulo 10: El financiero global",
+ "financeCOclear":"Ventana limpia",
+ "financeCOorderStatus":"Mostrar estado del pedido"
+ },
+ "getMemberSecret": {
+ "gs_type":"Tipo",
+ "gs_members":"Miembros",
+ "gs_company":"nombre de empresa",
+ "gs_email":"dirección de correo electrónico",
+ "gs_userID":"identidad de usuario",
+ "gs_secret":"secreto",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "provider": {
+ "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:",
+ "provider_clear":"Ventana limpia",
+ "providerOrderStatus":"Mostrar estado del pedido"
+ },
+ "removeMember": {
+ "rm_type":"Tipo",
+ "rm_members":"Miembros",
+ "rm_company":"nombre de empresa",
+ "rm_email":"dirección de correo electrónico",
+ "rm_userID":"identidad de usuario",
+ "rm_secret":"secreto",
+ "cancel":"Cancelar",
+ "submit":"Enviar"
+ },
+ "seller": {
+ "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:",
+ "seller_clear":"Ventana limpia",
+ "sellerOrderStatus":"Mostrar estado del pedido"
+ },
+ "shipper": {
+ "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:",
+ "shipper_clear":"Ventana limpia",
+ "shipperOrderStatus":"Mostrar estado del pedido"
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"},
+ "Dispute": {"select": "Disputa","message":"Disputa"},
+ "Resolve": {"select": "Resolver","message":"Resolver"},
+ "Purchase": {"select": "Compra","message":"Compra"},
+ "Cancel": {"select": "Cancelar","message":"Cancelar"},
+ "Pay": {"select": "Paga","message":"Paga"},
+ "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"},
+ "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"},
+ "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"},
+ "Refund": {"select": "Reembolso","message":"Reembolso"},
+ "Delivered": {"select": "Entregado","message":"Entregado"},
+ "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"},
+ "Order": {"select": "Orden","message":"Ordene del proveedor"},
+ "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"},
+ "ex_button":"Ejecutar",
+ "ca_button":"Cancelar",
+ "orderno":"Orden #",
+ "status":"Estado",
+ "total":"Total",
+ "seller":"Vendedor:",
+ "itemno":"Número de artículo",
+ "description":"Descripción",
+ "qty":"Cantidad",
+ "price":"Precio",
+ "processing_msg":"Procesando {0} solicitud de número de pedido: {1}",
+ "b_no_order_msg":"No hay pedidos para este comprador:",
+ "s_no_order_msg":"No hay pedidos para este vendedor:",
+ "p_no_order_msg":"No hay pedidos para este proveedor:",
+ "sh_no_order_msg":"No hay pedidos para este remitente:",
+ "create_msg":"Procesando Crear solicitud de pedido",
+ "buyer":"Comprador:"
+ },
+ "financeCoOrder": {
+ "status":"Estatus actual",
+ "action":"Acción",
+ "by":"Por",
+ "date":"Fecha",
+ "comments":"Comentarios",
+ "created":"Creado",
+ "cancelled":"Cancelado",
+ "notCancel":"(no cancelado)",
+ "purchased":"Comprado",
+ "noPurchase":"(no hay orden de compra)",
+ "thirdParty":"Orden de un tercero",
+ "nothirdParty":"(no se ha enviado a un tercero)",
+ "backordered":"¿Atrasado?",
+ "notBackordered":"(no atrasado)",
+ "shippingRequested":"Embarque requerido",
+ "noRequestShip":"(No hay requerimiento al transportista)",
+ "shippingStarted":"Embarque iniciado",
+ "noDeliveryStart":"(No ha comenzado la entrega)",
+ "delivered":"Entregado",
+ "notDelivered":"(no ha sido entregado)",
+ "payRequested":"Pago requerido",
+ "noRequest":"(no se ha solicitado el pago)",
+ "disputed":"Disputa planteada",
+ "noDispute":"(no en disputa)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/features/text/fr/prompts.json b/Chapter06/controller/restapi/features/text/fr/prompts.json
index e152842..794db18 100644
--- a/Chapter06/controller/restapi/features/text/fr/prompts.json
+++ b/Chapter06/controller/restapi/features/text/fr/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language":"Le Français",
- "title":"Z2B Chapitre 06",
- "header":"Chapitre 06 : Construire l'experience de l'acheteur",
- "titleBar":"Zero to Blockchain tutoriel",
- "idx_unified":"Charger l'expérience utilisateur unifiée",
- "idx_buyer":"Charger l'expérience de l'acheteur",
- "idx_seller":"Charger l'expérience du vendeur",
- "idx_provider":"Charger l'expérience du fournisseur",
- "idx_shipper":"Charger l'expérience de lexpéditeur",
- "idx_financeco":"Charger l'expérience du financier",
- "idx_roles":"Roles",
- "idx_admin":"Admin",
- "idx_adminUX":"Charger l'expérience de l'administrateur",
- "idx_preload":"Pré-charger le Réseau"
- },
- "admin": {
- "title":"Zero to Blockchain Chapitre 06",
- "npm":"Gestion profil réseau",
- "npm_API":"API",
- "npm_param":"Paramètres",
- "npm_dp_api":"Effacer le profil",
- "npm_dp_param":"Nom du profil",
- "npm_cp_api":"Créer un profil",
- "npm_cp_param":"Objet du Profil",
- "npm_ga_api":"Obtenir tous les profils de connexion",
- "npm_ga_param":"(aucun)",
- "npm_g1_api":"Obyenir un profil de connexion spécifique",
- "npm_g1_param":"Nom du profil",
- "bnm":"Gestion du Réseau d'affaire",
- "bnm_param":"Paramètres",
- "bnm_api":"API",
- "bnm_nd_api":"Déployer un réseau",
- "bnm_nd_param":"Fichier archive réseau, options",
- "bnm_ni_api":"Installer un nouveau réseau",
- "bnm_ni_param":"Fichier archive réseau, options",
- "bnm_ns_api":"Démarrer un réseau installé",
- "bnm_ns_param":"Nom du réseau, options",
- "bnm_nl_api":"Liste des réseaux d'affaire déployés",
- "bnm_nl_param":"(aucun)",
- "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité",
- "bnm_np_param":"Nom du réseau d'affaire",
- "bnm_nu_api":"Prendre un réseau d'affaire hors ligne",
- "bnm_nu_param":"Nom du réseau d'affaire<",
- "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant",
- "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive",
- "rm":"Gestion des ressources",
- "rm_api":"API",
- "rm_param":"Paramètres",
- "rm_lr_api":"Lister les membres d'un registre",
- "rm_la_api":"Lister les objets d'un registre",
- "rm_la_param":"(aucun)",
- "rm_am_api":"Ajouter un membre",
- "rm_am_param":"Co nom, id, type",
- "rm_rm_api":"Retirer membre",
- "rm_gs_api":"getmembersecret",
- "bc":"Blockchain",
- "bc_api":"API",
- "bc_param":"Paramètres",
- "bc_gi_api":"Initier la connexion à Blockchain",
- "bc_gi_param":"(aucun)",
- "bc_ge_api":"Enregistrer pour les évènements Blockchain",
- "bc_ge_param":"(aucun)",
- "bc_gh_api":"Charger l'historique",
- "bc_gh_param":"(aucun)"
- },
- "buyer": {
+ "index": {"language":"Anglais USA",
+ "title":"Z2B Chapitre 6",
+ "header":"Chapitre 6 : Construire l'experience de l'acheteur",
+ "titleBar":"Zero to Blockchain tutoriel",
+ "idx_unified":"Charger l'expérience utilisateur unifiée",
+ "idx_buyer":"Charger l'expérience de l'acheteur",
+ "idx_seller":"Charger l'expérience du vendeur",
+ "idx_provider":"Charger l'expérience du fournisseur",
+ "idx_shipper":"Charger l'expérience de lexpéditeur",
+ "idx_financeco":"Charger l'expérience du financier",
+ "idx_roles":"Roles",
+ "idx_admin":"Admin",
+ "idx_adminUX":"Charger l'expérience de l'administrateur",
+ "idx_preload":"Pré-charger le Réseau"
+ },
+ "admin": {
+ "title":"Zero to Blockchain Chapitre 05",
+ "npm":"Gestion profil réseau",
+ "npm_API":"API",
+ "npm_param":"Paramètres",
+ "npm_dp_api":"Effacer le profil",
+ "npm_dp_param":"Nom du profil",
+ "npm_cp_api":"Créer un profil",
+ "npm_cp_param":"Objet du Profil",
+ "npm_ga_api":"Obtenir tous les profils de connexion",
+ "npm_ga_param":"(aucun)",
+ "npm_g1_api":"Obyenir un profil de connexion spécifique",
+ "npm_g1_param":"Nom du profil",
+ "bnm":"Gestion du Réseau d'affaire",
+ "bnm_param":"Paramètres",
+ "bnm_api":"API",
+ "bnm_nd_api":"Déployer un réseau",
+ "bnm_nd_param":"Fichier archive réseau, options",
+ "bnm_ni_api":"Installer un nouveau réseau",
+ "bnm_ni_param":"Fichier archive réseau, options",
+ "bnm_ns_api":"Démarrer un réseau installé",
+ "bnm_ns_param":"Nom du réseau, options",
+ "bnm_nl_api":"Liste des réseaux d'affaire déployés",
+ "bnm_nl_param":"(aucun)",
+ "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité",
+ "bnm_np_param":"Nom du réseau d'affaire",
+ "bnm_nu_api":"Prendre un réseau d'affaire hors ligne",
+ "bnm_nu_param":"Nom du réseau d'affaire<",
+ "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant",
+ "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive",
+ "rm":"Gestion des ressources",
+ "rm_api":"API",
+ "rm_param":"Paramètres",
+ "rm_lr_api":"Lister les membres d'un registre",
+ "rm_la_api":"Lister les objets d'un registre",
+ "rm_la_param":"(aucun)",
+ "rm_am_api":"Ajouter un membre",
+ "rm_am_param":"Co nom, id, type",
+ "rm_rm_api":"Retirer membre",
+ "rm_gs_api":"getmembersecret",
+ "rm_ii_api":"émission d'identité",
+ "rm_cc_api":"vérifier si la carte d'identité existe",
+ "rm_cc2_api": "Créér une nouvelle carte d'identité",
+ "bc":"Blockchain",
+ "bc_api":"API",
+ "bc_param":"Paramètres",
+ "bc_gi_api":"Initier la connexion à Blockchain",
+ "bc_gi_param":"(aucun)",
+ "bc_ge_api":"Enregistrer pour les évènements Blockchain",
+ "bc_ge_param":"(aucun)",
+ "bc_gh_api":"Charger l'historique",
+ "bc_gh_param":"(aucun)"
+ },
+ "buyer": {
"title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:",
"newOrder":"Créér une nouvelle commande",
- "orderStatus":"Afficher le status des Commandes"
- },
- "createConnectionProfile": {
- "title":"Entrer le nom du nouveau profil ici:",
- "cp_type":"type",
- "cp_orderers":"Commandes",
- "cp_orderers_url":"url",
- "cp_ca":"ca",
- "cp_ca_url":"url",
- "cp_ca_name":"nom",
- "cp_peers":"pairs",
- "cp_peers_event_url":"eventURL",
- "cp_peers_request_url":"requestURL",
- "cp_keyValStore":"keyValStore",
- "cp_channel":"canal",
- "cp_mspID":"mspID",
- "cp_timeout":"timeout",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "createMember": {
- "cd_type":"Type",
- "cd_buyer":"Acheteur",
- "cd_seller":"Vendeur",
- "cd_shipper":"Expéditeur",
- "cd_provider":"Fournisseur",
- "cd_financeco":"Financeur",
- "cd_cn":"Nom Companie",
- "cd_e":"Adresse email",
- "cancelNewOrder":"Annuler",
- "submitNewOrder":"Soumettre"
- },
- "createOrder": {
- "title":"Créér un nouvel ordre",
- "selectVendor":"Selectionner fournisseur:",
- "cn_on":"Numéro de commande",
- "cn_status":"Status",
- "cn_date":"Date",
- "cn_total":"Total",
- "cn_selectItem":"Selectionner item",
- "addItem":"Ajouter item",
- "cancelNewOrder":"Annuler",
- "submitNewOrder":"Soumettre"
- },
- "deleteConnectionProfile": {
- "title":"Selectionner le profil à annuler",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "financeCo": {
+ "orderStatus":"Afficher le status des Commandes"
+ },
+ "createConnectionProfile": {
+ "title":"Entrer le nom du nouveau profil ici:",
+ "cp_type":"type",
+ "cp_orderers":"Commandes",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"nom",
+ "cp_peers":"pairs",
+ "cp_peers_event_url":"eventURL",
+ "cp_peers_request_url":"requestURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"canal",
+ "cp_mspID":"mspID",
+ "cp_timeout":"timeout",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "createMember": {
+ "cd_type":"Type",
+ "cd_buyer":"Acheteur",
+ "cd_seller":"Vendeur",
+ "cd_shipper":"Expéditeur",
+ "cd_provider":"Fournisseur",
+ "cd_financeco":"Financeur",
+ "cd_cn":"Nom Companie",
+ "cd_e":"Adresse email",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "createOrder": {
+ "title":"Créér un nouvel ordre",
+ "selectVendor":"Selectionner fournisseur:",
+ "cn_on":"Numéro de commande",
+ "cn_status":"Status",
+ "cn_date":"Date",
+ "cn_total":"Total",
+ "cn_selectItem":"Selectionner item",
+ "addItem":"Ajouter item",
+ "cancelNewOrder":"Annuler",
+ "submitNewOrder":"Soumettre"
+ },
+ "deleteConnectionProfile": {
+ "title":"Selectionner le profil à annuler",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "financeCo": {
"title":"Zero to Blockchain Chapitre 10: Le financier mondial",
"financeCOclear":"Effacer le contenu de la fenetre",
- "financeCOorderStatus":"Afficher le status des Commandes"
- },
- "getMemberSecret": {
- "gs_type":"Type",
- "gs_members":"Membres",
- "gs_company":"Nom Companie",
- "gs_email":"Adresse email",
- "gs_userID":"userID",
- "gs_secret":"secret",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "provider": {
+ "financeCOorderStatus":"Afficher le status des Commandes"
+ },
+ "getMemberSecret": {
+ "gs_type":"Type",
+ "gs_members":"Membres",
+ "gs_company":"Nom Companie",
+ "gs_email":"Adresse email",
+ "gs_userID":"userID",
+ "gs_secret":"secret",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "provider": {
"title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:",
"provider_clear":"Effacer le contenu de la fenetre",
- "providerOrderStatus":"Afficher le status des Commandes"
- },
- "removeMember": {
- "rm_type":"",
- "rm_members":"Type",
- "rm_company":"Membres",
- "rm_email":"Adresse email",
- "rm_userID":"userID",
- "rm_secret":"secret",
- "cancel":"Annuler",
- "submit":"Soumettre"
- },
- "seller": {
+ "providerOrderStatus":"Afficher le status des Commandes"
+ },
+ "removeMember": {
+ "rm_type":"",
+ "rm_members":"Type",
+ "rm_company":"Membres",
+ "rm_email":"Adresse email",
+ "rm_userID":"userID",
+ "rm_secret":"secret",
+ "cancel":"Annuler",
+ "submit":"Soumettre"
+ },
+ "seller": {
"title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:",
"seller_clear":"Effacer le contenu de la fenetre",
- "sellerOrderStatus":"Afficher le status des Commandes"
- },
- "shipper": {
+ "sellerOrderStatus":"Afficher le status des Commandes"
+ },
+ "shipper": {
"title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:",
"shipper_clear":"Effacer le contenu de la fenetre",
- "shipperOrderStatus":"Afficher le status des Commandes"
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"},
- "Dispute": {"select": "Disputer","message":"Dispute"},
- "Resolve": {"select": "Résoudre","message":"Résoudre"},
- "Purchase": {"select": "Acheter","message":"Acheter"},
- "Cancel": {"select": "Annuler","message":"Annuler"},
- "Pay": {"select": "Payer","message":"Payer"},
- "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"},
- "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"},
- "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"},
- "Refund": {"select": "Remboursement","message":"Rembourser"},
- "Delivered": {"select": "Livré","message":"Livré"},
- "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"},
- "Order": {"select": "Commande","message":"Commande du fournisseur"},
- "NoAction": {"select": "Pas d'action","message":"Pas d'action"},
- "ex_button":"Ecécuter",
- "ca_button":"Annuler",
- "orderno":"# Commande",
- "status":"Status",
- "total":"Total",
- "seller":"Vendeur:",
- "itemno":"Numero item",
- "description":"Description",
- "qty":"Quantité",
- "price":"Prix",
- "processing_msg":"Processer{0} demander le numero de commande:{1}",
- "b_no_order_msg":"Pas de commande pour cet acheteur:",
- "s_no_order_msg":"Pas de commande pour ce vendeur:",
- "p_no_order_msg":"Pas de commande pour ce fournisseur:",
- "sh_no_order_msg":"Pas de commande pour cet expéditeur:",
- "create_msg":"Création demande de commande en cours",
- "buyer":"Acheteur:"
- },
- "financeCoOrder": {
- "status":"Status actuel:",
- "action":"Action",
- "by":"Par",
- "date":"Date",
- "comments":"Commentaires",
- "created":"Créé",
- "cancelled":"Annulé?",
- "notCancel":"(non annulé)",
- "purchased":"Acheté",
- "noPurchase":"(pas de demande de commande)",
- "thirdParty":"Commande de partie tierce",
- "nothirdParty":"(pas encire envoyé à partie tierce)",
- "backordered":"Rupture de stock?",
- "notBackordered":"(pas de rupture de stock)",
- "shippingRequested":"Expédition demandée",
- "noRequestShip":"(pas de demande à l'expéditeur)",
- "shippingStarted":"Expédition en cours",
- "noDeliveryStart":"(expédition en attente)",
- "delivered":"Livré",
- "notDelivered":"(pas encore livré)",
- "payRequested":"Paiement demandé",
- "noRequest":"(paiement pas encore demandé)",
- "disputed":"Dispute lancée",
- "noDispute":"(pas de dispute)"
- }
- }
\ No newline at end of file
+ "shipperOrderStatus":"Afficher le status des Commandes"
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"},
+ "Dispute": {"select": "Disputer","message":"Dispute"},
+ "Resolve": {"select": "Résoudre","message":"Résoudre"},
+ "Purchase": {"select": "Acheter","message":"Acheter"},
+ "Cancel": {"select": "Annuler","message":"Annuler"},
+ "Pay": {"select": "Payer","message":"Payer"},
+ "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"},
+ "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"},
+ "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"},
+ "Refund": {"select": "Remboursement","message":"Rembourser"},
+ "Delivered": {"select": "Livré","message":"Livré"},
+ "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"},
+ "Order": {"select": "Commande","message":"Commande du fournisseur"},
+ "NoAction": {"select": "Pas d'action","message":"Pas d'action"},
+ "ex_button":"Ecécuter",
+ "ca_button":"Annuler",
+ "orderno":"# Commande",
+ "status":"Status",
+ "total":"Total",
+ "seller":"Vendeur:",
+ "itemno":"Numero item",
+ "description":"Description",
+ "qty":"Quantité",
+ "price":"Prix",
+ "processing_msg":"Processer(0) demander le numero de commande:(1)",
+ "b_no_order_msg":"Pas de commande pour cet acheteur:",
+ "s_no_order_msg":"Pas de commande pour ce vendeur:",
+ "p_no_order_msg":"Pas de commande pour ce fournisseur:",
+ "sh_no_order_msg":"Pas de commande pour cet expéditeur:",
+ "create_msg":"Création demande de commande en cours",
+ "buyer":"Acheteur:"
+ },
+ "financeCoOrder": {
+ "status":"Status actuel:",
+ "action":"Action",
+ "by":"Par",
+ "date":"Date",
+ "comments":"Commentaires",
+ "created":"Créé",
+ "cancelled":"Annulé?",
+ "notCancel":"(non annulé)",
+ "purchased":"Acheté",
+ "noPurchase":"(pas de demande de commande)",
+ "thirdParty":"Commande de partie tierce",
+ "nothirdParty":"(pas encire envoyé à partie tierce)",
+ "backordered":"Rupture de stock?",
+ "notBackordered":"(pas de rupture de stock)",
+ "shippingRequested":"Expédition demandée",
+ "noRequestShip":"(pas de demande à l'expéditeur)",
+ "shippingStarted":"Expédition en cours",
+ "noDeliveryStart":"(expédition en attente)",
+ "delivered":"Livré",
+ "notDelivered":"(pas encore livré)",
+ "payRequested":"Paiement demandé",
+ "noRequest":"(paiement pas encore demandé)",
+ "disputed":"Dispute lancée",
+ "noDispute":"(pas de dispute)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/features/text/jp/prompts.json b/Chapter06/controller/restapi/features/text/jp/prompts.json
index c7f3c26..76fb476 100644
--- a/Chapter06/controller/restapi/features/text/jp/prompts.json
+++ b/Chapter06/controller/restapi/features/text/jp/prompts.json
@@ -1,219 +1,222 @@
{
- "index": {"language":"米国英語",
- "title":"Z2B 弟 6章",
- "header":"弟 6章: 購入者ユーザー経験の構築",
- "titleBar":"Zero to Blockchainチュートリアル",
- "idx_unified":"統合ユーザー経験のロード",
- "idx_buyer":"購入者ユーザー経験のロード",
- "idx_seller":"販売者ユーザー経験のロード",
- "idx_provider":"プロバイダユーユーザー経験のロード",
- "idx_shipper":"荷送人ユーザー経験のロード",
- "idx_financeco":"財務会社ユーザー経験のロード",
- "idx_roles":"役割",
- "idx_admin":"管理者",
- "idx_adminUX":"管理者ユーザー経験のロード",
- "idx_preload":"事前ロードネットワーク"
- },
- "admin": {
- "title":"Zero To Blockchain 弟05章",
- "npm":"ネットワークプロファイル管理",
- "npm_API":"API",
- "npm_param":"パラメーター",
- "npm_dp_api":"プロフィールの削除",
- "npm_dp_param":"プロフィール名",
- "npm_cp_api":"プロフィールの作成",
- "npm_cp_param":"プロファイルオブジェクト",
- "npm_ga_api":"すべての接続プロファイルの取得",
- "npm_ga_param":"(なし)",
- "npm_g1_api":"特定のネットワーク接続プロファイルの取得",
- "npm_g1_param":"プロフィール名",
- "bnm":"ビジネスネットワーク管理",
- "bnm_param":"パラメーター",
- "bnm_api":"API",
- "bnm_nd_api":"ネットワークの展開",
- "bnm_nd_param":"ネットワークアーカイブファイル、オプション",
- "bnm_ni_api":"新規ネットワークのインストールする",
- "bnm_ni_param":"ネットワークアーカイブファイル、オプション",
- "bnm_ns_api":"インストールされたネットワークの開始",
- "bnm_ns_param":"ネットワーク名、オプション",
- "bnm_nl_api":"展開されたビジネスネットワークの一覧表示",
- "bnm_nl_param":"(なし)",
- "bnm_np_api":"ネットワークに触れる、互換性をチェックする",
- "bnm_np_param":"ビジネスネットワーク名",
- "bnm_nu_api":"ビジネスネットワークをオフラインにする",
- "bnm_nu_param":"ビジネスネットワーク名<",
- "bnm_nuu_api":"既存のビジネスネットワークの更新",
- "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル",
- "rm":"リソース管理",
- "rm_api":"API",
- "rm_param":"パラメーター",
- "rm_lr_api":"レジストリのメンバーの一覧表示",
- "rm_la_api":"レジストリのリストアセット",
- "rm_la_param":"(なし)",
- "rm_am_api":"メンバーの追加",
- "rm_am_param":"Co 名, id, タイプ",
- "rm_rm_api":"メンバーの削除",
- "rm_gs_api":"メンバーシークレットの取得",
- "bc":"ブロックチェーン",
- "bc_api":"API",
- "bc_param":"パラメーター",
- "bc_gi_api":"ブロックチェーンへの接続の開始",
- "bc_gi_param":"(なし)",
- "bc_ge_api":"ブロックチェーンイベントの登録",
- "bc_ge_param":"(なし)",
- "bc_gh_api":"歴史家の取得",
- "bc_gh_param":"(なし)"
- },
- "buyer": {
- "title":"購入者弟06章. 購入者を選択してビューの表示: ",
- "newOrder":"新規発注の作成",
- "orderStatus":"発注状況の表示"
- },
- "createConnectionProfile": {
- "title":"ここに新しいプロファイルの名前を入力してください: ",
- "cp_type":"タイプ",
- "cp_orderers":"発注者",
- "cp_orderers_url":"url",
- "cp_ca":"ca",
- "cp_ca_url":"url",
- "cp_ca_name":"名",
- "cp_peers":"同僚",
- "cp_peers_event_url":"イベントURL",
- "cp_peers_request_url":"依頼URL",
- "cp_keyValStore":"keyValStore",
- "cp_channel":"チャネル",
- "cp_mspID":"mspID",
- "cp_timeout":"タイムアウト",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "createMember": {
- "cd_type":"タイプ",
- "cd_buyer":"購入者",
- "cd_seller":"販売者",
- "cd_shipper":"荷送人",
- "cd_provider":"プロバイダ",
- "cd_financeco":"財務会社",
- "cd_cn":"会社名",
- "cd_e":"e-メールアドレス",
- "cancelNewOrder":"キャンセル",
- "submitNewOrder":"提出"
- },
- "createOrder": {
- "title":"新規発注の作成",
- "selectVendor":"ベンダーの選択: ",
- "cn_on":"発注番号",
- "cn_status":"状態",
- "cn_date":"日付",
- "cn_total":"合計",
- "cn_selectItem":"アイテムの選択",
- "addItem":"アイテムの追加",
- "cancelNewOrder":"キャンセル",
- "submitNewOrder":"提出"
- },
- "deleteConnectionProfile": {
- "title":"削除するプロファイルの選択: ",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "financeCo": {
- "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー",
- "financeCOclear":"ウィンドウのクリア",
- "financeCOorderStatus":"発注状況の表示"
- },
- "getMemberSecret": {
- "gs_type":"タイプ",
- "gs_members":"メンバー",
- "gs_company":"会社名",
- "gs_email":"e-メールアドレス",
- "gs_userID":"ユーザーID",
- "gs_secret":"シークレット",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "provider": {
- "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ",
- "provider_clear":"ウィンドウのクリア",
- "providerOrderStatus":"発注状況の表示"
- },
- "removeMember": {
- "rm_type":"タイプ",
- "rm_members":"メンバー",
- "rm_company":"会社名",
- "rm_email":"e-メールアドレス",
- "rm_userID":"ユーザーID",
- "rm_secret":"シークレット",
- "cancel":"キャンセル",
- "submit":"提出"
- },
- "seller": {
- "title":"販売者弟07章, 販売者を選択してビューの表示: ",
- "seller_clear":"ウィンドウのクリア",
- "sellerOrderStatus":"発注状況の表示"
- },
- "shipper": {
- "title":"荷送人弟09章, 荷送人を選択してビューの表示: ",
- "shipper_clear":"ウィンドウのクリア",
- "shipperOrderStatus":"発注状況の表示 "
- },
- "singleUX": {},
- "orderProcess": {
- "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"},
- "Dispute": {"select": "紛争","message":"紛争"},
- "Resolve": {"select": "解決","message":"解決"},
- "Purchase": {"select": "購入","message":"購入"},
- "Cancel": {"select": "キャンセル","message":"キャンセル"},
- "Pay": {"select": "支払い","message":"支払い"},
- "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"},
- "BackOrder": {"select": "バックワード","message":"バックワード"},
- "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"},
- "Refund": {"select": "払い戻し","message":"払い戻し"},
- "Delivered": {"select": "配信されました","message":"配信されました"},
- "Delivering": {"select": "配信されています","message":"配信状況の更新"},
- "Order": {"select": "発注","message":"サプライヤからの発注"},
- "NoAction": {"select": "アクションがありません","message":"何もしない"},
- "ex_button":"実行",
- "ca_button":"キャンセル",
- "orderno":"発注 #",
- "status":"状態",
- "total":"合計",
- "seller":"販売者: ",
- "itemno":"アイテム番号",
- "description":"説明",
- "qty":"数量",
- "price":"価格",
- "processing_msg":"発注番号の処理{0}依頼:{1}",
- "b_no_order_msg":"本購入者の発注はありません: ",
- "s_no_order_msg":"本販売者の発注はありません: ",
- "p_no_order_msg":"本プロバイダの発注はありません: ",
- "sh_no_order_msg":"本荷送人の発注はありません: ",
- "create_msg":"発注の作成の処理",
- "buyer":"購入者: "
- },
- "financeCoOrder": {
- "status":"現在の状態: ",
- "action":"アクション",
- "by":"から",
- "date":"日付",
- "comments":"コメント",
- "created":"作成されました",
- "cancelled":"キャンセルされましたか?",
- "notCancel":"(キャンセルされていません)",
- "purchased":"購入されました",
- "noPurchase":"(購入依頼がありません)",
- "thirdParty":"第三者発注",
- "nothirdParty":"(まだ第三者に送られていません)",
- "backordered":"バックワードされていますか?",
- "notBackordered":"(バックワードされていません)",
- "shippingRequested":"出荷の依頼",
- "noRequestShip":"(荷送人への依頼がありません)",
- "shippingStarted":"出荷の開始",
- "noDeliveryStart":"(出荷は開始されていません)",
- "delivered":"配信されました",
- "notDelivered":"(配信されていません)",
- "payRequested":"支払いの依頼",
- "noRequest":"(支払いの依頼がありません)",
- "disputed":"紛争は申請されました",
- "noDispute":"(紛争ではありません)"
- }
- }
\ No newline at end of file
+ "index": {"language":"米国英語",
+ "title":"Z2B 弟 6章",
+ "header":"弟 6章: 購入者ユーザー経験の構築",
+ "titleBar":"Zero to Blockchainチュートリアル",
+ "idx_unified":"統合ユーザー経験のロード",
+ "idx_buyer":"購入者ユーザー経験のロード",
+ "idx_seller":"販売者ユーザー経験のロード",
+ "idx_provider":"プロバイダユーユーザー経験のロード",
+ "idx_shipper":"荷送人ユーザー経験のロード",
+ "idx_financeco":"財務会社ユーザー経験のロード",
+ "idx_roles":"役割",
+ "idx_admin":"管理者",
+ "idx_adminUX":"管理者ユーザー経験のロード",
+ "idx_preload":"事前ロードネットワーク"
+ },
+ "admin": {
+ "title":"Zero To Blockchain 弟05章",
+ "npm":"ネットワークプロファイル管理",
+ "npm_API":"API",
+ "npm_param":"パラメーター",
+ "npm_dp_api":"プロフィールの削除",
+ "npm_dp_param":"プロフィール名",
+ "npm_cp_api":"プロフィールの作成",
+ "npm_cp_param":"プロファイルオブジェクト",
+ "npm_ga_api":"すべての接続プロファイルの取得",
+ "npm_ga_param":"(なし)",
+ "npm_g1_api":"特定のネットワーク接続プロファイルの取得",
+ "npm_g1_param":"プロフィール名",
+ "bnm":"ビジネスネットワーク管理",
+ "bnm_param":"パラメーター",
+ "bnm_api":"API",
+ "bnm_nd_api":"ネットワークの展開",
+ "bnm_nd_param":"ネットワークアーカイブファイル、オプション",
+ "bnm_ni_api":"新規ネットワークのインストールする",
+ "bnm_ni_param":"ネットワークアーカイブファイル、オプション",
+ "bnm_ns_api":"インストールされたネットワークの開始",
+ "bnm_ns_param":"ネットワーク名、オプション",
+ "bnm_nl_api":"展開されたビジネスネットワークの一覧表示",
+ "bnm_nl_param":"(なし)",
+ "bnm_np_api":"ネットワークに触れる、互換性をチェックする",
+ "bnm_np_param":"ビジネスネットワーク名",
+ "bnm_nu_api":"ビジネスネットワークをオフラインにする",
+ "bnm_nu_param":"ビジネスネットワーク名<",
+ "bnm_nuu_api":"既存のビジネスネットワークの更新",
+ "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル",
+ "rm":"リソース管理",
+ "rm_api":"API",
+ "rm_param":"パラメーター",
+ "rm_lr_api":"レジストリのメンバーの一覧表示",
+ "rm_la_api":"レジストリのリストアセット",
+ "rm_la_param":"(なし)",
+ "rm_am_api":"メンバーの追加",
+ "rm_am_param":"Co 名, id, タイプ",
+ "rm_rm_api":"メンバーの削除",
+ "rm_gs_api":"メンバーシークレットの取得",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Check if card exists",
+ "rm_cc2_api": "Create Card",
+ "bc":"ブロックチェーン",
+ "bc_api":"API",
+ "bc_param":"パラメーター",
+ "bc_gi_api":"ブロックチェーンへの接続の開始",
+ "bc_gi_param":"(なし)",
+ "bc_ge_api":"ブロックチェーンイベントの登録",
+ "bc_ge_param":"(なし)",
+ "bc_gh_api":"歴史家の取得",
+ "bc_gh_param":"(なし)"
+ },
+ "buyer": {
+ "title":"購入者弟06章. 購入者を選択してビューの表示: ",
+ "newOrder":"新規発注の作成",
+ "orderStatus":"発注状況の表示"
+ },
+ "createConnectionProfile": {
+ "title":"ここに新しいプロファイルの名前を入力してください: ",
+ "cp_type":"タイプ",
+ "cp_orderers":"発注者",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"名",
+ "cp_peers":"同僚",
+ "cp_peers_event_url":"イベントURL",
+ "cp_peers_request_url":"依頼URL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"チャネル",
+ "cp_mspID":"mspID",
+ "cp_timeout":"タイムアウト",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "createMember": {
+ "cd_type":"タイプ",
+ "cd_buyer":"購入者",
+ "cd_seller":"販売者",
+ "cd_shipper":"荷送人",
+ "cd_provider":"プロバイダ",
+ "cd_financeco":"財務会社",
+ "cd_cn":"会社名",
+ "cd_e":"e-メールアドレス",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "createOrder": {
+ "title":"新規発注の作成",
+ "selectVendor":"ベンダーの選択: ",
+ "cn_on":"発注番号",
+ "cn_status":"状態",
+ "cn_date":"日付",
+ "cn_total":"合計",
+ "cn_selectItem":"アイテムの選択",
+ "addItem":"アイテムの追加",
+ "cancelNewOrder":"キャンセル",
+ "submitNewOrder":"提出"
+ },
+ "deleteConnectionProfile": {
+ "title":"削除するプロファイルの選択: ",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "financeCo": {
+ "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー",
+ "financeCOclear":"ウィンドウのクリア",
+ "financeCOorderStatus":"発注状況の表示"
+ },
+ "getMemberSecret": {
+ "gs_type":"タイプ",
+ "gs_members":"メンバー",
+ "gs_company":"会社名",
+ "gs_email":"e-メールアドレス",
+ "gs_userID":"ユーザーID",
+ "gs_secret":"シークレット",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "provider": {
+ "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ",
+ "provider_clear":"ウィンドウのクリア",
+ "providerOrderStatus":"発注状況の表示"
+ },
+ "removeMember": {
+ "rm_type":"タイプ",
+ "rm_members":"メンバー",
+ "rm_company":"会社名",
+ "rm_email":"e-メールアドレス",
+ "rm_userID":"ユーザーID",
+ "rm_secret":"シークレット",
+ "cancel":"キャンセル",
+ "submit":"提出"
+ },
+ "seller": {
+ "title":"販売者弟07章, 販売者を選択してビューの表示: ",
+ "seller_clear":"ウィンドウのクリア",
+ "sellerOrderStatus":"発注状況の表示"
+ },
+ "shipper": {
+ "title":"荷送人弟09章, 荷送人を選択してビューの表示: ",
+ "shipper_clear":"ウィンドウのクリア",
+ "shipperOrderStatus":"発注状況の表示 "
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"},
+ "Dispute": {"select": "紛争","message":"紛争"},
+ "Resolve": {"select": "解決","message":"解決"},
+ "Purchase": {"select": "購入","message":"購入"},
+ "Cancel": {"select": "キャンセル","message":"キャンセル"},
+ "Pay": {"select": "支払い","message":"支払い"},
+ "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"},
+ "BackOrder": {"select": "バックワード","message":"バックワード"},
+ "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"},
+ "Refund": {"select": "払い戻し","message":"払い戻し"},
+ "Delivered": {"select": "配信されました","message":"配信されました"},
+ "Delivering": {"select": "配信されています","message":"配信状況の更新"},
+ "Order": {"select": "発注","message":"サプライヤからの発注"},
+ "NoAction": {"select": "アクションがありません","message":"何もしない"},
+ "ex_button":"実行",
+ "ca_button":"キャンセル",
+ "orderno":"発注 #",
+ "status":"状態",
+ "total":"合計",
+ "seller":"販売者: ",
+ "itemno":"アイテム番号",
+ "description":"説明",
+ "qty":"数量",
+ "price":"価格",
+ "processing_msg":"発注番号の処理{0}依頼:{1}",
+ "b_no_order_msg":"本購入者の発注はありません: ",
+ "s_no_order_msg":"本販売者の発注はありません: ",
+ "p_no_order_msg":"本プロバイダの発注はありません: ",
+ "sh_no_order_msg":"本荷送人の発注はありません: ",
+ "create_msg":"発注の作成の処理",
+ "buyer":"購入者: "
+ },
+ "financeCoOrder": {
+ "status":"現在の状態: ",
+ "action":"アクション",
+ "by":"から",
+ "date":"日付",
+ "comments":"コメント",
+ "created":"作成されました",
+ "cancelled":"キャンセルされましたか?",
+ "notCancel":"(キャンセルされていません)",
+ "purchased":"購入されました",
+ "noPurchase":"(購入依頼がありません)",
+ "thirdParty":"第三者発注",
+ "nothirdParty":"(まだ第三者に送られていません)",
+ "backordered":"バックワードされていますか?",
+ "notBackordered":"(バックワードされていません)",
+ "shippingRequested":"出荷の依頼",
+ "noRequestShip":"(荷送人への依頼がありません)",
+ "shippingStarted":"出荷の開始",
+ "noDeliveryStart":"(出荷は開始されていません)",
+ "delivered":"配信されました",
+ "notDelivered":"(配信されていません)",
+ "payRequested":"支払いの依頼",
+ "noRequest":"(支払いの依頼がありません)",
+ "disputed":"紛争は申請されました",
+ "noDispute":"(紛争ではありません)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/features/text/languages.json b/Chapter06/controller/restapi/features/text/languages.json
index 91b0348..8ee6b21 100644
--- a/Chapter06/controller/restapi/features/text/languages.json
+++ b/Chapter06/controller/restapi/features/text/languages.json
@@ -6,6 +6,6 @@
"French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"},
"Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"},
"Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"},
- "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"}
+ "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"}
}
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/features/text/pt/prompts.json b/Chapter06/controller/restapi/features/text/pt/prompts.json
index 4a3c1db..11311d1 100644
--- a/Chapter06/controller/restapi/features/text/pt/prompts.json
+++ b/Chapter06/controller/restapi/features/text/pt/prompts.json
@@ -1,7 +1,222 @@
{
- "index": {"language": "Português do Brasi",
- "title": "Saiba Bluemix agora!",
- "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app",
- "titleBar": "Zero de déficit cognitivo Tutorial",
- "speech": "Falei a saída vai aqui"}
-}
+ "index": {"language":"Inglês Americano",
+ "title":"Z2B Capítulo 6",
+ "header":"Capítulo 6: Construindo a Experiência de Usuário Consumidor",
+ "titleBar":"Tutorial Zero to Blockchain",
+ "idx_unified":"carregar a Experiência de Usuário Unificado",
+ "idx_buyer":"carregar a Experiência de Usuário Consumidor",
+ "idx_seller":"carregar a Experiência de Usuário Vendedor",
+ "idx_provider":"carregar a Experiência de Usuário Fornecedor",
+ "idx_shipper":"carregar a Experiência de Usuário Transportador",
+ "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira",
+ "idx_roles":"Cargos",
+ "idx_admin":"Administrador ",
+ "idx_adminUX":"carregar a Experiência de Usuário Administrador",
+ "idx_preload":"Carregar previamente a rede"
+ },
+ "admin": {
+ "title":"Zero to Blockchain Capítulo 5",
+ "npm":"Gerenciamento de perfil de rede",
+ "npm_API":"API",
+ "npm_param":"Parametros",
+ "npm_dp_api":"deletar perfil",
+ "npm_dp_param":"nome do perfil",
+ "npm_cp_api":"criar perfil",
+ "npm_cp_param":"objeto de perfil",
+ "npm_ga_api":"obter todos os perfis de conexão",
+ "npm_ga_param":"",
+ "npm_g1_api":"obter um perfil específico de conexão de rede",
+ "npm_g1_param":"nome do perfil",
+ "bnm":"Gerenciamento da rede de negócios",
+ "bnm_param":"Parametros",
+ "bnm_api":"API",
+ "bnm_nd_api":"implantar uma rede",
+ "bnm_nd_param":"arquivar arquivo de rede, opções",
+ "bnm_ni_api":"instalar nova rede",
+ "bnm_ni_param":"arquivar arquivo de rede, opções",
+ "bnm_ns_api":"Iniciar rede instalada",
+ "bnm_ns_param":"nome da rede, opções",
+ "bnm_nl_api":"listas de redes de negócios implantadas",
+ "bnm_nl_param":"",
+ "bnm_np_api":"toque uma rede, verifique a compatibilidade",
+ "bnm_np_param":"nome da rede de negócios",
+ "bnm_nu_api":"pegue uma rede de negócios off line",
+ "bnm_nu_param":"nome da rede de negócios",
+ "bnm_nuu_api":"atualizar rede de negócios existente",
+ "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo",
+ "rm":"Gestão de Recursos",
+ "rm_api":"API",
+ "rm_param":"Parametros",
+ "rm_lr_api":"lista membros de um registro",
+ "rm_la_api":"Lista de ativos no registro",
+ "rm_la_param":"",
+ "rm_am_api":"Adicionar Membro",
+ "rm_am_param":"Co Nome, id, Tipo",
+ "rm_rm_api":"Remover Membro",
+ "rm_gs_api":"getMemberSecret",
+ "rm_ii_api":"Issue Identity",
+ "rm_cc_api":"Verifique se o cartão de identidade existe",
+ "rm_cc2_api": "criar um documento de identidade",
+ "bc":"BlockChain",
+ "bc_api":"API",
+ "bc_param":"Parametros",
+ "bc_gi_api":"iniciar conexão com Blockchain",
+ "bc_gi_param":"",
+ "bc_ge_api":"Registro para eventos de Blockchain",
+ "bc_ge_param":"",
+ "bc_gh_api":"obter histórico",
+ "bc_gh_param":""
+ },
+ "buyer": {
+ "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:",
+ "newOrder":"Criar novo pedido",
+ "orderStatus":"Exibir Estatus de Pedidos"
+ },
+ "createConnectionProfile": {
+ "title":"Digite o nome de perfil novo aqui:",
+ "cp_type":"tipo",
+ "cp_orderers":"ordenadores",
+ "cp_orderers_url":"url",
+ "cp_ca":"ca",
+ "cp_ca_url":"url",
+ "cp_ca_name":"nome",
+ "cp_peers":"colegas",
+ "cp_peers_event_url":"eventURL",
+ "cp_peers_request_url":"requestURL",
+ "cp_keyValStore":"keyValStore",
+ "cp_channel":"canal",
+ "cp_mspID":"mspID",
+ "cp_timeout":"Tempo Esgotado",
+ "cancel":"cancelar",
+ "submit":"submeter"
+ },
+ "createMember": {
+ "cd_type":"Tipo",
+ "cd_buyer":"Consumidor",
+ "cd_seller":"Vendedor",
+ "cd_shipper":"Transportador",
+ "cd_provider":"Fornecedor",
+ "cd_financeco":"Empresa Financeira",
+ "cd_cn":"Nome da Empresa",
+ "cd_e":"Endereço de email",
+ "cancel":"Cancelar",
+ "submit":"Submeter"
+ },
+ "createOrder": {
+ "title":"Criar novo pedido",
+ "selectVendor":"Selecione Vendedor:",
+ "cn_on":"Numero do Pedido",
+ "cn_status":"Estatus",
+ "cn_date":"Data",
+ "cn_total":"Total",
+ "cn_selectItem":"Selecionar Item",
+ "addItem":"Adicionar Item",
+ "cancelNewOrder":"cancelar",
+ "submitNewOrder":"submeter"
+ },
+ "deleteConnectionProfile": {
+ "title":"Selecionar Perfil para deletar:",
+ "cancel":"cancelar",
+ "submit":"submeter"
+ },
+ "financeCo": {
+ "title":"Zero to Blockchain Capítulo 10: O Financeiro Global",
+ "financeCOclear":"Limpar Janela",
+ "financeCOorderStatus":"Exibir Estatus de Pedidos"
+ },
+ "getMemberSecret": {
+ "gs_type":"Tipo",
+ "gs_members":"Membros",
+ "gs_company":"Nome da Empresa",
+ "gs_email":"Endereço de email",
+ "gs_userID":"userID",
+ "gs_secret":"secret",
+ "cancel":"cancelar",
+ "submit":"submeter"
+ },
+ "provider": {
+ "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:",
+ "provider_clear":"Limpar Janela",
+ "providerOrderStatus":"Exibir Estatus de Pedidos"
+ },
+ "removeMember": {
+ "rm_type":"Tipo",
+ "rm_members":"Membros",
+ "rm_company":"Nome da Empresa",
+ "rm_email":"Endereço de email",
+ "rm_userID":"userID",
+ "rm_secret":"secret",
+ "cancel":"Cancelar",
+ "submit":"Submeter"
+ },
+ "seller": {
+ "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:",
+ "seller_clear":"Limpar Janela",
+ "sellerOrderStatus":"Exibir Estatus de Pedidos"
+ },
+ "shipper": {
+ "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:",
+ "shipper_clear":"Limpar Janela",
+ "shipperOrderStatus":"Exibir Estatus de Pedidos"
+ },
+ "singleUX": {},
+ "orderProcess": {
+ "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"},
+ "Dispute": {"select": "Disputa","message":"Disputa"},
+ "Resolve": {"select": "Resolver","message":"Resolver"},
+ "Purchase": {"select": "Compra","message":"Compra"},
+ "Cancel": {"select": "Cancelar","message":"Cancelar"},
+ "Pay": {"select": "Pagar","message":"Pagar"},
+ "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"},
+ "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"},
+ "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"},
+ "Refund": {"select": "Reembolsar","message":"Reembolsar"},
+ "Delivered": {"select": "Entregue","message":"Entregue"},
+ "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"},
+ "Order": {"select": "Pedido","message":"Pedido do fornecedor"},
+ "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"},
+ "ex_button":"Executar",
+ "ca_button":"Cancelar",
+ "orderno":"Pedido #",
+ "status":"Estatus",
+ "total":"Total",
+ "seller":"Vendedor:",
+ "itemno":"Numero do Item",
+ "description":"Descrição",
+ "qty":"Quantidade",
+ "price":"Preço",
+ "processing_msg":"Processando {0} solicitação para o número do pedido: {1}",
+ "b_no_order_msg":"Sem pedidos para esse consumidor:",
+ "s_no_order_msg":"Sem pedidos para esse vendedor:",
+ "p_no_order_msg":"Sem pedidos para esse fornecedor:",
+ "sh_no_order_msg":"Sem pedidos para esse transportador:",
+ "create_msg":"Processando requerimento de criar pedido",
+ "buyer":"Consumidor:"
+ },
+ "financeCoOrder": {
+ "status":"Estatus Atual",
+ "action":"Ação",
+ "by":"Por",
+ "date":"Data",
+ "comments":"Comentarios",
+ "created":"Criado",
+ "cancelled":"Cancelado",
+ "notCancel":"(não cancelado)",
+ "purchased":"Comprado",
+ "noPurchase":"(sem solicitação de compra)",
+ "thirdParty":"Pedido de terceiros",
+ "nothirdParty":"(ainda não enviado para terceiros)",
+ "backordered":"Reencaminhado?",
+ "notBackordered":"(não reencaminhado)",
+ "shippingRequested":"Envio Solicitado",
+ "noRequestShip":"(sem solicitação de envio)",
+ "shippingStarted":"Envio Iniciado",
+ "noDeliveryStart":"Entrega não iniciada",
+ "delivered":"Entregue",
+ "notDelivered":"(ainda não entregue)",
+ "payRequested":"Pagamento solicitado",
+ "noRequest":"(sem solicitação de pagamento)",
+ "disputed":"Disputa levantada",
+ "noDispute":"(não em disputa)"
+ }
+ }
\ No newline at end of file
diff --git a/Chapter06/controller/restapi/router.js b/Chapter06/controller/restapi/router.js
index dad4fa2..6fa15bd 100644
--- a/Chapter06/controller/restapi/router.js
+++ b/Chapter06/controller/restapi/router.js
@@ -12,18 +12,19 @@
* limitations under the License.
*/
+'use strict';
-var express = require('express');
-var router = express.Router();
-var format = require('date-format');
+let express = require('express');
+let router = express.Router();
+let format = require('date-format');
-var multi_lingual = require('./features/multi_lingual');
-var resources = require('./features/resources');
-var getCreds = require('./features/getCredentials');
-var hlcAdmin = require('./features/composer/hlcAdmin');
-var hlcClient = require('./features/composer/hlcClient');
-var setup = require('./features/composer/autoLoad');
-var hlcFabric = require('./features/composer/queryBlockChain');
+let multi_lingual = require('./features/multi_lingual');
+let resources = require('./features/resources');
+let getCreds = require('./features/getCredentials');
+let hlcAdmin = require('./features/composer/hlcAdmin');
+let hlcClient = require('./features/composer/hlcClient');
+let setup = require('./features/composer/autoLoad');
+let hlcFabric = require('./features/composer/queryBlockChain');
router.post('/setup/autoLoad*', setup.autoLoad);
router.get('/setup/getPort*', setup.getPort);
@@ -32,28 +33,28 @@ router.get('/fabric/getChainEvents', hlcFabric.getChainEvents);
router.get('/fabric/getHistory', hlcAdmin.getHistory);
module.exports = router;
-var count = 0;
+let count = 0;
/**
- * This is a request tracking function which logs to the terminal window each request coming in to the web serve and
+ * This is a request tracking function which logs to the terminal window each request coming in to the web serve and
* increments a counter to allow the requests to be sequenced.
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- *
+ *
* @function
*/
router.use(function(req, res, next) {
- count++;
- console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url);
- next(); // make sure we go to the next routes and don't stop here
+ count++;
+ console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url);
+ next(); // make sure we go to the next routes and don't stop here
});
// the following get and post statements tell nodeJS what to do when a request comes in
-// The request is the single quoted phrase following the get( or post( statement.
+// The request is the single quoted phrase following the get( or post( statement.
// the text at the end identifies which function in which require(d) module to implement
-// These are searched in order by get/post request.
+// These are searched in order by get/post request.
// The asterisk (*) means 'ignore anything following this point'
-// which means we have to be careful about ordering these statements.
+// which means we have to be careful about ordering these statements.
//
router.get('/api/getSupportedLanguages*',multi_lingual.languages);
router.get('/api/getTextLocations*',multi_lingual.locations);
@@ -69,7 +70,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds);
router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles);
router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin);
router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries);
-router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin);
router.post('/composer/admin/createProfile*', hlcAdmin.createProfile);
router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile);
@@ -86,6 +86,9 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets);
router.post('/composer/admin/addMember*', hlcAdmin.addMember);
router.post('/composer/admin/removeMember*', hlcAdmin.removeMember);
router.post('/composer/admin/getSecret*', setup.getMemberSecret);
+router.post('/composer/admin/checkCard*', hlcAdmin.checkCard);
+router.post('/composer/admin/createCard*', hlcAdmin.createCard);
+router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity);
// router requests specific to the Buyer
router.get('/composer/client/getItemTable*', hlcClient.getItemTable);
diff --git a/Chapter06/createArchive.sh b/Chapter06/createArchive.sh
index f7640c6..cb2371a 100755
--- a/Chapter06/createArchive.sh
+++ b/Chapter06/createArchive.sh
@@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent
showStep "creating archive"
cd ./network
-composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
\ No newline at end of file
+composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna
+#
+# new create command from tutorial is following:
+# composer archive create -t dir -n .
+#
\ No newline at end of file
diff --git a/Chapter06/deployNetwork.sh b/Chapter06/deployNetwork.sh
index 9c13a36..d9042c9 100755
--- a/Chapter06/deployNetwork.sh
+++ b/Chapter06/deployNetwork.sh
@@ -80,12 +80,38 @@ showStep "deploying network"
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString
#
-# what the documentation implies is required
+# what the v0.14 documentation implies is required
# cd network/dist
# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
#
-# what really works
-composer identity request -p hlfv1 -i admin -s adminpw
-composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# what really works for v0.14
+# composer identity request -p hlfv1 -i admin -s adminpw
+# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem
+# cd network/dist
+# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+#
+# documentation for v0.15
+#
cd network/dist
-composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString
+showStep "installing PeerAdmin card"
+composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME
+showStep "starting network"
+# change in documentation
+# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card
+# corrected to:
+composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card
+showStep "importing networkadmin card"
+if composer card list -n admin@$NETWORK_NAME > /dev/null; then
+ composer card delete -n admin@$NETWORK_NAME
+fi
+composer card import --file networkadmin.card
+showStep "pinging admin@$NETWORK_NAME card"
+composer network ping --card admin@$NETWORK_NAME
+#
+# creating card for test program
+# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin
+# composer card import --file defaultProfile@hlfv1.card
+# showStep "pinging defaultProfile@hlfv1 card"
+# composer network ping --card defaultProfile@hlfv1
+#
+
diff --git a/Chapter06/favicon.ico b/Chapter06/favicon.ico
index 4126853..fc9e25d 100755
Binary files a/Chapter06/favicon.ico and b/Chapter06/favicon.ico differ
diff --git a/Chapter06/network/dist/networkadmin.card b/Chapter06/network/dist/networkadmin.card
new file mode 100644
index 0000000..7238f6d
Binary files /dev/null and b/Chapter06/network/dist/networkadmin.card differ
diff --git a/Chapter06/network/package.json b/Chapter06/network/package.json
index be89bc0..5ef56b0 100644
--- a/Chapter06/network/package.json
+++ b/Chapter06/network/package.json
@@ -36,11 +36,11 @@
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-admin": "^0.14.0",
- "composer-cli": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
+ "composer-admin": "^0.16.0",
+ "composer-cli": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
diff --git a/Chapter06/network/test/sample.js b/Chapter06/network/test/sample.js
index 1c3e3e6..4bacd5f 100644
--- a/Chapter06/network/test/sample.js
+++ b/Chapter06/network/test/sample.js
@@ -14,18 +14,11 @@
'use strict';
-const AdminConnection = require('composer-admin').AdminConnection;
-const BrowserFS = require('browserfs/dist/node/index');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
-const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
-const path = require('path');
require('chai').should();
-const network = 'zerotoblockchain-network';
-const adminID = 'admin';
-const adminPW = 'adminpw';
-const bfs_fs = BrowserFS.BFSRequire('fs');
+const _timeout = 90000;
const NS = 'org.acme.Z2BTestNetwork';
const orderNo = '12345';
const buyerID = 'billybob@email.com';
@@ -110,30 +103,12 @@ function addItems (_inbound)
return (_inbound);
}
-describe('Finance Network', () => {
-
- // let adminConnection;
+describe('Finance Network', function () {
+ this.timeout(_timeout);
let businessNetworkConnection;
-
- before(() => {
- BrowserFS.initialize(new BrowserFS.FileSystem.InMemory());
- const adminConnection = new AdminConnection({ fs: bfs_fs });
- return adminConnection.createProfile('defaultProfile', {
- type: 'embedded'
- })
- .then(() => {
- return adminConnection.connect('defaultProfile', adminID, adminPW);
- })
- .then(() => {
- return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..'));
- })
- .then((businessNetworkDefinition) => {
- return adminConnection.deploy(businessNetworkDefinition);
- })
- .then(() => {
- businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs });
- return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW);
- });
+ before(function () {
+ businessNetworkConnection = new BusinessNetworkConnection();
+ return businessNetworkConnection.connect('admin@zerotoblockchain-network');
});
describe('#createOrder', () => {
diff --git a/Chapter06/package.json b/Chapter06/package.json
index 1d086ff..57535e3 100644
--- a/Chapter06/package.json
+++ b/Chapter06/package.json
@@ -17,7 +17,8 @@
"doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out",
"test-inner": "mocha -t 0 --recursive && cucumber-js",
"test-cover": "nyc npm run test-inner",
- "test": "mocha network/test --recursive -t 4000"
+ "test": "mocha network/test --recursive -t 4000",
+ "start": "node index"
},
"repository": {
"type": "git",
@@ -37,13 +38,13 @@
"browserfs": "^1.2.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
- "composer-connector-embedded": "^0.14.0",
- "composer-cucumber-steps": "^0.14.0",
- "composer-admin": "^0.14.0",
- "composer-client": "^0.14.0",
- "composer-common": "^0.14.0",
- "composer-runtime": "^0.14.0",
- "composer-runtime-hlfv1": "^0.14.0",
+ "composer-connector-embedded": "^0.16.0",
+ "composer-cucumber-steps": "^0.16.0",
+ "composer-admin": "^0.16.0",
+ "composer-client": "^0.16.0",
+ "composer-common": "^0.16.0",
+ "composer-runtime": "^0.16.0",
+ "composer-runtime-hlfv1": "^0.16.0",
"cucumber": "^2.2.0",
"eslint": "^3.6.1",
"istanbul": "^0.4.5",
@@ -100,6 +101,7 @@
"http": "0.0.0",
"https": "^1.0.0",
"mime": "^2.0.2",
+ "os": "^0.1.1",
"path": "^0.12.7",
"sleep": "^5.1.1",
"uuid": "^3.1.0",
diff --git a/Chapter06/startup.sh b/Chapter06/startup.sh
index 33108c7..a4602d8 100755
--- a/Chapter06/startup.sh
+++ b/Chapter06/startup.sh
@@ -1,11 +1,46 @@
#!/bin/bash
-. ../common_OSX.sh
+ YELLOW='\033[1;33m'
+ RED='\033[1;31m'
+ GREEN='\033[1;32m'
+ RESET='\033[0m'
+
+# indent text on echo
+function indent() {
+ c='s/^/ /'
+ case $(uname) in
+ Darwin) sed -l "$c";;
+ *) sed -u "$c";;
+ esac
+}
+
+# Grab the current directory
+function getCurrent()
+ {
+ showStep "getting current directory"
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+ THIS_SCRIPT=`basename "$0"`
+ showStep "Running '${THIS_SCRIPT}'"
+ }
+
+# displays where we are, uses the indent function (above) to indent each line
+function showStep ()
+ {
+ echo -e "${YELLOW}=====================================================" | indent
+ echo -e "${RESET}-----> $*" | indent
+ echo -e "${YELLOW}=====================================================${RESET}" | indent
+ }
showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}"
cd "${HLF_INSTALL_PATH}"
showStep "starting fabric"
-./startFabric.sh
-showStep "creating new composer profile (required with each restart)"
-./createComposerProfile.sh
+~/fabric-tools/startFabric.sh
+#
+# no longer required with hyperledger composer V0.15
+# showStep "creating new composer profile (required with each restart)"
+# ~/fabric-tools/createComposerProfile.sh
+#
+showStep "creating new PeerAdmin card (required with each restart)"
+~/fabric-tools/createPeerAdminCard.sh
+composer card list --name PeerAdmin@hlfv1
showStep "start up complete"
\ No newline at end of file
diff --git a/Chapter06/z2c_login b/Chapter06/z2c_login
index 9743fc0..b8aba8a 100755
--- a/Chapter06/z2c_login
+++ b/Chapter06/z2c_login
@@ -1,6 +1,5 @@
#!/bin/bash
-ded_URL="https://api.w3ibm.bluemix.net"
pub_URL="https://api.ng.bluemix.net"
gb_URL="https://api.eu-gb.bluemix.net"
de_URL="https://api.eu-de.bluemix.net"
@@ -18,7 +17,7 @@ then targetURL=$de_URL
elif [[ $2 == "sydney" ]]
then targetURL=$au_URL
else
- echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:"
+ echo "Parameter 2 is required to be one of the following public designations:"
echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'"
echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'"
exit -1
diff --git a/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf
index 789736e..b7a141a 100644
Binary files a/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf and b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf differ
diff --git a/Chapter07/Documentation/Chinese/Z2B_Chapter07.pptx b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pptx
new file mode 100644
index 0000000..06a1e0a
Binary files /dev/null and b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pptx differ
diff --git a/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf
index fdf9240..357fbcf 100644
Binary files a/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf and b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf differ
diff --git a/Chapter07/Documentation/Espanol/Z2B_Chapter07.pptx b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pptx
new file mode 100644
index 0000000..5b44792
Binary files /dev/null and b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pptx differ
diff --git a/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf
index 62aa4a8..917e26c 100644
Binary files a/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf and b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf differ
diff --git a/Chapter07/Documentation/Japanese/Z2B_Chapter07.pptx b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pptx
new file mode 100644
index 0000000..ecba27d
Binary files /dev/null and b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pptx differ
diff --git a/Chapter07/Documentation/Z2B Chapter07.pdf b/Chapter07/Documentation/Z2B Chapter07.pdf
index b71c481..d04cad7 100644
Binary files a/Chapter07/Documentation/Z2B Chapter07.pdf and b/Chapter07/Documentation/Z2B Chapter07.pdf differ
diff --git a/Chapter07/Documentation/answers/composer/hlcClient_complete.js b/Chapter07/Documentation/answers/composer/hlcClient_complete.js
index 1c43f70..d484aa5 100644
--- a/Chapter07/Documentation/answers/composer/hlcClient_complete.js
+++ b/Chapter07/Documentation/answers/composer/hlcClient_complete.js
@@ -14,15 +14,14 @@
'use strict';
-var fs = require('fs');
-var path = require('path');
+let fs = require('fs');
+let path = require('path');
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
-const config = require('../../../env.json');
+// const config = require('../../../env.json');
const NS = 'org.acme.Z2BTestNetwork';
let itemTable = null;
const svc = require('./Z2B_Services');
-const util = require('./Z2B_Utilities');
const financeCoID = 'easymoney@easymoneyinc.com';
/**
@@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com';
* @param {express.req} req - the inbound request object from the client
* req.body.id - the id of the buyer making the request
* req.body.userID - the user id of the buyer in the identity table making this request
- * req.body.secret - the pw of this user.
+ * req.body.secret - the pw of this user.
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.getMyOrders = function (req, res, next) {
// connect to the network
- let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json')));
+ let method = 'getMyOrders';
+ console.log(method+' req.body.userID is: '+req.body.userID );
let allOrders = new Array();
let businessNetworkConnection;
- let factory;
- if (svc.m_connection == null) {svc.createMessageSocket();}
+ if (svc.m_connection === null) {svc.createMessageSocket();}
let ser;
let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna'));
businessNetworkConnection = new BusinessNetworkConnection();
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then((bnd) => {
ser = bnd.getSerializer();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
- .then(() => {
- return businessNetworkConnection.query('selectOrders')
- .then((orders) => {
- let jsn;
- let allOrders = new Array();
- for (let each in orders)
- { (function (_idx, _arr)
- {
- let _jsn = ser.toJSON(_arr[_idx]);
- _jsn.id = _arr[_idx].orderNumber;
- allOrders.push(_jsn);
- })(each, orders)
- }
- res.send({'result': 'success', 'orders': allOrders});
- })
- .catch((error) => {console.log('selectOrders failed ', error);
- res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});
- });
- })
- .catch((error) => {console.log('businessNetwork connect failed ', error);
- res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret)
+ //
+ // v0.15
+ console.log(method+' req.body.userID is: '+req.body.userID );
+ return businessNetworkConnection.connect(req.body.userID)
+ .then(() => {
+ return businessNetworkConnection.query('selectOrders')
+ .then((orders) => {
+ allOrders = new Array();
+ for (let each in orders)
+ { (function (_idx, _arr)
+ {
+ let _jsn = ser.toJSON(_arr[_idx]);
+ _jsn.id = _arr[_idx].orderNumber;
+ allOrders.push(_jsn);
+ })(each, orders);
+ }
+ res.send({'result': 'success', 'orders': allOrders});
+ })
+ .catch((error) => {console.log('selectOrders failed ', error);
+ res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});
});
})
- .catch((error) => {console.log('create bnd from archive failed ', error);
+ .catch((error) => {console.log('businessNetwork connect failed ', error);
+ res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('create bnd from archive failed ', error);
res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message});
});
-}
+};
/**
@@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) {
* @param {express.req} req - the inbound request object from the client
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * return {Array} an array of assets
* @function
*/
exports.getItemTable = function (req, res, next)
{
- if (itemTable == null)
+ if (itemTable === null)
{
- let options = { flag : 'w' };
let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt');
itemTable = JSON.parse(fs.readFileSync(newFile));
}
res.send(itemTable);
-}
+};
+
/**
* orderAction - act on an order for a buyer
* @param {express.req} req - the inbound request object from the client
* req.body.action - string with buyer requested action
- * buyer available actions are:
+ * buyer available actions are:
* Pay - approve payment for an order
* Dispute - dispute an existing order. requires a reason
* Purchase - submit created order to seller for execution
@@ -111,145 +115,141 @@ exports.getItemTable = function (req, res, next)
* req.body.reason - reason for dispute, required for dispute processing to proceed
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.orderAction = function (req, res, next) {
- if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) )
- {let reason = req.body.reason;}
+ let method = 'orderAction';
+ console.log(method+' req.body.participant is: '+req.body.participant );
+ if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) )
+ {/*let reason = req.body.reason;*/}
else {
- if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) ))
- res.send({'result': 'failed', 'error': 'no reason provided for dispute'});
+ if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) ))
+ {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});}
}
- if (svc.m_connection == null) {svc.createMessageSocket();}
+ if (svc.m_connection === null) {svc.createMessageSocket();}
let businessNetworkConnection;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let updateOrder;
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.get(req.body.orderNo)
- .then((order) => {
- let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- order.status = req.body.action;
- switch (req.body.action)
- {
- case 'Pay':
- console.log('Pay entered');
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.participant)
+ .then(() => {
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.get(req.body.orderNo)
+ .then((order) => {
+ let factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ order.status = req.body.action;
+ switch (req.body.action)
+ {
+ case 'Pay':
- break;
- case 'Dispute':
- console.log('Dispute entered');
- updateOrder = factory.newTransaction(NS, 'Dispute');
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.dispute = req.body.reason;
- break;
- case 'Purchase':
- console.log('Purchase entered');
- updateOrder = factory.newTransaction(NS, 'Buy');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Order From Supplier':
- console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier);
- updateOrder = factory.newTransaction(NS, 'OrderFromSupplier');
- updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- case 'Request Payment':
- console.log('Request Payment entered');
- updateOrder = factory.newTransaction(NS, 'RequestPayment');
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- break;
- case 'Refund':
- console.log('Refund Payment entered');
- updateOrder = factory.newTransaction(NS, 'Refund');
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.refund = req.body.reason;
- break;
- case 'Resolve':
- console.log('Resolve entered');
- updateOrder = factory.newTransaction(NS, 'Resolve');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier);
- updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- updateOrder.resolve = req.body.reason;
- break;
- case 'Request Shipping':
- console.log('Request Shipping entered');
+ break;
+ case 'Dispute':
+ console.log('Dispute entered');
+ updateOrder = factory.newTransaction(NS, 'Dispute');
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.dispute = req.body.reason;
+ break;
+ case 'Purchase':
+ console.log('Purchase entered');
+ updateOrder = factory.newTransaction(NS, 'Buy');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ case 'Order From Supplier':
+ console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier);
+ updateOrder = factory.newTransaction(NS, 'OrderFromSupplier');
+ updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ case 'Request Payment':
+ console.log('Request Payment entered');
+ updateOrder = factory.newTransaction(NS, 'RequestPayment');
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ break;
+ case 'Refund':
+ console.log('Refund Payment entered');
+ updateOrder = factory.newTransaction(NS, 'Refund');
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.refund = req.body.reason;
+ break;
+ case 'Resolve':
+ console.log('Resolve entered');
+ updateOrder = factory.newTransaction(NS, 'Resolve');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier);
+ updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ updateOrder.resolve = req.body.reason;
+ break;
+ case 'Request Shipping':
- break;
- case 'Update Delivery Status':
- console.log('Update Delivery Status');
+ break;
+ case 'Update Delivery Status':
- break;
- case 'Delivered':
- console.log('Delivered entered');
+ break;
+ case 'Delivered':
- break;
- case 'BackOrder':
- console.log('BackOrder entered');
-
- break;
- case 'Authorize Payment':
- console.log('Authorize Payment entered');
- updateOrder = factory.newTransaction(NS, 'AuthorizePayment');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- break;
- case 'Cancel':
- console.log('Cancel entered');
- updateOrder = factory.newTransaction(NS, 'OrderCancel');
- updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
- updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
- break;
- default :
- console.log('default entered for action: '+req.body.action);
- res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
- }
- updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
- return businessNetworkConnection.submitTransaction(updateOrder)
- .then(() => {
- console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action);
- res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action});
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(" retrying assetRegistry.update for: "+req.body.orderNo);
- svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
- }
- else
- {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);}
- });
+ break;
+ case 'BackOrder':
+ break;
+ case 'Authorize Payment':
+ console.log('Authorize Payment entered');
+ updateOrder = factory.newTransaction(NS, 'AuthorizePayment');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ break;
+ case 'Cancel':
+ console.log('Cancel entered');
+ updateOrder = factory.newTransaction(NS, 'OrderCancel');
+ updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier);
+ updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier);
+ break;
+ default :
+ console.log('default entered for action: '+req.body.action);
+ res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action});
+ }
+ updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier);
+ return businessNetworkConnection.submitTransaction(updateOrder)
+ .then(() => {
+ console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action);
+ res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action});
})
.catch((error) => {
- console.log('Registry Get Order failed: '+error.message);
- res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(' retrying assetRegistry.update for: '+req.body.orderNo);
+ svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection);
+ }
+ else
+ {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);}
});
+
})
- .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
+ .catch((error) => {
+ console.log('Registry Get Order failed: '+error.message);
+ res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message});
+ });
+ })
+ .catch((error) => {console.log('Get Asset Registry failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
- })
- .catch((error) => {console.log('Business Network Connect failed: '+error.message);
+ })
+ .catch((error) => {console.log('Business Network Connect failed: '+error.message);
res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message});
});
-}
+};
+
/**
* adds an order to the blockchain
* @param {express.req} req - the inbound request object from the client
@@ -258,85 +258,87 @@ exports.orderAction = function (req, res, next) {
* req.body.items - array with items for order
* @param {express.res} res - the outbound response object for communicating back to client
* @param {express.next} next - an express service to enable post processing prior to responding to the client
- * returns an array of assets
+ * @returns {Array} an array of assets
* @function
*/
exports.addOrder = function (req, res, next) {
+ let method = 'addOrder';
+ console.log(method+' req.body.buyer is: '+req.body.buyer );
let businessNetworkConnection;
let factory;
- let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt');
- let _table = JSON.parse(fs.readFileSync(newFile));
- let _userID = ''; let _secret = '';
- let bFound = false;
let ts = Date.now();
- let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
- if (svc.m_connection == null) {svc.createMessageSocket();}
-
- for (let each in _table.members)
- { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}}
- if (!bFound) {res.send({'result':req.body.id + 'not found'});}
- businessNetworkConnection = new BusinessNetworkConnection();
- return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret)
- .then(() => {
- factory = businessNetworkConnection.getBusinessNetwork().getFactory();
- let order = factory.newResource(NS, 'Order', orderNo);
- order = svc.createOrderTemplate(order);
- order.amount = 0;
- order.orderNumber = orderNo;
- order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
- order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
- order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- for (let each in req.body.items)
- {(function(_idx, _arr)
- { _arr[_idx].description = _arr[_idx].itemDescription;
- order.items.push(JSON.stringify(_arr[_idx]));
- order.amount += parseInt(_arr[_idx].extendedPrice);
- })(each, req.body.items)
- }
- // create the buy transaction
- const createNew = factory.newTransaction(NS, 'CreateOrder');
-
- createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
- createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
- createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
- createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
- createNew.amount = order.amount;
- // add the order to the asset registry.
- return businessNetworkConnection.getAssetRegistry(NS+'.Order')
- .then((assetRegistry) => {
- return assetRegistry.add(order)
- .then(() => {
- return businessNetworkConnection.submitTransaction(createNew)
- .then(() => {console.log(' order '+orderNo+" successfully added");
- res.send({'result': ' order '+orderNo+' successfully added'});
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- else
- {console.log(orderNo+" submitTransaction failed with text: ",error.message);}
- });
- })
- .catch((error) => {
- if (error.message.search('MVCC_READ_CONFLICT') != -1)
- {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo);
- svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
- }
- else
- {console.log(orderNo+" assetRegistry.add failed: ",error.message);}
- });
- })
- .catch((error) => {
- console.log(orderNo+" getAssetRegistry failed: ",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
- });
- })
- .catch((error) => {
- console.log(orderNo+" business network connection failed: text",error.message);
- res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
- });
+ let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts;
+ if (svc.m_connection === null) {svc.createMessageSocket();}
+ businessNetworkConnection = new BusinessNetworkConnection();
+ //
+ // v0.14
+ // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret)
+ //
+ // v0.15
+ return businessNetworkConnection.connect(req.body.buyer)
+ .then(() => {
+ factory = businessNetworkConnection.getBusinessNetwork().getFactory();
+ let order = factory.newResource(NS, 'Order', orderNo);
+ order = svc.createOrderTemplate(order);
+ order.amount = 0;
+ order.orderNumber = orderNo;
+ order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
+ order.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
+ order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy');
+ order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy');
+ order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ for (let each in req.body.items)
+ {(function(_idx, _arr)
+ { _arr[_idx].description = _arr[_idx].itemDescription;
+ order.items.push(JSON.stringify(_arr[_idx]));
+ order.amount += parseInt(_arr[_idx].extendedPrice);
+ })(each, req.body.items);
}
+ // create the buy transaction
+ const createNew = factory.newTransaction(NS, 'CreateOrder');
+
+ createNew.order = factory.newRelationship(NS, 'Order', order.$identifier);
+ createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer);
+ createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller);
+ createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID);
+ createNew.amount = order.amount;
+ // add the order to the asset registry.
+ return businessNetworkConnection.getAssetRegistry(NS+'.Order')
+ .then((assetRegistry) => {
+ return assetRegistry.add(order)
+ .then(() => {
+ return businessNetworkConnection.submitTransaction(createNew)
+ .then(() => {console.log(' order '+orderNo+' successfully added');
+ res.send({'result': ' order '+orderNo+' successfully added'});
+ })
+ .catch((error) => {
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo);
+ svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
+ }
+ else
+ {console.log(orderNo+' submitTransaction failed with text: ',error.message);}
+ });
+ })
+ .catch((error) => {
+ if (error.message.search('MVCC_READ_CONFLICT') !== -1)
+ {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo);
+ svc.loadTransaction(createNew, orderNo, businessNetworkConnection);
+ }
+ else
+ {
+ console.log(orderNo+' assetRegistry.add failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ }
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' getAssetRegistry failed: ',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message});
+ });
+ })
+ .catch((error) => {
+ console.log(orderNo+' business network connection failed: text',error.message);
+ res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message});
+ });
+};
diff --git a/Chapter07/Documentation/answers/js/z2b-seller_complete.js b/Chapter07/Documentation/answers/js/z2b-seller_complete.js
index 7099a9b..ecc7209 100644
--- a/Chapter07/Documentation/answers/js/z2b-seller_complete.js
+++ b/Chapter07/Documentation/answers/js/z2b-seller_complete.js
@@ -13,167 +13,171 @@
*/
// z2c-seller.js
-var sellerOrderDiv = "sellerOrderDiv";
+
+'use strict';
+let sellerOrderDiv = 'sellerOrderDiv';
/**
- * load the administration User Experience
+ * load the administration Seller Experience
*/
function loadSellerUX ()
{
- toLoad = "seller.html";
- getPort();
- if (buyers.length === 0)
- { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res)
- {setupSeller(page[0], port[0]);});
-}
- else{
- $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port)
+ let toLoad = 'seller.html';
+ getPort();
+ if (buyers.length === 0)
+ { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res)
{setupSeller(page[0], port[0]);});
- }
+ }
+ else{
+ $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port)
+ {setupSeller(page[0], port[0]);});
+ }
}
+/**
+ * load the administration User Experience
+ * @param {String} page - page to load
+ * @param {Integer} port - web socket port to use
+ */
function setupSeller(page, port)
{
- $("#body").empty();
- $("#body").append(page);
- updatePage("seller");
- msgPort = port.port;
- wsDisplay('seller_messages', msgPort);
- var _clear = $("#seller_clear");
- var _list = $("#sellerOrderStatus");
- var _orderDiv = $("#"+sellerOrderDiv);
- _clear.on('click', function(){_orderDiv.empty();});
- //
- // this section changes from the previous chapter, buyer changing to seller
- //
- _list.on('click', function(){listSellerOrders()});
- $("#seller").empty();
- $("#seller").append(s_string);
- $("#sellerCompany").empty();
- $("#sellerCompany").append(sellers[0].companyName);
- $("#seller").on('change', function() {
- $("#sellerCompany").empty(); _orderDiv.empty(); $("#seller_messages").empty();
- $("#sellerCompany").append(findMember($("#seller").find(":selected").val(),sellers).companyName);
- });
+ $('#body').empty();
+ $('#body').append(page);
+ updatePage('seller');
+ msgPort = port.port;
+ wsDisplay('seller_messages', msgPort);
+ let _clear = $('#seller_clear');
+ let _list = $('#sellerOrderStatus');
+ let _orderDiv = $('#'+sellerOrderDiv);
+ _clear.on('click', function(){_orderDiv.empty();});
+ //
+ // this section changes from the previous chapter, buyer changing to seller
+ //
+ _list.on('click', function(){listSellerOrders();});
+ $('#seller').empty();
+ $('#seller').append(s_string);
+ $('#sellerCompany').empty();
+ $('#sellerCompany').append(sellers[0].companyName);
+ $('#seller').on('change', function() {
+ $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty();
+ $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName);
+ });
}
/**
* lists all orders for the selected seller
*/
function listSellerOrders()
{
- var options = {};
- //
- // seller instead of buyer
- //
- options.id = $("#seller").find(":selected").val();
- $.when($.post('/composer/admin/getSecret', options)).done(function(_mem)
- {
- options.userID = _mem.userID; options.secret = _mem.secret;
+ let options = {};
+ //
+ // seller instead of buyer
+ //
+ options.id= $('#seller').find(':selected').val();
+ options.userID = options.id;
$.when($.post('/composer/client/getMyOrders', options)).done(function(_results)
- {
- if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));}
- else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)}
- });
- });
+ {
+ if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));}
+ else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);}
+ });
}
/**
* used by the listOrders() function
* formats the orders for a buyer. Orders to be formatted are provided in the _orders array
* output replaces the current contents of the html element identified by _target
- * @param _target - string with div id prefaced by #
- * @param _orders - array with order objects
+ * @param {String} _target - string with div id prefaced by #
+ * @param {Array} _orders - array with order objects
*/
function formatSellerOrders(_target, _orders)
{
- _target.empty();
- let _str = ""; let _date = "";
- for (let each in _orders)
- {(function(_idx, _arr)
- { _action = '