Skip to content

Commit 7d3e868

Browse files
committed
feat: proxy cli
1 parent 53700d3 commit 7d3e868

8 files changed

+191
-16
lines changed

README.md

+17-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Proxy server for batch processing of other services using [JSONScript](https://g
1010

1111
## Install
1212

13-
To run proxy server using configuration file (not implemented yet):
13+
To run proxy server from command line using configuration file:
1414

1515
```
1616
npm install -g jsonscript-proxy
@@ -23,7 +23,21 @@ npm install jsonscript-proxy
2323
```
2424

2525

26-
## Getting started
26+
## Using from command line
27+
28+
```
29+
jsproxy config.json
30+
```
31+
32+
The parameter passed to proxy cli is the name of the config file that should be valid according to the [config schema](https://github.com/JSONScript/jsonscript-proxy/blob/master/config_schema.json). See [sample config file](https://github.com/JSONScript/jsonscript-proxy/blob/master/config_sample.json).
33+
34+
Options:
35+
36+
- -p or --port: the port proxy will listen to, `3000` by default
37+
- -a or --api: the path proxy will receive POST requests on, `/js` by default
38+
39+
40+
## Using proxy as a middleware
2741

2842
Sample proxy:
2943

@@ -141,7 +155,7 @@ Defaults:
141155
- _Promise_: an optional Promise class, the native Promise is used by default.
142156

143157

144-
## Service definitions
158+
#### Service definitions
145159

146160
`services` properties in options object should contain a map of services:
147161

bin/jsproxy.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env node
2+
3+
'use strict';
4+
5+
var express = require('express');
6+
var bodyParser = require('body-parser');
7+
var jsonscriptProxy = require('..');
8+
var _ = require('lodash');
9+
var fs = require('fs');
10+
11+
var argv = require('minimist')(process.argv.slice(2));
12+
13+
var optionsFile = argv._[0];
14+
if (!optionsFile) {
15+
console.error('Configuration file must be specified');
16+
process.exit(1);
17+
}
18+
19+
var options = JSON.parse(fs.readFileSync(optionsFile));
20+
var port = argv.p || argv.port || 3000;
21+
var api = argv.a || argv.api || '/js';
22+
23+
var app = express();
24+
app.use(bodyParser.json());
25+
app.post(api, jsonscriptProxy(options));
26+
27+
app.listen(port);
28+
console.log('JSONScript proxy listens on port', port);

config_sample.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"services": {
3+
"service1": {
4+
"basePath": "http://localhost:3001"
5+
},
6+
"service2": {
7+
"basePath": "http://localhost:3002"
8+
}
9+
},
10+
"processResponse": "body"
11+
}

config_schema.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
"type": "object"
2222
},
2323
"processResponse": { "$ref": "#/definitions/processResponse" },
24-
"Promise": { "typeof": "function" }
24+
"Promise": {
25+
"description": "Promise class to use, will be ignored if used from command line",
26+
"typeof": "function"
27+
}
2528
},
2629
"definitions": {
2730
"service": {

package.json

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
{
22
"name": "jsonscript-proxy",
3-
"version": "0.1.1",
3+
"version": "0.2.0",
44
"description": "Proxy server for scripted processing of other services using JSONScript",
55
"main": "index.js",
6+
"bin": {
7+
"jsproxy": "bin/jsproxy.js"
8+
},
69
"scripts": {
710
"test": "npm run eslint && npm run test-cov",
811
"test-spec": "mocha spec/*.spec.js -R spec",
@@ -27,15 +30,16 @@
2730
"dependencies": {
2831
"ajv": "^4.1.2",
2932
"ajv-keywords": "^0.2.0",
33+
"body-parser": "^1.15.1",
34+
"express": "^4.13.4",
3035
"jsonscript-js": "^0.4.2",
3136
"lodash": "^4.13.1",
37+
"minimist": "^1.2.0",
3238
"request": "^2.72.0"
3339
},
3440
"devDependencies": {
35-
"body-parser": "^1.15.1",
3641
"coveralls": "^2.11.9",
3742
"eslint": "^2.12.0",
38-
"express": "^4.13.4",
3943
"istanbul": "^0.4.3",
4044
"mocha": "^2.5.3",
4145
"pre-commit": "^1.1.3",

spec/proxy_cli.spec.js

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
'use strict';
2+
3+
var startService = require('./service')
4+
, request = require('request')
5+
, assert = require('assert')
6+
, spawn = require('child_process').spawn;
7+
8+
describe('jsonscript proxy cli', function() {
9+
var proxy;
10+
11+
before(function (done) {
12+
proxy = spawnProxy(['proxy_config.json']);
13+
startService('service1', 3003);
14+
startService('service2', 3004);
15+
setTimeout(done, 1000);
16+
});
17+
18+
after(function (done) {
19+
proxy.on('exit', done);
20+
proxy.kill();
21+
});
22+
23+
describe('parallel evaluation', function() {
24+
it('should process script via proxy', function (done) {
25+
testProxy(3000, '/js', done);
26+
});
27+
});
28+
29+
describe('port option', function() {
30+
it('should support -p option', function (done) {
31+
var proxy = spawnProxy(['-p', '3010', 'proxy_config.json']);
32+
testNewProxy(proxy, 3010, '/js', done);
33+
});
34+
35+
it('should support --port option', function (done) {
36+
var proxy = spawnProxy(['--port', '3020', 'proxy_config.json']);
37+
testNewProxy(proxy, 3020, '/js', done);
38+
});
39+
});
40+
41+
describe('api option', function() {
42+
it('should support -a option', function (done) {
43+
var proxy = spawnProxy(['-a', '/jsonscript', '-p', '3030', 'proxy_config.json']);
44+
testNewProxy(proxy, 3030, '/jsonscript', done);
45+
});
46+
47+
it('should support --api option', function (done) {
48+
var proxy = spawnProxy(['--api', '/jsonscript', '-p', '3040', 'proxy_config.json']);
49+
testNewProxy(proxy, 3040, '/jsonscript', done);
50+
});
51+
});
52+
});
53+
54+
55+
function spawnProxy(params) {
56+
return spawn('../bin/jsproxy.js', params, { cwd: __dirname });
57+
}
58+
59+
60+
function testProxy(port, api, callback) {
61+
send(port, api, {
62+
script: {
63+
obj1: { '$$service1.get': { path: '/object/1' } },
64+
obj2: { '$$service2.get': { path: '/object/2' } }
65+
}
66+
}, function (err, resp, body) {
67+
assert(!err, err && err.message);
68+
assert.equal(resp.statusCode, 200);
69+
assertGetResult(body.obj1, 'service1', 'object', '1');
70+
assertGetResult(body.obj2, 'service2', 'object', '2');
71+
callback();
72+
});
73+
}
74+
75+
76+
function testNewProxy(proxy, port, api, callback) {
77+
setTimeout(function() {
78+
testProxy(port, api, function() {
79+
proxy.on('exit', callback);
80+
proxy.kill();
81+
});
82+
}, 1000);
83+
}
84+
85+
86+
function send(port, api, reqBody, callback) {
87+
request.post({
88+
uri: 'http://localhost:' + port + api,
89+
headers: { Accept: 'application/json' },
90+
json: reqBody
91+
}, callback);
92+
}
93+
94+
95+
function assertGetResult(result, serviceName, name, id) {
96+
assert.equal(result.statusCode, 200);
97+
assert.equal(typeof result.headers, 'object');
98+
assert.deepEqual(result.request, { method: 'get', path: '/' + name + '/' + id })
99+
assert.deepEqual(result.body, {
100+
name: name,
101+
id: id,
102+
service: serviceName,
103+
info: 'resource ' + name + ' id ' + id
104+
});
105+
}

spec/proxy_config.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"services": {
3+
"service1": {
4+
"basePath": "http://localhost:3003/api"
5+
},
6+
"service2": {
7+
"basePath": "http://localhost:3004/api"
8+
}
9+
}
10+
}

spec/proxy_handler.spec.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
'use strict';
22

3-
var test = require('supertest');
4-
var createProxy = require('./proxy');
5-
var startService = require('./service');
6-
var assert = require('assert');
3+
var createProxy = require('./proxy')
4+
, startService = require('./service')
5+
, test = require('supertest')
6+
, assert = require('assert');
77

88
var SERVICES = {
99
service1: {
@@ -15,12 +15,12 @@ var SERVICES = {
1515
};
1616

1717
describe('jsonscript proxy handler', function() {
18-
var proxy, service1, service2;
18+
var proxy;
1919

2020
before(function (done) {
21-
service1 = startService('service1', 3001);
22-
service2 = startService('service2', 3002);
23-
setTimeout(done, 1000);
21+
startService('service1', 3001);
22+
startService('service2', 3002);
23+
setTimeout(done, 500);
2424
});
2525

2626
beforeEach(function() {
@@ -270,7 +270,7 @@ describe('jsonscript proxy handler', function() {
270270
describe('options validation', function() {
271271
it('should throw if options are invalid', function() {
272272
assert.throws(function() {
273-
var proxy = createProxy({}); // "services" is required property
273+
proxy = createProxy({}); // "services" is required property
274274
});
275275
});
276276
});

0 commit comments

Comments
 (0)