diff --git a/asset-transfer-basic/rest-api-typescript/src/__mocks__/fabric-network.ts b/asset-transfer-basic/rest-api-typescript/src/__mocks__/fabric-network.ts index d13ff057..626f34e6 100644 --- a/asset-transfer-basic/rest-api-typescript/src/__mocks__/fabric-network.ts +++ b/asset-transfer-basic/rest-api-typescript/src/__mocks__/fabric-network.ts @@ -3,10 +3,14 @@ */ import { mock } from 'jest-mock-extended'; -import { Contract, Network, Transaction, WalletStore } from 'fabric-network'; +import { Contract, Network, Transaction } from 'fabric-network'; import { mocked } from 'ts-jest/utils'; import * as fabricProtos from 'fabric-protos'; +const actualFabricNetwork = jest.requireActual('fabric-network'); +const Wallet = actualFabricNetwork.Wallet; +const Wallets = actualFabricNetwork.Wallets; + const mockAsset1 = { ID: 'asset1', Color: 'blue', @@ -50,15 +54,8 @@ const { DefaultEventHandlerStrategies, DefaultQueryHandlerStrategies, Gateway, - Wallet, - Wallets, }: FabricNetworkModule = jest.createMockFromModule('fabric-network'); -const mockWalletStore = mock(); -mocked(Wallets.newInMemoryWallet).mockResolvedValue( - new Wallet(mockWalletStore) -); - const mockAssetExistsTransaction = mock(); mockAssetExistsTransaction.evaluate .calledWith('asset1') @@ -171,24 +168,11 @@ mockNetwork.getContract.calledWith('qscc').mockReturnValue(mockSystemContract); mocked(Gateway.prototype.getNetwork).mockResolvedValue(mockNetwork); -// TODO remove this and use simpler mocks in fabric spec tests -const getMockedNetwork = (getContract = jest.fn()) => { - return mocked(Gateway.prototype.getNetwork).mockResolvedValue({ - getGateway: jest.fn(), - getContract, - getChannel: jest.fn(), - addCommitListener: jest.fn(), - removeCommitListener: jest.fn(), - addBlockListener: jest.fn(), - removeBlockListener: jest.fn(), - }); -}; - export { DefaultEventHandlerStrategies, DefaultQueryHandlerStrategies, Contract, Gateway, + Wallet, Wallets, - getMockedNetwork, }; diff --git a/asset-transfer-basic/rest-api-typescript/src/assets.router.ts b/asset-transfer-basic/rest-api-typescript/src/assets.router.ts index eb3adb58..5d75c65a 100644 --- a/asset-transfer-basic/rest-api-typescript/src/assets.router.ts +++ b/asset-transfer-basic/rest-api-typescript/src/assets.router.ts @@ -16,11 +16,7 @@ import { Contract } from 'fabric-network'; import { getReasonPhrase, StatusCodes } from 'http-status-codes'; import { Redis } from 'ioredis'; import { AssetExistsError, AssetNotFoundError } from './errors'; -import { - evatuateTransaction, - submitTransaction, - getContractForOrg, -} from './fabric'; +import { evatuateTransaction, submitTransaction } from './fabric'; import { logger } from './logger'; const { @@ -38,7 +34,9 @@ assetsRouter.get('/', async (req: Request, res: Response) => { logger.debug('Get all assets request received'); try { - const contract: Contract = getContractForOrg(req).contract; + const mspId = req.user as string; + const contract = req.app.get(mspId).assetContract as Contract; + const data = await evatuateTransaction(contract, 'GetAllAssets'); let assets = []; if (data.length > 0) { @@ -77,8 +75,9 @@ assetsRouter.post( }); } - const contract: Contract = getContractForOrg(req).contract; - const redis: Redis = req.app.get('redis'); + const mspId = req.user as string; + const contract = req.app.get(mspId).assetContract as Contract; + const redis = req.app.get('redis') as Redis; const assetId = req.body.id; try { @@ -128,7 +127,8 @@ assetsRouter.options('/:assetId', async (req: Request, res: Response) => { logger.debug('Asset options request received for asset ID %s', assetId); try { - const contract: Contract = getContractForOrg(req).contract; + const mspId = req.user as string; + const contract = req.app.get(mspId).assetContract as Contract; const data = await evatuateTransaction(contract, 'AssetExists', assetId); const exists = data.toString() === 'true'; @@ -167,7 +167,8 @@ assetsRouter.get('/:assetId', async (req: Request, res: Response) => { logger.debug('Read asset request received for asset ID %s', assetId); try { - const contract: Contract = getContractForOrg(req).contract; + const mspId = req.user as string; + const contract = req.app.get(mspId).assetContract as Contract; const data = await evatuateTransaction(contract, 'ReadAsset', assetId); const asset = JSON.parse(data.toString()); @@ -225,8 +226,9 @@ assetsRouter.put( }); } - const contract: Contract = getContractForOrg(req).contract; - const redis: Redis = req.app.get('redis'); + const mspId = req.user as string; + const contract = req.app.get(mspId).assetContract as Contract; + const redis = req.app.get('redis') as Redis; const assetId = req.params.assetId; try { @@ -294,8 +296,9 @@ assetsRouter.patch( }); } - const contract: Contract = getContractForOrg(req).contract; - const redis: Redis = req.app.get('redis'); + const mspId = req.user as string; + const contract = req.app.get(mspId).assetContract as Contract; + const redis = req.app.get('redis') as Redis; const assetId = req.params.assetId; const newOwner = req.body[0].value; @@ -339,8 +342,9 @@ assetsRouter.patch( assetsRouter.delete('/:assetId', async (req: Request, res: Response) => { logger.debug(req.body, 'Delete asset request received'); - const contract: Contract = getContractForOrg(req).contract; - const redis: Redis = req.app.get('redis'); + const mspId = req.user as string; + const contract = req.app.get(mspId).assetContract as Contract; + const redis = req.app.get('redis') as Redis; const assetId = req.params.assetId; try { diff --git a/asset-transfer-basic/rest-api-typescript/src/auth.ts b/asset-transfer-basic/rest-api-typescript/src/auth.ts index fd40ed43..03ea8b14 100644 --- a/asset-transfer-basic/rest-api-typescript/src/auth.ts +++ b/asset-transfer-basic/rest-api-typescript/src/auth.ts @@ -17,16 +17,13 @@ export const fabricAPIKeyStrategy: HeaderAPIKeyStrategy = false, function (apikey, done) { logger.debug({ apikey }, 'Checking X-API-Key'); - const user: { org: string } = { - org: '', - }; if (apikey === config.org1ApiKey) { - user.org = config.identityNameOrg1; - logger.debug('Organisation set to Org1'); + const user = config.mspIdOrg1; + logger.debug('User set to %s', user); done(null, user); } else if (apikey === config.org2ApiKey) { - user.org = config.identityNameOrg2; - logger.info('Organisation set to Org2'); + const user = config.mspIdOrg2; + logger.debug('User set to %s', user); done(null, user); } else { logger.debug({ apikey }, 'No valid X-API-Key'); @@ -44,7 +41,6 @@ export const authenticateApiKey = ( 'headerapikey', { session: false }, (err, user, _info) => { - logger.debug({ user }, 'USERUSERUSER'); if (err) return next(err); if (!user) return res.status(UNAUTHORIZED).json({ diff --git a/asset-transfer-basic/rest-api-typescript/src/config.ts b/asset-transfer-basic/rest-api-typescript/src/config.ts index 3a00c813..afc15aac 100644 --- a/asset-transfer-basic/rest-api-typescript/src/config.ts +++ b/asset-transfer-basic/rest-api-typescript/src/config.ts @@ -50,12 +50,6 @@ export const asLocalhost = env .example('true') .asBoolStrict(); -// TODO delete this and use mspIdOrg1 -export const identityNameOrg1 = 'Org1'; - -// TODO delete this and use mspIdOrg2 -export const identityNameOrg2 = 'Org2'; - /* * The Org1 MSP ID */ @@ -128,7 +122,7 @@ export const connectionProfileOrg1 = env .example( '{"name":"test-network-org1","version":"1.0.0","client":{"organization":"Org1" ... }' ) - .asJsonObject(); + .asJsonObject() as Record; /* * Certificate for the Org1 identity @@ -157,7 +151,7 @@ export const connectionProfileOrg2 = env .example( '{"name":"test-network-org2","version":"1.0.0","client":{"organization":"Org2" ... }' ) - .asJsonObject(); + .asJsonObject() as Record; /* * Certificate for the Org2 identity diff --git a/asset-transfer-basic/rest-api-typescript/src/fabric.spec.ts b/asset-transfer-basic/rest-api-typescript/src/fabric.spec.ts index 3cc7b1d8..7c37bf00 100644 --- a/asset-transfer-basic/rest-api-typescript/src/fabric.spec.ts +++ b/asset-transfer-basic/rest-api-typescript/src/fabric.spec.ts @@ -1,13 +1,32 @@ -import { retryTransaction, getGateway } from './fabric'; -import { getMockedNetwork } from './__mocks__/fabric-network'; +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + createGateway, + createWallet, + getContracts, + getNetwork, + retryTransaction, +} from './fabric'; import * as config from './config'; import IORedis from './__mocks__/IORedis'; import { Redis } from 'ioredis'; -import { Contract } from 'fabric-network'; +import { + Contract, + Gateway, + GatewayOptions, + Network, + Transaction, + Wallet, +} from 'fabric-network'; + +import { mock } from 'jest-mock-extended'; jest.mock('./config'); jest.mock('ioredis'); + const redisOptions = { port: config.redisPort, host: config.redisHost, @@ -17,20 +36,72 @@ const redisOptions = { const redis = new IORedis(redisOptions) as unknown as Redis; -describe('Testing retryTransaction', () => { - const transactionId = - '0ae62c01e4c4b112c3f3954a2f11243da76778e46df9ad2783bcbafc79652b95'; - const state = `{"name":"CreateAsset","nonce":"damqinq8nrI4n4qY8lFVsZw7RwG2ufrv","transactionId":${transactionId}`; - const args = '["test111","red",400,"Jean",101]'; - const timestamp = 1628078044362; - const savedTransaction = { - timestamp: timestamp.toString(), - state: state, - retries: '', - args: args, - }; +describe('Fabric', () => { + describe('createWallet', () => { + it('creates a wallet containing identities for both orgs', async () => { + const wallet = await createWallet(); - describe('Check retry increment ', () => { + expect(await wallet.list()).toStrictEqual(['Org1MSP', 'Org2MSP']); + }); + }); + + describe('createGateway', () => { + it('creates a Gateway and connects using the provided arguments', async () => { + const connectionProfile = config.connectionProfileOrg1; + const identity = config.mspIdOrg1; + const mockWallet = mock(); + + const gateway = await createGateway( + connectionProfile, + identity, + mockWallet + ); + + expect(gateway.connect).toBeCalledWith( + connectionProfile, + expect.objectContaining({ + wallet: mockWallet, + identity, + discovery: expect.any(Object), + eventHandlerOptions: expect.any(Object), + queryHandlerOptions: expect.any(Object), + }) + ); + }); + }); + + describe('getNetwork', () => { + it('gets a Network instance for the required channel from the Gateway', async () => { + const mockGateway = mock(); + + await getNetwork(mockGateway); + + expect(mockGateway.getNetwork).toHaveBeenCalledWith(config.channelName); + }); + }); + + describe('getContracts', () => { + it('gets the asset and qscc contracts from the network', async () => { + const mockBasicContract = mock(); + const mockSystemContract = mock(); + const mockNetwork = mock(); + mockNetwork.getContract + .calledWith(config.chaincodeName) + .mockReturnValue(mockBasicContract); + mockNetwork.getContract + .calledWith('qscc') + .mockReturnValue(mockSystemContract); + + const contracts = await getContracts(mockNetwork); + + expect(contracts).toStrictEqual({ + assetContract: mockBasicContract, + qsccContract: mockSystemContract, + }); + }); + }); + + describe('Testing retryTransaction', () => { const transactionId = '0ae62c01e4c4b112c3f3954a2f11243da76778e46df9ad2783bcbafc79652b95'; const state = `{"name":"CreateAsset","nonce":"damqinq8nrI4n4qY8lFVsZw7RwG2ufrv","transactionId":${transactionId}`; @@ -43,52 +114,53 @@ describe('Testing retryTransaction', () => { args: args, }; - it('Transaction failure, check redis increment func call', async () => { - jest.doMock('fabric-network'); - const transaction = { - submit: jest.fn().mockRejectedValue({}), + describe('Check retry increment ', () => { + const transactionId = + '0ae62c01e4c4b112c3f3954a2f11243da76778e46df9ad2783bcbafc79652b95'; + const state = `{"name":"CreateAsset","nonce":"damqinq8nrI4n4qY8lFVsZw7RwG2ufrv","transactionId":${transactionId}`; + const args = '["test111","red",400,"Jean",101]'; + const timestamp = 1628078044362; + const savedTransaction = { + timestamp: timestamp.toString(), + state: state, + retries: '', + args: args, }; - const mockedContact = { - deserializeTransaction: jest.fn().mockReturnValue(transaction), - }; - const rejectableGetContract = jest - .fn() - .mockImplementation(() => mockedContact); - const network = getMockedNetwork(rejectableGetContract)(''); - const contract: Contract = (await network).getContract(''); - savedTransaction.retries = '3'; - await retryTransaction(contract, redis, transactionId, savedTransaction); - expect(redis.hincrby).toHaveBeenCalledTimes(1); + it('Transaction failure, check redis increment func call', async () => { + const mockTransaction = mock(); + mockTransaction.submit.mockRejectedValue('MOCKERROR'); + const mockContract = mock(); + mockContract.deserializeTransaction.mockReturnValue(mockTransaction); + + savedTransaction.retries = '3'; + await retryTransaction( + mockContract, + redis, + transactionId, + savedTransaction + ); + expect(redis.hincrby).toHaveBeenCalledTimes(1); + }); }); - }); - describe('Transaction successful, check redis delete key func call ', () => { - it('call redis increment', async () => { - jest.doMock('fabric-network'); - const transaction = { - submit: jest.fn().mockResolvedValue({}), - }; - const mockedContact = { - deserializeTransaction: jest.fn().mockReturnValue(transaction), - }; - const resolvableGetContract = jest - .fn() - .mockImplementation(() => mockedContact); + describe('Transaction successful, check redis delete key func call ', () => { + it('call redis increment', async () => { + const mockTransaction = mock(); + mockTransaction.submit.mockResolvedValue(Buffer.from('{}')); + const mockContract = mock(); + mockContract.deserializeTransaction.mockReturnValue(mockTransaction); - const network = getMockedNetwork(resolvableGetContract)(''); - const contract: Contract = (await network).getContract(''); - savedTransaction.retries = '3'; - await retryTransaction(contract, redis, transactionId, savedTransaction); - expect(redis.del).toHaveBeenCalledTimes(1); + savedTransaction.retries = '3'; + await retryTransaction( + mockContract, + redis, + transactionId, + savedTransaction + ); + + expect(redis.del).toHaveBeenCalledTimes(1); + }); }); }); }); - -describe('Test getGateway', () => { - it('should throw error for invalid org name', async () => { - expect(async () => await getGateway('')).rejects.toThrow( - 'Invalid org name for gateway' - ); - }); -}); diff --git a/asset-transfer-basic/rest-api-typescript/src/fabric.ts b/asset-transfer-basic/rest-api-typescript/src/fabric.ts index 8249c55d..44014ce4 100644 --- a/asset-transfer-basic/rest-api-typescript/src/fabric.ts +++ b/asset-transfer-basic/rest-api-typescript/src/fabric.ts @@ -13,8 +13,8 @@ import { BlockListener, BlockEvent, TransactionEvent, + Wallet, } from 'fabric-network'; -import { Request } from 'express'; import { Redis } from 'ioredis'; import * as config from './config'; import { logger } from './logger'; @@ -31,63 +31,60 @@ import { } from './errors'; import protos from 'fabric-protos'; -export const getNetwork = async (gateway: Gateway): Promise => { - const network = await gateway.getNetwork(config.channelName); - return network; -}; - -interface FabricConfigType { - identityName: string; - mspId: string; - connectionProfile: { [key: string]: any }; - certificate: string; - privateKey: string; -} - -const ORG1_CONFIG = { - identityName: config.identityNameOrg1, - mspId: config.mspIdOrg1, - connectionProfile: config.connectionProfileOrg1, - certificate: config.certificateOrg1, - privateKey: config.privateKeyOrg1, -}; - -const ORG2_CONFIG = { - identityName: config.identityNameOrg2, - mspId: config.mspIdOrg2, - connectionProfile: config.connectionProfileOrg2, - certificate: config.certificateOrg2, - privateKey: config.privateKeyOrg2, -}; - -const FabricDataMapper: { [key: string]: FabricConfigType } = { - [config.identityNameOrg1]: ORG1_CONFIG, - [config.identityNameOrg2]: ORG2_CONFIG, -}; - -export const getGateway = async (org: string): Promise => { - const fabricConfig = FabricDataMapper[org]; - if (fabricConfig == undefined) { - throw new Error('Invalid org name for gateway'); - } - logger.debug('Configuring fabric gateway for %s', org); +/* + * Creates an in memory wallet to hold credentials for an Org1 and Org2 user + * + * In this sample there is a single user for each MSP ID to demonstrate how + * a client app might submit transactions for different users + * + * Alternatively a REST server could use its own identity for all transactions, + * or it could use credentials supplied in the REST requests + */ +export const createWallet = async (): Promise => { const wallet = await Wallets.newInMemoryWallet(); - const x509Identity = { + const org1Identity = { credentials: { - certificate: fabricConfig.certificate, - privateKey: fabricConfig.privateKey, + certificate: config.certificateOrg1, + privateKey: config.privateKeyOrg1, }, - mspId: fabricConfig.mspId, + mspId: config.mspIdOrg1, type: 'X.509', }; - await wallet.put(fabricConfig.identityName, x509Identity); + await wallet.put(config.mspIdOrg1, org1Identity); + + const org2Identity = { + credentials: { + certificate: config.certificateOrg2, + privateKey: config.privateKeyOrg2, + }, + mspId: config.mspIdOrg2, + type: 'X.509', + }; + + await wallet.put(config.mspIdOrg2, org2Identity); + + return wallet; +}; + +/* + * Create a Gateway connection + * + * Gateway instances can and should be reused rather than connecting to submit every transaction + */ +export const createGateway = async ( + connectionProfile: Record, + identity: string, + wallet: Wallet +): Promise => { + logger.debug({ connectionProfile, identity }, 'Configuring gateway'); + const gateway = new Gateway(); - const connectOptions: GatewayOptions = { + const options: GatewayOptions = { wallet, - identity: fabricConfig.identityName, + identity, discovery: { enabled: true, asLocalhost: config.asLocalhost }, eventHandlerOptions: { commitTimeout: config.commitTimeout, @@ -100,16 +97,22 @@ export const getGateway = async (org: string): Promise => { }, }; - await gateway.connect(fabricConfig.connectionProfile, connectOptions); + await gateway.connect(connectionProfile, options); + return gateway; }; +export const getNetwork = async (gateway: Gateway): Promise => { + const network = await gateway.getNetwork(config.channelName); + return network; +}; + export const getContracts = async ( network: Network -): Promise<{ contract: Contract; qscc: Contract }> => { - const contract = network.getContract(config.chaincodeName); - const qscc = network.getContract('qscc'); - return { contract, qscc }; +): Promise<{ assetContract: Contract; qsccContract: Contract }> => { + const assetContract = network.getContract(config.chaincodeName); + const qsccContract = network.getContract('qscc'); + return { assetContract, qsccContract }; }; export const startRetryLoop = (contract: Contract, redis: Redis): void => { @@ -334,25 +337,15 @@ export const blockEventHandler = (redis: Redis): BlockListener => { return blockListner; }; -export const getChainInfo = async (qscc: Contract): Promise => { - try { - const data = await qscc.evaluateTransaction( - 'GetChainInfo', - config.channelName - ); - const info = protos.common.BlockchainInfo.decode(data); - const blockHeight = info.height.toString(); - logger.info('Current block height: %s', blockHeight); - return true; - } catch (e) { - logger.error(e, 'Unable to get blockchain info'); - return false; - } -}; - -export const getContractForOrg = ( - req: Request -): { contract: Contract; qscc: Contract } => { - const user: { org: string } = req.user as { org: string }; - return req.app.get('fabric')[user.org as string].contracts; +export const getBlockHeight = async ( + qscc: Contract +): Promise => { + const data = await qscc.evaluateTransaction( + 'GetChainInfo', + config.channelName + ); + const info = protos.common.BlockchainInfo.decode(data); + const blockHeight = info.height; + logger.debug('Current block height: %d', blockHeight); + return blockHeight; }; diff --git a/asset-transfer-basic/rest-api-typescript/src/index.ts b/asset-transfer-basic/rest-api-typescript/src/index.ts index 94814eb6..722079c5 100644 --- a/asset-transfer-basic/rest-api-typescript/src/index.ts +++ b/asset-transfer-basic/rest-api-typescript/src/index.ts @@ -12,10 +12,11 @@ import { createServer } from './server'; async function main() { const app = await createServer(); - const contract: Contract = - app.get('fabric')[config.identityNameOrg1].contracts.contract; - const redis: Redis = app.get('redis'); - const network: Network = app.get('fabric')[config.identityNameOrg1].network; + // TODO block listener and retry logic currently only handles a single org!!! + // TODO should these be initialised here? + const contract = app.get(config.mspIdOrg1).assetContract as Contract; + const redis = app.get('redis') as Redis; + const network = app.get('networkOrg1') as Network; await network.addBlockListener(blockEventHandler(redis)); startRetryLoop(contract, redis); diff --git a/asset-transfer-basic/rest-api-typescript/src/server.ts b/asset-transfer-basic/rest-api-typescript/src/server.ts index 5caf5799..4aeed8dd 100644 --- a/asset-transfer-basic/rest-api-typescript/src/server.ts +++ b/asset-transfer-basic/rest-api-typescript/src/server.ts @@ -12,10 +12,10 @@ import { assetsRouter } from './assets.router'; import { transactionsRouter } from './transactions.router'; import { getContracts, - getGateway, getNetwork, - getChainInfo, - getContractForOrg, + getBlockHeight, + createGateway, + createWallet, } from './fabric'; import { redis } from './redis'; import { Contract } from 'fabric-network'; @@ -74,29 +74,29 @@ export const createServer = async (): Promise => { if (process.env.NODE_ENV === 'production') { app.use(helmet()); } - // - const gatewayOrg1 = await getGateway(config.identityNameOrg1); - const gatewayOrg2 = await getGateway(config.identityNameOrg2); + + const wallet = await createWallet(); + + const gatewayOrg1 = await createGateway( + config.connectionProfileOrg1, + config.mspIdOrg1, + wallet + ); const networkOrg1 = await getNetwork(gatewayOrg1); - const networkOrg2 = await getNetwork(gatewayOrg2); - const contractsOrg1 = await getContracts(networkOrg1); + app.set(config.mspIdOrg1, contractsOrg1); + + // TODO used for block listener, which needs fixing! + app.set('networkOrg1', networkOrg1); + + const gatewayOrg2 = await createGateway( + config.connectionProfileOrg2, + config.mspIdOrg2, + wallet + ); + const networkOrg2 = await getNetwork(gatewayOrg2); const contractsOrg2 = await getContracts(networkOrg2); - - const fabric = { - [config.identityNameOrg1]: { - gateway: gatewayOrg1, - contracts: contractsOrg1, - network: networkOrg1, - }, - [config.identityNameOrg2]: { - gateway: gatewayOrg2, - contracts: contractsOrg2, - network: networkOrg2, - }, - }; - - app.set('fabric', fabric); + app.set(config.mspIdOrg2, contractsOrg2); app.set('redis', redis); @@ -107,32 +107,27 @@ export const createServer = async (): Promise => { timestamp: new Date().toISOString(), }) ); - app.get('/live', async (_req, res) => { - _req.user = { org: config.identityNameOrg1 }; - const qsccOrg1: Contract = getContractForOrg(_req).qscc; - const Org1Liveness = await getChainInfo(qsccOrg1); - logger.debug('Org1 liveness %s', Org1Liveness); - _req.user = { org: config.identityNameOrg2 }; - const qsccOrg2: Contract = getContractForOrg(_req).qscc; - const Org2Liveness = await getChainInfo(qsccOrg2); - logger.debug('Org2 liveness %s', Org2Liveness); + app.get('/live', async (req, res) => { + logger.debug(req.body, 'Liveness request received'); + + const qsccOrg1 = req.app.get(config.mspIdOrg1).qsccContract as Contract; + const qsccOrg2 = req.app.get(config.mspIdOrg2).qsccContract as Contract; + + try { + await Promise.all([getBlockHeight(qsccOrg1), getBlockHeight(qsccOrg2)]); + } catch (err) { + logger.error(err, 'Error processing liveness request'); - if (Org1Liveness && Org2Liveness) { - res.status(OK).json({ - status: getReasonPhrase(OK), - timestamp: new Date().toISOString(), - }); - } else { res.status(SERVICE_UNAVAILABLE).json({ status: getReasonPhrase(SERVICE_UNAVAILABLE), timestamp: new Date().toISOString(), }); } - }); - // TODO delete me - app.get('/error', (_req, _res) => { - throw new Error('Example error'); + res.status(OK).json({ + status: getReasonPhrase(OK), + timestamp: new Date().toISOString(), + }); }); app.use('/api/assets', authenticateApiKey, assetsRouter); diff --git a/asset-transfer-basic/rest-api-typescript/src/transactions.router.ts b/asset-transfer-basic/rest-api-typescript/src/transactions.router.ts index c3dd49bf..27f6438b 100644 --- a/asset-transfer-basic/rest-api-typescript/src/transactions.router.ts +++ b/asset-transfer-basic/rest-api-typescript/src/transactions.router.ts @@ -7,7 +7,7 @@ import { Contract } from 'fabric-network'; import { protos } from 'fabric-protos'; import { getReasonPhrase, StatusCodes } from 'http-status-codes'; import { Redis } from 'ioredis'; -import { evatuateTransaction, getContractForOrg } from './fabric'; +import { evatuateTransaction } from './fabric'; import { logger } from './logger'; import * as config from './config'; import { TransactionNotFoundError } from './errors'; @@ -28,8 +28,9 @@ transactionsRouter.get( let progress: Progress = 'DONE'; let validationCode = ''; - const qscc: Contract = getContractForOrg(req).qscc; - const redis: Redis = req.app.get('redis'); + const mspId = req.user as string; + const qscc = req.app.get(mspId).qsccContract as Contract; + const redis = req.app.get('redis') as Redis; try { const savedTransaction = await (redis as Redis).hgetall(