Merge pull request #1494 from 0xProject/feature/order-watcher/dockerize
Dockerize OrderWatcher WS Server
This commit is contained in:
commit
5dd55491b8
@ -8,12 +8,18 @@ import { schemas } from './schemas';
|
|||||||
*/
|
*/
|
||||||
export class SchemaValidator {
|
export class SchemaValidator {
|
||||||
private readonly _validator: Validator;
|
private readonly _validator: Validator;
|
||||||
|
private static _assertSchemaDefined(schema: Schema): void {
|
||||||
|
if (schema === undefined) {
|
||||||
|
throw new Error(`Cannot add undefined schema`);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Instantiates a SchemaValidator instance
|
* Instantiates a SchemaValidator instance
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this._validator = new Validator();
|
this._validator = new Validator();
|
||||||
for (const schema of values(schemas)) {
|
for (const schema of values(schemas)) {
|
||||||
|
SchemaValidator._assertSchemaDefined(schema);
|
||||||
this._validator.addSchema(schema, schema.id);
|
this._validator.addSchema(schema, schema.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,6 +30,7 @@ export class SchemaValidator {
|
|||||||
* @param schema The schema to add
|
* @param schema The schema to add
|
||||||
*/
|
*/
|
||||||
public addSchema(schema: Schema): void {
|
public addSchema(schema: Schema): void {
|
||||||
|
SchemaValidator._assertSchemaDefined(schema);
|
||||||
this._validator.addSchema(schema, schema.id);
|
this._validator.addSchema(schema, schema.id);
|
||||||
}
|
}
|
||||||
// In order to validate a complex JS object using jsonschema, we must replace any complex
|
// In order to validate a complex JS object using jsonschema, we must replace any complex
|
||||||
@ -37,6 +44,7 @@ export class SchemaValidator {
|
|||||||
* @returns The results of the validation
|
* @returns The results of the validation
|
||||||
*/
|
*/
|
||||||
public validate(instance: any, schema: Schema): ValidatorResult {
|
public validate(instance: any, schema: Schema): ValidatorResult {
|
||||||
|
SchemaValidator._assertSchemaDefined(schema);
|
||||||
const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance));
|
const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance));
|
||||||
return this._validator.validate(jsonSchemaCompatibleObject, schema);
|
return this._validator.validate(jsonSchemaCompatibleObject, schema);
|
||||||
}
|
}
|
||||||
|
13
packages/order-watcher/Dockerfile
Normal file
13
packages/order-watcher/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
FROM node
|
||||||
|
|
||||||
|
WORKDIR /order-watcher
|
||||||
|
|
||||||
|
COPY package.json .
|
||||||
|
RUN npm i
|
||||||
|
RUN npm install forever -g
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
CMD ["forever", "./lib/src/server.js"]
|
@ -36,6 +36,7 @@
|
|||||||
"@0x/dev-utils": "^1.0.21",
|
"@0x/dev-utils": "^1.0.21",
|
||||||
"@0x/migrations": "^2.2.2",
|
"@0x/migrations": "^2.2.2",
|
||||||
"@0x/tslint-config": "^2.0.0",
|
"@0x/tslint-config": "^2.0.0",
|
||||||
|
"@0x/subproviders": "^2.1.8",
|
||||||
"@types/bintrees": "^1.0.2",
|
"@types/bintrees": "^1.0.2",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
|
44
packages/order-watcher/src/server.ts
Normal file
44
packages/order-watcher/src/server.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { getContractAddressesForNetworkOrThrow } from '@0x/contract-addresses';
|
||||||
|
import { RPCSubprovider, Web3ProviderEngine } from '@0x/subproviders';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { OrderWatcherWebSocketServer } from './order_watcher/order_watcher_web_socket_server';
|
||||||
|
|
||||||
|
const GANACHE_NETWORK_ID = 50;
|
||||||
|
const DEFAULT_RPC_URL = 'http://localhost:8545';
|
||||||
|
|
||||||
|
const provider = new Web3ProviderEngine();
|
||||||
|
const jsonRpcUrl = process.env.JSON_RPC_URL || DEFAULT_RPC_URL;
|
||||||
|
const rpcSubprovider = new RPCSubprovider(jsonRpcUrl);
|
||||||
|
provider.addProvider(rpcSubprovider);
|
||||||
|
provider.start();
|
||||||
|
|
||||||
|
const networkId = process.env.NETWORK_ID !== undefined ? _.parseInt(process.env.NETWORK_ID) : GANACHE_NETWORK_ID;
|
||||||
|
|
||||||
|
const contractAddressesString = process.env.contractAddresses;
|
||||||
|
const contractAddressesIfExists =
|
||||||
|
contractAddressesString === undefined
|
||||||
|
? getContractAddressesForNetworkOrThrow(networkId)
|
||||||
|
: JSON.parse(contractAddressesString);
|
||||||
|
|
||||||
|
const orderWatcherConfig: any = {
|
||||||
|
isVerbose: process.env.IS_VERBOSE === 'true',
|
||||||
|
};
|
||||||
|
const orderExpirationCheckingIntervalMs = process.env.ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
|
||||||
|
if (orderExpirationCheckingIntervalMs !== undefined) {
|
||||||
|
orderWatcherConfig.orderExpirationCheckingIntervalMs = _.parseInt(orderExpirationCheckingIntervalMs);
|
||||||
|
}
|
||||||
|
const eventPollingIntervalMs = process.env.EVENT_POLLING_INTERVAL_MS;
|
||||||
|
if (eventPollingIntervalMs !== undefined) {
|
||||||
|
orderWatcherConfig.eventPollingIntervalMs = _.parseInt(eventPollingIntervalMs);
|
||||||
|
}
|
||||||
|
const expirationMarginMs = process.env.EXPIRATION_MARGIN_MS;
|
||||||
|
if (expirationMarginMs !== undefined) {
|
||||||
|
orderWatcherConfig.expirationMarginMs = _.parseInt(expirationMarginMs);
|
||||||
|
}
|
||||||
|
const cleanupJobIntervalMs = process.env.CLEANUP_JOB_INTERVAL_MS;
|
||||||
|
if (cleanupJobIntervalMs !== undefined) {
|
||||||
|
orderWatcherConfig.cleanupJobIntervalMs = _.parseInt(cleanupJobIntervalMs);
|
||||||
|
}
|
||||||
|
const wsServer = new OrderWatcherWebSocketServer(provider, networkId, contractAddressesIfExists, orderWatcherConfig);
|
||||||
|
wsServer.start();
|
@ -1,9 +1,10 @@
|
|||||||
|
import { ContractAddresses } from '@0x/contract-addresses';
|
||||||
import { ContractWrappers } from '@0x/contract-wrappers';
|
import { ContractWrappers } from '@0x/contract-wrappers';
|
||||||
import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils';
|
import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { FillScenarios } from '@0x/fill-scenarios';
|
import { FillScenarios } from '@0x/fill-scenarios';
|
||||||
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
|
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
|
||||||
import { ExchangeContractErrs, OrderStateInvalid, OrderStateValid, SignedOrder } from '@0x/types';
|
import { ExchangeContractErrs, OrderStateInvalid, SignedOrder } from '@0x/types';
|
||||||
import { BigNumber, logUtils } from '@0x/utils';
|
import { BigNumber, logUtils } from '@0x/utils';
|
||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
@ -44,14 +45,16 @@ describe('OrderWatcherWebSocketServer', async () => {
|
|||||||
let orderHash: string;
|
let orderHash: string;
|
||||||
let addOrderPayload: AddOrderRequest;
|
let addOrderPayload: AddOrderRequest;
|
||||||
let removeOrderPayload: RemoveOrderRequest;
|
let removeOrderPayload: RemoveOrderRequest;
|
||||||
|
let networkId: number;
|
||||||
|
let contractAddresses: ContractAddresses;
|
||||||
const decimals = constants.ZRX_DECIMALS;
|
const decimals = constants.ZRX_DECIMALS;
|
||||||
const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals);
|
const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals);
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
// Set up constants
|
// Set up constants
|
||||||
const contractAddresses = await migrateOnceAsync();
|
contractAddresses = await migrateOnceAsync();
|
||||||
await blockchainLifecycle.startAsync();
|
await blockchainLifecycle.startAsync();
|
||||||
const networkId = constants.TESTRPC_NETWORK_ID;
|
networkId = constants.TESTRPC_NETWORK_ID;
|
||||||
const config = {
|
const config = {
|
||||||
networkId,
|
networkId,
|
||||||
contractAddresses,
|
contractAddresses,
|
||||||
@ -93,17 +96,16 @@ describe('OrderWatcherWebSocketServer', async () => {
|
|||||||
method: OrderWatcherMethod.RemoveOrder,
|
method: OrderWatcherMethod.RemoveOrder,
|
||||||
params: { orderHash },
|
params: { orderHash },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prepare OrderWatcher WebSocket server
|
|
||||||
const orderWatcherConfig = {
|
|
||||||
isVerbose: true,
|
|
||||||
};
|
|
||||||
wsServer = new OrderWatcherWebSocketServer(provider, networkId, contractAddresses, orderWatcherConfig);
|
|
||||||
});
|
});
|
||||||
after(async () => {
|
after(async () => {
|
||||||
await blockchainLifecycle.revertAsync();
|
await blockchainLifecycle.revertAsync();
|
||||||
});
|
});
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
// Prepare OrderWatcher WebSocket server
|
||||||
|
const orderWatcherConfig = {
|
||||||
|
isVerbose: true,
|
||||||
|
};
|
||||||
|
wsServer = new OrderWatcherWebSocketServer(provider, networkId, contractAddresses, orderWatcherConfig);
|
||||||
wsServer.start();
|
wsServer.start();
|
||||||
await blockchainLifecycle.startAsync();
|
await blockchainLifecycle.startAsync();
|
||||||
wsClient = new WebSocket.w3cwebsocket('ws://127.0.0.1:8080/');
|
wsClient = new WebSocket.w3cwebsocket('ws://127.0.0.1:8080/');
|
||||||
@ -260,7 +262,9 @@ describe('OrderWatcherWebSocketServer', async () => {
|
|||||||
id: 1,
|
id: 1,
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
method: 'ADD_ORDER',
|
method: 'ADD_ORDER',
|
||||||
signedOrder: nonZeroMakerFeeSignedOrder,
|
params: {
|
||||||
|
signedOrder: nonZeroMakerFeeSignedOrder,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set up a second client and have it add the order
|
// Set up a second client and have it add the order
|
||||||
@ -278,15 +282,15 @@ describe('OrderWatcherWebSocketServer', async () => {
|
|||||||
// Check that both clients receive the emitted event by awaiting the onMessageAsync promises
|
// Check that both clients receive the emitted event by awaiting the onMessageAsync promises
|
||||||
let updateMsg = await clientOneOnMessagePromise;
|
let updateMsg = await clientOneOnMessagePromise;
|
||||||
let updateData = JSON.parse(updateMsg.data);
|
let updateData = JSON.parse(updateMsg.data);
|
||||||
let orderState = updateData.result as OrderStateValid;
|
let orderState = updateData.result as OrderStateInvalid;
|
||||||
expect(orderState.isValid).to.be.true();
|
expect(orderState.isValid).to.be.false();
|
||||||
expect(orderState.orderRelevantState.makerFeeProxyAllowance).to.be.eq('0');
|
expect(orderState.error).to.be.eq('INSUFFICIENT_MAKER_FEE_ALLOWANCE');
|
||||||
|
|
||||||
updateMsg = await clientTwoOnMessagePromise;
|
updateMsg = await clientTwoOnMessagePromise;
|
||||||
updateData = JSON.parse(updateMsg.data);
|
updateData = JSON.parse(updateMsg.data);
|
||||||
orderState = updateData.result as OrderStateValid;
|
orderState = updateData.result as OrderStateInvalid;
|
||||||
expect(orderState.isValid).to.be.true();
|
expect(orderState.isValid).to.be.false();
|
||||||
expect(orderState.orderRelevantState.makerFeeProxyAllowance).to.be.eq('0');
|
expect(orderState.error).to.be.eq('INSUFFICIENT_MAKER_FEE_ALLOWANCE');
|
||||||
|
|
||||||
wsClientTwo.close();
|
wsClientTwo.close();
|
||||||
logUtils.log(`${new Date()} [Client] Closed.`);
|
logUtils.log(`${new Date()} [Client] Closed.`);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user