-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathhlcClient.js
381 lines (330 loc) · 16.6 KB
/
hlcClient.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
/*
* 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';
let fs = require('fs');
let path = require('path');
let itemTable = null;
const svc = require('./Z2B_Services');
const financeCoID = 'easymoney@easymoneyinc.com';
// Bring Fabric SDK network class
const { FileSystemWallet, Gateway } = require('fabric-network');
// A wallet stores a collection of identities for use
let walletDir = path.join(path.dirname(require.main.filename),'controller/restapi/features/fabric/_idwallet');
const wallet = new FileSystemWallet(walletDir);
const configDirectory = path.join(process.cwd(), 'controller/restapi/features/fabric');
const configPath = path.join(configDirectory, 'config.json');
const configJSON = fs.readFileSync(configPath, 'utf8');
const config = JSON.parse(configJSON);
let userName = config.appAdmin;
let channelName = config.channel_name;
let smartContractName = config.smart_contract_name;
let gatewayDiscoveryEnabled = 'enabled' in config.gatewayDiscovery?config.gatewayDiscovery.enabled:true;
let gatewayDiscoveryAsLocalhost = 'asLocalHost' in config.gatewayDiscovery?config.gatewayDiscovery.asLocalhost:true;
const ccpFile = config.connection_file;
const ccpPath = path.join(configDirectory, ccpFile);
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
/**
* get orders for buyer with ID = _id
* @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.
* @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} an array of assets
* @function
*/
exports.getMyOrders = async function (req, res, next) {
// connect to the network
let method = 'getMyOrders';
console.log(method+' req.body.userID is: '+req.body.userID );
let allOrders = new Array();
// Main try/catch block
try {
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(userName);
if (!userExists) {
console.log('An identity for the user ' + userName + ' does not exist in the wallet');
console.log('Run the enrollAdmin.js before retrying');
res.send({error: 'An identity for the user ' + userName + ' does not exist in the wallet. Register ' + userName + ' first'});
}
// A gateway defines the peers used to access Fabric networks
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: userName, discovery: { enabled: gatewayDiscoveryEnabled, asLocalHost: gatewayDiscoveryAsLocalhost } });
// Get addressability to network
const network = await gateway.getNetwork(channelName);
// Get addressability to contract
const contract = await network.getContract(smartContractName);
// Get member state
const responseMember = await contract.evaluateTransaction('GetState', req.body.userID);
console.log('responseMember: ');
console.log(JSON.parse(responseMember.toString()));
let member = JSON.parse(responseMember.toString());
// Get the orders for the member including their state
for (let orderNo of member.orders) {
const response = await contract.evaluateTransaction('GetState', orderNo);
console.log('response: ');
console.log(JSON.parse(response.toString()));
let _jsn = JSON.parse(response.toString());
let _jsnItems = JSON.parse(_jsn.items);
_jsn.items = _jsnItems;
allOrders.push(_jsn);
}
// Disconnect from the gateway
console.log('Disconnect from Fabric gateway.');
console.log('getMyOrders Complete');
await gateway.disconnect();
res.send({result: 'success', orders: allOrders});
} catch (error) {
console.log(`Error processing transaction. ${error}`);
console.log(error.stack);
res.send({error: error.stack});
}
};
/**
* 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
* return {Array} an array of assets
* @function
*/
exports.getItemTable = function (req, res, next)
{
if (itemTable === null)
{
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:
* Pay - approve payment for an order
* Dispute - dispute an existing order. requires a reason
* Purchase - submit created order to seller for execution
* Cancel - cancel an existing order
* req.body.participant - string with buyer id
* req.body.orderNo - string with orderNo to be acted upon
* 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 {Array} an array of assets
* @function
*/
exports.orderAction = async function (req, res, next) {
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 (svc.m_connection === null) {svc.createMessageSocket();}
// Main try/catch block
try {
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(userName);
if (!userExists) {
console.log('An identity for the user ' + userName + ' does not exist in the wallet');
console.log('Run the enrollAdmin.js before retrying');
res.send({error: 'An identity for the user ' + userName + ' does not exist in the wallet. Register ' + userName + ' first'});
}
// A gateway defines the peers used to access Fabric networks
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: userName, discovery: { enabled: gatewayDiscoveryEnabled, asLocalHost: gatewayDiscoveryAsLocalhost } });
// Get addressability to network
const network = await gateway.getNetwork(channelName);
// Get addressability to contract
const contract = await network.getContract(smartContractName);
// Get state of order
const responseOrder = await contract.evaluateTransaction('GetState', req.body.orderNo);
console.log('responseOrder: ');
console.log(JSON.parse(responseOrder.toString()));
let order = JSON.parse(responseOrder.toString());
// Perform action on the order
switch (req.body.action)
{
case 'Pay': {
console.log('Pay entered');
const payResponse = await contract.submitTransaction('Pay', order.orderNumber, order.sellerId, financeCoID);
console.log('payResponse: ');
console.log(JSON.parse(payResponse.toString()));
break;
}
case 'Dispute': {
console.log('Dispute entered');
const disputeResponse = await contract.submitTransaction('Dispute', order.orderNumber, order.buyerId, order.sellerId, financeCoID, req.body.reason);
console.log('disputeResponse_response: ');
console.log(JSON.parse(disputeResponse.toString()));
}
break;
case 'Purchase': {
console.log('Purchase entered');
const buyResponse = await contract.submitTransaction('Buy', order.orderNumber, order.buyerId, order.sellerId);
console.log('buyResponse: ');
console.log(JSON.parse(buyResponse.toString()));
}
break;
case 'Order From Supplier': {
console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.sellerId+' with provider as: '+req.body.provider);
const orderSupplierResponse = await contract.submitTransaction('OrderFromSupplier', order.orderNumber, order.sellerId, req.body.provider);
console.log('orderSupplierResponse: ');
console.log(JSON.parse(orderSupplierResponse.toString()));
}
break;
case 'Request Payment':{
console.log('Request Payment entered');
const requestPaymentResponse = await contract.submitTransaction('RequestPayment', order.orderNumber, order.sellerId, financeCoID);
console.log('requestPaymentResponse_response: ');
console.log(JSON.parse(requestPaymentResponse.toString()));
}
break;
case 'Refund': {
console.log('Refund Payment entered');
const refundResponse = await contract.submitTransaction('Refund', order.orderNumber, order.sellerId, financeCoID, req.body.reason);
console.log('refundResponse_response: ');
console.log(JSON.parse(refundResponse.toString()));
}
break;
case 'Resolve': {
console.log('Resolve entered');
const resolveResponse = await contract.submitTransaction('Resolve', order.orderNumber, order.buyerId, order.sellerId, order.shipperId, order.providerId, financeCoID, req.body.reason);
console.log('resolveResponse_response: ');
console.log(JSON.parse(resolveResponse.toString()));
}
break;
case 'Request Shipping': {
console.log('Request Shipping entered');
const requestShippingResponse = await contract.submitTransaction('RequestShipping', order.orderNumber, order.providerId, req.body.shipper);
console.log('requestShippingResponse: ');
console.log(JSON.parse(requestShippingResponse.toString()));
}
break;
case 'Update Delivery Status': {
console.log('Update Delivery Status');
const deliveringResponse = await contract.submitTransaction('Delivering', order.orderNumber, order.shipperId, req.body.delivery);
console.log('deliveringResponse: ');
console.log(JSON.parse(deliveringResponse.toString()));
}
break;
case 'Delivered': {
console.log('Delivered entered');
console.log('participant: ' + req.body.participant);
const deliverResponse = await contract.submitTransaction('Deliver', order.orderNumber, req.body.participant);
console.log('deliverResponse_response: ');
console.log(JSON.parse(deliverResponse.toString()));
}
break;
case 'BackOrder': {
console.log('BackOrder entered');
const backOrderResponse = await contract.submitTransaction('BackOrder', order.orderNumber, order.providerId, req.body.reason);
console.log('backOrderResponse_response: ');
console.log(JSON.parse(backOrderResponse.toString()));
}
break;
case 'Authorize Payment':{
console.log('Authorize Payment entered');
const authorizePaymentResponse = await contract.submitTransaction('AuthorizePayment', order.orderNumber, order.buyerId, financeCoID);
console.log('authorizePaymentResponse: ');
console.log(JSON.parse(authorizePaymentResponse.toString()));
}
break;
case 'Cancel': {
console.log('Cancel entered');
const orderCancelResponse = await contract.submitTransaction('OrderCancel', order.orderNumber, order.sellerId, order.providerId);
console.log('orderCancelResponse_response: ');
console.log(JSON.parse(orderCancelResponse.toString()));
}
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});
}
// Disconnect from the gateway
console.log('Disconnect from Fabric gateway.');
console.log('orderAction Complete');
await gateway.disconnect();
res.send({result: ' order '+req.body.orderNo+' successfully updated to '+req.body.action});
} catch (error) {
console.log(`Error processing transaction. ${error}`);
console.log(error.stack);
res.send({error: error.stack});
}
};
/**
* adds an order to the blockchain
* @param {express.req} req - the inbound request object from the client
* req.body.seller - string with seller id
* req.body.buyer - string with buyer id
* 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 {Array} an array of assets
* @function
*/
exports.addOrder = async function (req, res, next) {
let method = 'addOrder';
console.log(method+' req.body.buyer is: '+req.body.buyer );
let orderNo = '00' + Math.floor(Math.random() * 10000);
let order = {};
order = svc.createOrderTemplate(order);
if (svc.m_connection === null) {svc.createMessageSocket();}
// Main try/catch block
try {
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(userName);
if (!userExists) {
console.log('An identity for the user ' + userName + ' does not exist in the wallet');
console.log('Run the enrollAdmin.js before retrying');
res.send({error: 'An identity for the user ' + userName + ' does not exist in the wallet. Register ' + userName + ' first'});
}
// A gateway defines the peers used to access Fabric networks
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: userName, discovery: { enabled: gatewayDiscoveryEnabled, asLocalHost: gatewayDiscoveryAsLocalhost } });
// Get addressability to network
const network = await gateway.getNetwork(channelName);
// Get addressability to contract
const contract = await network.getContract(smartContractName);
let items;
let amount;
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);
}
items = JSON.stringify(order.items);
amount = order.amount.toString();
const createOrderResponse = await contract.submitTransaction('CreateOrder', req.body.buyer, req.body.seller, financeCoID, orderNo, items, amount);
console.log('createOrderResponse: ');
console.log(JSON.parse(createOrderResponse.toString()));
// Disconnect from the gateway
console.log('Disconnect from Fabric gateway.');
console.log('addOrder Complete');
await gateway.disconnect();
res.send({result: ' order '+orderNo+' successfully added'});
} catch (error) {
console.log(`Error processing transaction. ${error}`);
console.log(error.stack);
res.send({error: error.stack});
}
};