Skip to content

Commit 3bf58a0

Browse files
committed
runner router
1 parent 3896410 commit 3bf58a0

13 files changed

Lines changed: 158 additions & 110 deletions

File tree

examples/test-service-node-host.js

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
const Path = require('path')
22
const debug = require('debug')('test.server-db')
33
const Dataparty = require('../src')
4-
5-
const BouncerServerModels = require('@dataparty/bouncer-model')
6-
const BouncerClientModels = require('@dataparty/bouncer-model/dist/bouncer-model.json')
4+
const dataparty_crypto = require('@dataparty/crypto')
75

86
class ExampleService extends Dataparty.IService {
97
constructor(opts){
@@ -19,6 +17,8 @@ class ExampleService extends Dataparty.IService {
1917
this.addEndpoint(Dataparty.endpoint_paths.secureecho)
2018
this.addEndpoint(Dataparty.endpoint_paths.identity)
2119
this.addEndpoint(Dataparty.endpoint_paths.version)
20+
21+
this.addSchema(Path.join(__dirname, './party/schema/basic_types.js'))
2222
}
2323

2424
}
@@ -29,38 +29,53 @@ async function main(){
2929
//const uri = 'mongodb://localhost:27017/server-party-test'
3030
//debug('db location', uri)
3131

32-
const path = '/data/datparty/srv-party'
32+
33+
const service = new ExampleService({ name: '@dataparty/example', version: '0.0.1' })
34+
const build = await service.compile(Path.join(__dirname,'/dataparty'), true)
35+
36+
const serviceName = build.package.name
37+
const basePath = '/data/datparty/'
38+
const servicePath = Path.join(basePath, serviceName.replace('/','-'))
39+
40+
let config = new Dataparty.Config.JsonFileConfig({ basePath: servicePath })
41+
config.touchDir('/tingo')
3342

43+
const dbPath = Path.join(servicePath, '/tingo')
3444

3545
let party = new Dataparty.TingoParty({
36-
path,
37-
model: BouncerClientModels,
38-
serverModels: BouncerServerModels,
39-
config: new Dataparty.Config.JsonFileConfig({basePath: '/data/datparty/'})
46+
config,
47+
path: dbPath,
48+
model: build
4049
})
4150

4251
party.topics = new Dataparty.LocalTopicHost()
4352

44-
const service = new ExampleService({ name: '@dataparty/example', version: '0.0.1' })
45-
46-
const build = await service.compile(Path.join(__dirname,'/dataparty'), true)
47-
48-
debug('built', Object.keys(build))
53+
const live = new Dataparty.IService(build.package, build)
4954

55+
5056
const runner = new Dataparty.ServiceRunnerNode({
51-
party, service,
57+
party,
58+
prefix: '',
59+
service: live,
5260
sendFullErrors: false,
5361
useNative: false
5462
})
5563

64+
await party.start()
65+
await runner.start()
66+
67+
68+
const runnerRouter = new Dataparty.RunnerRouter(runner)
69+
70+
//const srvRouter = new ServiceRouter()
71+
//srvRouter.addRunner(domain, prefix, runner)
72+
5673
const host = new Dataparty.ServiceHost({
57-
runner,
74+
runner: runnerRouter,
5875
trust_proxy: true,
5976
wsEnabled: true,
6077
})
6178

62-
await party.start()
63-
await runner.start()
6479
await host.start()
6580

6681
console.log('started')

src/bouncer/idb.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module.exports = class IDb extends EventEmitter {
2424
for(const collectionName of this.factory.getValidators()){
2525
debug('creating collection', collectionName)
2626

27-
const indexSettings = reach(this.factory, 'model.IndexSettings.'+collectionName)
27+
const indexSettings = reach(this.factory, 'model.schemas.IndexSettings.'+collectionName)
2828
await this.createCollection(collectionName, indexSettings)
2929
}
3030
}

src/config/json-file.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
22

33
const fs = require('fs')
4+
const Path = require('path')
5+
const mkdirp = require('mkdirp')
46
const deepSet = require('deep-set')
57
const reach = require('../utils/reach')
68
const logger = require('debug')('dataparty.config.json-file');
@@ -12,7 +14,8 @@ const logger = require('debug')('dataparty.config.json-file');
1214
class JsonFileConfig {
1315

1416
constructor(defaults={}){
15-
this.path = reach(defaults, 'basePath') +'/config.json'
17+
this.basePath = reach(defaults, 'basePath')
18+
this.path = this.basePath +'/config.json'
1619
this.defaults = defaults || {}
1720
this.content = Object.assign({}, this.defaults)
1821
}
@@ -40,6 +43,7 @@ class JsonFileConfig {
4043
}
4144

4245
async start () {
46+
await this.touchDir('')
4347
await this.load()
4448
logger('started')
4549
}
@@ -72,6 +76,23 @@ class JsonFileConfig {
7276
async save(){
7377
fs.writeFileSync(this.path, JSON.stringify(this.content, null, 2))
7478
}
79+
80+
async touchDir (path) {
81+
return new Promise((resolve, reject) => {
82+
const basedPath = Path.join(this.basePath, path)
83+
logger('touching', basedPath)
84+
mkdirp(basedPath, (error) => {
85+
if (error) {
86+
logger(`failed to mkdirp '${basedPath}':`, error)
87+
return reject(error)
88+
}
89+
90+
logger('touched', basedPath)
91+
// resolve to adjusted path on success
92+
resolve(basedPath)
93+
})
94+
})
95+
}
7596
}
7697

7798
module.exports = JsonFileConfig

src/party/document-factory.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ const Ajv = require('ajv')
22
const debug = require('debug')('dataparty.document-factory')
33
const IDocument = require('./idocument')
44

5+
const reach = require('../utils/reach')
6+
57
const DocumentValidationError = require('../errors/document-validation-error')
68

79

@@ -18,7 +20,8 @@ class DocumentFactory {
1820
this.validators = {}
1921

2022
if(this.model){
21-
for(let schema of this.model.JSONSchema){
23+
24+
for(let schema of this.model.schemas.JSONSchema){
2225
const v = this.ajv.compile(schema)
2326
this.validators[schema.title] = v
2427
debug(schema.title)

src/party/iparty.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class IParty {
140140
*/
141141
get identity(){
142142
if (!this.hasIdentity()){ return undefined }
143-
return this._identity.toJSON(false)
143+
return dataparty_crypto.Identity.fromString(this._identity.toString())
144144
}
145145

146146
get privateIdentity(){

src/service/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = {
66
IEndpoint: require('./iendpoint'),
77
IMiddleware: require('./imiddleware'),
88
ServiceHost: require('./service-host'),
9+
RunnerRouter: require('./runner-router'),
910
ServiceRunner: require('./service-runner'),
1011
ServiceRunnerNode: require('./service-runner-node'),
1112
EndpointRunner: require('./endpoint-runner'),

src/service/iservice.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const debug = require('debug')('dataparty.service.IService')
1212
module.exports = class IService {
1313
constructor({
1414
name, version, githash='', branch=''
15-
}){
15+
}, build){
1616

1717
this.constructors = {
1818
schemas: {},
@@ -79,6 +79,10 @@ module.exports = class IService {
7979
quiet: false, // default
8080
debugLog: false // default
8181
}
82+
83+
if(build){
84+
this.importBuild(build)
85+
}
8286
}
8387

8488
importBuild(buildOutput){

src/service/runner-router.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
const Debug = require('debug')
2+
const debug = Debug('dataparty.service.runner-router')
3+
4+
class RunnerRouter {
5+
constructor(defaultRunner){
6+
debug('constructor')
7+
this.defaultRunner = defaultRunner
8+
9+
debug('default runner - ', this.defaultRunner.party.identity)
10+
11+
this.runnersByDomain = new Map()
12+
this.runnersByHost = new Map()
13+
14+
this.started = false
15+
}
16+
17+
async start(){
18+
19+
if(this.started){ return }
20+
21+
debug('start')
22+
23+
this.started = true
24+
25+
for(let runner of this.runnersByHost){
26+
await runner.start()
27+
}
28+
}
29+
30+
getRunnerByDomain(domain){
31+
debug('getRunnerByDomain -', domain)
32+
const runner = this.runnersByDomain.get(domain)
33+
if(!runner){
34+
return this.defaultRunner
35+
}
36+
}
37+
38+
getRunnerByHostIdentity(identity){
39+
const partyId = identity.toString()
40+
debug('getRunnerByHostIdentity -', partyId)
41+
const runner = this.runnersByHost.get(partyId)
42+
43+
return runner
44+
}
45+
46+
addRunner({domain, runner}){
47+
48+
const partyId = runner.party.identity.toString()
49+
debug('addRunner - ', partyId, domain)
50+
51+
if(!this.runnersByHost.has(party)){
52+
this.runnersByHost.set(partyId, runner)
53+
}
54+
55+
56+
if(domain && !this.runnersByDomain.has(party)){
57+
this.runnersByDomain.set(domain, runner)
58+
}
59+
}
60+
61+
62+
onRequest(req, res){
63+
const runner = this.getRunnerByDomain(req.hostname)
64+
65+
return runner.onRequest.bind(runner)(req,res)
66+
}
67+
}
68+
69+
module.exports = RunnerRouter

src/service/service-host-websocket.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,15 @@ class ServiceHostWebsocket{
100100

101101
debug('creating peer party')
102102

103+
104+
let hostRunner = this.runner.party ? this.runner : this.runner.getRunnerByDomain(req.hostname)
105+
let hostParty = hostRunner.party
106+
103107
let peer = new PeerParty({
104-
hostParty: this.runner.party,
105-
hostRunner: this.runner,
106-
model: this.runner.party.factory.model,
107-
config: this.runner.party.config,
108+
hostParty,
109+
hostRunner,
110+
model: hostParty.factory.model,
111+
config: hostParty.config,
108112
comms: new Comms.WebsocketComms({
109113
host: true,
110114
connection: conn,

src/service/service-runner-node.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const Router = require('origin-router').Router
1010
const Runner = require('@dataparty/tasker').Runner
1111

1212
class ServiceRunnerNode {
13-
constructor({service, party, sendFullErrors=false, useNative=true}){
13+
constructor({service, party, sendFullErrors=false, useNative=true, prefix='', router=new Router()}){
1414
this.party = party
1515
this.service = service
1616
this.sendFullErrors = sendFullErrors
@@ -20,7 +20,8 @@ class ServiceRunnerNode {
2020
this.endpoint = {}
2121
this.tasks = {}
2222

23-
this.router = new Router()
23+
this.prefix=prefix
24+
this.router = router
2425
this.taskRunner = new Runner()
2526
}
2627

@@ -143,9 +144,11 @@ class ServiceRunnerNode {
143144

144145
this.endpoint[name] = endpoint
145146

146-
this.router.add(name, name, this.endpointHandler(endpoint))
147+
const routablePath = Path.join(this.prefix, Path.normalize(name))
148+
149+
this.router.add(name, routablePath, this.endpointHandler(endpoint))
147150
dt.end()
148-
debug('loaded endpoint',name,'in',dt.deltaMs,'ms')
151+
debug('loaded endpoint', routablePath,'in',dt.deltaMs,'ms')
149152
}
150153

151154

@@ -230,12 +233,11 @@ class ServiceRunnerNode {
230233
}
231234

232235
async onRequest(req, res){
233-
debug('onRequest')
236+
debug('onRequest', req)
234237

235238
debug('req', req.method, req.hostname,'-', req.url, req.ips, req.body)
236239

237240

238-
239241
let route = await this.router.route(req, res)
240242

241243
debug('req done')

0 commit comments

Comments
 (0)