-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for dynamic proxying of requests
adds support for localfile specification, service initialization with exponential backoff,and programatic instantiation of service runner
- Loading branch information
Showing
51 changed files
with
7,092 additions
and
2,552 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"name": "simple-math-test", | ||
"version": "0.0.0-simple-math-test", | ||
"dependencies": { | ||
"@open-rpc/client-js": "^1.0.1", | ||
"@open-rpc/server-js": "^1.3.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
|
||
// Code generated by @open-rpc/client-generator DO NOT EDIT. | ||
import { RequestManager, WebSocketTransport, HTTPTransport, Client } from "@open-rpc/client-js"; | ||
import _ from "lodash"; | ||
import { OpenRPC, MethodObject, ContentDescriptorObject } from "@open-rpc/meta-schema"; | ||
import { MethodCallValidator, MethodNotFoundError } from "@open-rpc/schema-utils-js"; | ||
|
||
export type IntegerTfIB8Svh = number; | ||
export type Addition = (a?: IntegerTfIB8Svh, b?: IntegerTfIB8Svh) => Promise<IntegerTfIB8Svh>; | ||
export type Subtraction = (a?: IntegerTfIB8Svh, b?: IntegerTfIB8Svh) => Promise<IntegerTfIB8Svh>; | ||
|
||
export interface Options { | ||
transport: { | ||
type: "websocket" | "http" | "https"; | ||
host: string; | ||
port: number; | ||
path?: string; | ||
}; | ||
} | ||
|
||
export class SimpleMath { | ||
public static openrpcDocument: OpenRPC = { "openrpc": "1.0.0-rc1", "info": { "title": "Simple Math", "description": "A simple math example", "version": "1.0.0" }, "servers": [{ "name": "my simple math server", "summary": "simple math server summary", "description": "simple math server description", "url": "http://${username}.simple-math.example.org:${port}/${basePath}/", "variables": { "username": { "default": "demo", "description": "this is applied to the url as the subdomain" }, "port": { "default": "443", "enum": ["8545", "443"] }, "basePath": { "default": "jsonrpc" } } }], "methods": [{ "name": "addition", "params": [{ "name": "a", "schema": { "type": "integer" } }, { "name": "b", "schema": { "type": "integer" } }], "result": { "name": "c", "schema": { "type": "integer" } }, "examples": [{ "name": "simpleMathAdditionTwo", "params": [{ "name": "two", "summary": "its a sample two", "description": "Im not sure how else to say two", "value": 2 }, { "name": "two", "summary": "its a sample two", "description": "Im not sure how else to say two", "value": 2 }], "result": { "name": "four", "summary": "its a sample four", "description": "Im not sure how else to say four", "value": 4 } }, { "name": "simpleMathAdditionFour", "params": [{ "name": "four", "summary": "its a sample four", "description": "Im not sure how else to say four", "value": 4 }, { "name": "four", "summary": "its a sample four", "description": "Im not sure how else to say four", "value": 4 }], "result": { "name": "eight", "summary": "its a sample eight", "description": "Im not sure how else to say eight", "value": 8 } }], "links": [{ "name": "subtractionLink", "description": "use the parameters from addition for subtraction", "method": "subtraction", "params": { "a": "$params.a", "b": "$params.b" } }] }, { "name": "subtraction", "params": [{ "name": "a", "schema": { "type": "integer" } }, { "name": "b", "schema": { "type": "integer" } }], "result": { "name": "c", "schema": { "type": "integer" } }, "examples": [{ "name": "examplesSubtractFourTwo", "params": [{ "name": "four", "summary": "its a sample four", "description": "Im not sure how else to say four", "value": 4 }, { "name": "two", "summary": "its a sample two", "description": "Im not sure how else to say two", "value": 2 }], "result": { "name": "two", "summary": "its a sample two", "description": "Im not sure how else to say two", "value": 2 } }, { "name": "examplesSubtractEightFour", "params": [{ "name": "eight", "summary": "its a sample eight", "description": "Im not sure how else to say eight", "value": 8 }, { "name": "four", "summary": "its a sample four", "description": "Im not sure how else to say four", "value": 4 }], "result": { "name": "four", "summary": "its a sample four", "description": "Im not sure how else to say four", "value": 4 } }], "links": [{ "name": "additionLink", "description": "use the parameters from subtraction for addition", "method": "addition", "params": { "a": "$params.a", "b": "$params.b" } }] }], "components": { "contentDescriptors": { "c": { "name": "c", "schema": { "type": "integer" } } }, "schemas": { "Integer": { "type": "integer" } }, "examples": { "integerTwo": { "name": "two", "summary": "its a sample two", "description": "Im not sure how else to say two", "value": 2 }, "integerFour": { "name": "four", "summary": "its a sample four", "description": "Im not sure how else to say four", "value": 4 }, "integerEight": { "name": "eight", "summary": "its a sample eight", "description": "Im not sure how else to say eight", "value": 8 } } } }; | ||
public rpc: Client; | ||
public transport: HTTPTransport | WebSocketTransport; | ||
private validator: MethodCallValidator; | ||
|
||
constructor(options: Options) { | ||
// this.openrpcDocument = {"openrpc":"1.0.0-rc1","info":{"title":"Simple Math","description":"A simple math example","version":"1.0.0"},"servers":[{"name":"my simple math server","summary":"simple math server summary","description":"simple math server description","url":"http://${username}.simple-math.example.org:${port}/${basePath}/","variables":{"username":{"default":"demo","description":"this is applied to the url as the subdomain"},"port":{"default":"443","enum":["8545","443"]},"basePath":{"default":"jsonrpc"}}}],"methods":[{"name":"addition","params":[{"name":"a","schema":{"type":"integer"}},{"name":"b","schema":{"type":"integer"}}],"result":{"name":"c","schema":{"type":"integer"}},"examples":[{"name":"simpleMathAdditionTwo","params":[{"name":"two","summary":"its a sample two","description":"Im not sure how else to say two","value":2},{"name":"two","summary":"its a sample two","description":"Im not sure how else to say two","value":2}],"result":{"name":"four","summary":"its a sample four","description":"Im not sure how else to say four","value":4}},{"name":"simpleMathAdditionFour","params":[{"name":"four","summary":"its a sample four","description":"Im not sure how else to say four","value":4},{"name":"four","summary":"its a sample four","description":"Im not sure how else to say four","value":4}],"result":{"name":"eight","summary":"its a sample eight","description":"Im not sure how else to say eight","value":8}}],"links":[{"name":"subtractionLink","description":"use the parameters from addition for subtraction","method":"subtraction","params":{"a":"$params.a","b":"$params.b"}}]},{"name":"subtraction","params":[{"name":"a","schema":{"type":"integer"}},{"name":"b","schema":{"type":"integer"}}],"result":{"name":"c","schema":{"type":"integer"}},"examples":[{"name":"examplesSubtractFourTwo","params":[{"name":"four","summary":"its a sample four","description":"Im not sure how else to say four","value":4},{"name":"two","summary":"its a sample two","description":"Im not sure how else to say two","value":2}],"result":{"name":"two","summary":"its a sample two","description":"Im not sure how else to say two","value":2}},{"name":"examplesSubtractEightFour","params":[{"name":"eight","summary":"its a sample eight","description":"Im not sure how else to say eight","value":8},{"name":"four","summary":"its a sample four","description":"Im not sure how else to say four","value":4}],"result":{"name":"four","summary":"its a sample four","description":"Im not sure how else to say four","value":4}}],"links":[{"name":"additionLink","description":"use the parameters from subtraction for addition","method":"addition","params":{"a":"$params.a","b":"$params.b"}}]}],"components":{"contentDescriptors":{"c":{"name":"c","schema":{"type":"integer"}}},"schemas":{"Integer":{"type":"integer"}},"examples":{"integerTwo":{"name":"two","summary":"its a sample two","description":"Im not sure how else to say two","value":2},"integerFour":{"name":"four","summary":"its a sample four","description":"Im not sure how else to say four","value":4},"integerEight":{"name":"eight","summary":"its a sample eight","description":"Im not sure how else to say eight","value":8}}}}; | ||
|
||
if (options.transport === undefined || options.transport.type === undefined) { | ||
throw new Error("Invalid constructor params"); | ||
} | ||
const { type, host, port } = options.transport; | ||
let path = options.transport.path || ""; | ||
if (path && path[0] !== "/") { | ||
path = "/" + path; | ||
} | ||
switch (type) { | ||
case "http": | ||
case "https": | ||
this.transport = new HTTPTransport(type + "://" + host + ":" + port + path); | ||
break; | ||
case "websocket": | ||
this.transport = new WebSocketTransport("ws://" + host + ":" + port + path); | ||
break; | ||
default: | ||
throw new Error("unsupported transport"); | ||
break; | ||
} | ||
this.rpc = new Client(new RequestManager([this.transport])); | ||
this.validator = new MethodCallValidator(SimpleMath.openrpcDocument); | ||
} | ||
|
||
/** | ||
* Initiates [[SimpleMath.startBatch]] in order to build a batch call. | ||
* | ||
* Subsequent calls to [[SimpleMath.request]] will be added to the batch. | ||
* Once [[SimpleMath.stopBatch]] is called, the promises for the [[SimpleMath.request]] | ||
* will then be resolved. If there is already a batch in progress this method is a noop. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.foo().then(() => console.log("foobar")) | ||
* myClient.bar().then(() => console.log("foobarbaz")) | ||
* myClient.stopBatch(); | ||
*/ | ||
public startBatch(): void { | ||
// return this.rpc.startBatch(); | ||
} | ||
|
||
/** | ||
* Initiates [[Client.stopBatch]] in order to finalize and send the batch to the underlying transport. | ||
* | ||
* stopBatch will send the [[SimpleMath]] calls made since the last [[SimpleMath.startBatch]] call. For | ||
* that reason, [[SimpleMath.startBatch]] MUST be called before [[SimpleMath.stopBatch]]. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.foo().then(() => console.log("foobar")) | ||
* myClient.bar().then(() => console.log("foobarbaz")) | ||
* myClient.stopBatch(); | ||
*/ | ||
public stopBatch(): void { | ||
return this.rpc.stopBatch(); | ||
} | ||
|
||
/** | ||
* | ||
*/ | ||
public addition: Addition = (...params) => { | ||
return this.request("addition", params); | ||
} | ||
|
||
/** | ||
* | ||
*/ | ||
public subtraction: Subtraction = (...params) => { | ||
return this.request("subtraction", params); | ||
} | ||
|
||
private request(methodName: string, params: any[]): Promise<any> { | ||
const methodObject = _.find(SimpleMath.openrpcDocument.methods, ({ name }) => name === methodName) as MethodObject; | ||
const openRpcMethodValidationErrors = this.validator.validate(methodName, params); | ||
if (openRpcMethodValidationErrors instanceof MethodNotFoundError || openRpcMethodValidationErrors.length > 0) { | ||
return Promise.reject(openRpcMethodValidationErrors); | ||
} | ||
|
||
let rpcParams; | ||
if (methodObject.paramStructure && methodObject.paramStructure === "by-name") { | ||
rpcParams = _.zipObject(params, _.map(methodObject.params, "name")); | ||
} else { | ||
rpcParams = params; | ||
} | ||
return this.rpc.request(methodName, rpcParams); | ||
} | ||
|
||
} | ||
export default SimpleMath; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
export const simpleMathConfig = (assetLocation: string) => { | ||
return { | ||
services: [ | ||
{ | ||
name: "simple-math", | ||
version: "1.0.0", | ||
rpcPort: "${DYNAMIC_TCP_PORT_1}", | ||
environments: [ | ||
{ | ||
name: "http", | ||
args: { | ||
start: ["${SERVICE_DIR}/index.js", "--port=${DYNAMIC_TCP_PORT_1}", "--mode=http"], | ||
stop: [], | ||
teardown: [], | ||
}, | ||
health: { | ||
interval: 20000, | ||
retries: 5, | ||
port: "${DYNAMIC_TCP_PORT_1}", | ||
protocol: "tcp", | ||
}, | ||
}, | ||
{ | ||
rpcPort: "${DYNAMIC_TCP_PORT_1}", | ||
name: "ws", | ||
args: { | ||
start: ["${SERVICE_DIR}/index.js", "--port=${DYNAMIC_TCP_PORT_1}", "--mode=ws"], | ||
stop: [], | ||
teardown: [], | ||
}, | ||
health: { | ||
interval: 20000, | ||
retries: 5, | ||
port: "${DYNAMIC_TCP_PORT_1}", | ||
protocol: "tcp", | ||
}, | ||
}, | ||
], | ||
os: { | ||
osx: { | ||
commands: { | ||
setup: [], | ||
start: "node", | ||
stop: "", | ||
teardown: "", | ||
}, | ||
assets: [`file://${assetLocation}/testService.zip`], | ||
}, | ||
linux: { | ||
commands: { | ||
setup: [], | ||
start: "node", | ||
stop: "", | ||
teardown: "", | ||
}, | ||
assets: [`file://${assetLocation}/testService.zip`], | ||
}, | ||
windows: { | ||
commands: { | ||
setup: [], | ||
start: "node", | ||
stop: "", | ||
teardown: "", | ||
}, | ||
assets: [`file://${assetLocation}/testService.zip`], | ||
}, | ||
}, | ||
|
||
}, | ||
], | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { testServer } from "./server"; | ||
import { SimpleMath } from "./client"; | ||
import program from "commander"; | ||
program | ||
.option( | ||
"-p, --port <port>", | ||
"Set port for simple math", | ||
"8900", | ||
) | ||
.option( | ||
"-m, --mode <mode>", | ||
"Set protocol for simple math ws, wss, http, https", | ||
"ws", | ||
) | ||
.action(async () => { | ||
const port = parseInt(program.port, 10); | ||
const server = testServer(port, program.mode, SimpleMath.openrpcDocument, {}); | ||
// tslint:disable-next-line:no-console | ||
console.log(`simplemath test server starting with ${program.mode} - ${program.port}`); | ||
server.start(); | ||
// tslint:disable-next-line:no-console | ||
console.log("simplemath test server started"); | ||
}) | ||
.parse(process.argv); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { OpenRPC } from "@open-rpc/meta-schema"; | ||
import { Server, IServerOptions } from "@open-rpc/server-js"; | ||
export type TestProtocol = "ws" | "http"; | ||
|
||
export const testServer = (port: number, protocol: TestProtocol, openrpcDocument: OpenRPC, opts: any) => { | ||
|
||
let options = {} as IServerOptions; | ||
|
||
let transportConfigs; | ||
switch ( protocol) { | ||
case "ws": | ||
transportConfigs = [ | ||
{ | ||
options: { | ||
middleware: [], | ||
port, | ||
}, | ||
type: "WebSocketTransport", | ||
}, | ||
]; | ||
break; | ||
case "http": | ||
transportConfigs = [ | ||
{ | ||
options: { | ||
middleware: [], | ||
port, | ||
}, | ||
type: "HTTPTransport", | ||
}, | ||
]; | ||
break; | ||
} | ||
options = { | ||
methodMapping: { mockMode: true }, | ||
openrpcDocument, | ||
transportConfigs, | ||
} as IServerOptions; | ||
return new Server(options); | ||
}; |
Oops, something went wrong.