trooba-bootstrap
Bootstrap Trooba pipeline from configuration file.
This functionality is important when one needs to scale to 100+ applications.
The idea is it is always easy to inject new configuration than ask applications developers of more than 100+ applications/teams to update their code to meet new service requirements. This also allows to provide default configurations by platform team.
Install
$ npm install trooba-bootstrap -S
Usage
Configuration
Configuration has two main artifacts:
-
Handlers profile definition is where platform team would define all handlers that can be used to build pipelines and their default configuration if any.
-
Service client or endpoint configuration is actual configuration used by application developer to define specific configuration for service clients and/or endpoints.
Handlers profile declaration
The definition specifies a path to the module, execution priority (specifies position priority) and default configuration if needed.
const profiles = {
"default": {
"trace": {
"priority": 10,
"module": "trooba-opentrace"
},
"circuit": {
"priority": 20,
"module": "trooba-hystrix-handler",
"config": {
"timeout": 0,
"circuitBreakerErrorThresholdPercentage": 50
}
},
"retry": {
"priority": 30,
"module": "trooba-retry"
},
"http-transport": {
"transport": true,
"module": "trooba-http-transport"
}
},
"soap": {
"trace": {
"priority": 10,
"module": "trooba-opentrace"
},
"circuit": {
"priority": 20,
"module": "trooba-hystrix-handler",
"config": {
"timeout": 0,
"circuitBreakerErrorThresholdPercentage": 70
}
},
"retry": {
"priority": 30,
"module": "trooba-retry"
},
"soap": {
"priority": 40,
"module": "trooba-soap"
}
"http-transport": {
"transport": true,
"module": "trooba-http-transport"
}
}
}
Service client or endpoint configuration
This section would declare a configuration for a specific pipeline. For example, we can have one configuration to make service calls to one service 'foo' and other for service 'bar'.
The pipeline configuration can provide specific configurations for every handler if needed. This config will override default configuration properties for the given handler or transport.
const clients = {
"my-service-rest-client": {
"circuit": {
"config": {
"circuitBreakerErrorThresholdPercentage": 70
}
},
"retry": {
"priority": 35,
"config": {
"retry": 3
}
},
"http-transport": {
"config": {
"context": "my-app-http-context",
"hostname": "localhost",
"port": 8000,
"protocol": "http:",
"path": "/view/item",
"socketTimeout": 2000
}
}
},
"my-service-soap-client": {
"$profile": "soap",
"http-transport": {
"config": {
"context": "my-app-http-context",
"hostname": "localhost",
"port": 8000,
"protocol": "http:",
"path": "/view/item",
"socketTimeout": 2000
}
}
},
"my-service-extend-client": {
"$profile": "soap",
"metrics": {
"priority": 1000,
"module": "metrics-module"
},
"http-transport": {
"config": {
"context": "my-app-http-context",
"hostname": "localhost",
"port": 8000,
"protocol": "http:"
}
}
}
}
Bootstrapping from config
const provider = require('trooba-bootstrap')(profiles, clients);
Provider.updateProfiles(profiles);
Provider.updatePipes(clients);
Provider.createClient('my-service-rest-client');
.create({ 'some': 'context' })
.request({foo:'bar'}, console.log);
Sharing handlers between middleware and service invocation pipelines.
In this case one needs to be aware of a few differences:
- The handler priorities may need to be different.
- The transport always goes first and then the handlers in execution order.
- Client configs become routes for incoming traffic.
- Some of the handlers may not be needed or new ones needs to be added.
The above requirements may require to re-define priorities for the routes.
Define middleware for the incoming traffic
const profiles = {
"default": {
"http-transport": {
"config": {
"port": [8000, 8443]
}
},
"router-match": {
"priority": 0,
"module": "trooba-http-router/matcher"
},
"retry": {},
"router-invoke": {
"priority": 1000,
"module": "trooba-http-router/invoker"
}
}
};
const middleware = {
"my-service": {
"$profile": "default",
"http-transport": {
"config": {
"context": "my-app-http-context"
}
},
"router-match": {
"config": {
"routes": "./routes.json"
}
},
"jsonParser": {
"priority": 50
},
"cookies": {
"priority": 60,
"module": "cookies-module"
},
"trace": {
"enabled": false
}
}
};
const provider = require('trooba-bootstrap')(profiles, middleware);
const app = Provider.createService('my-service');
app.listen(8000, () => {
console.log('The server is ready');
})