Skip to content

Commit

Permalink
Merge pull request #85 from thiagobustamante/master
Browse files Browse the repository at this point in the history
save gateway version on database
  • Loading branch information
thiagobustamante authored Dec 14, 2017
2 parents 4faf922 + ff075c8 commit 422559b
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 15 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tree-gateway",
"version": "1.3.1",
"version": "1.4.0",
"homepage": "http://treegateway.org",
"description": "The Tree Gateway API Gateway",
"author": "Thiago da Rosa de Bustamante <trbustamante@gmail.com>",
Expand Down
6 changes: 4 additions & 2 deletions src/admin/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { ApiConfig, validateApiConfig } from '../../config/api';
import { ApiService } from '../../service/api';
import { Inject } from 'typescript-ioc';
import * as swagger from 'typescript-rest-swagger';
import { Configuration } from '../../configuration';

@Path('apis')
@swagger.Tags('APIs')
@swagger.Security('Bearer')
export class APIRest {
@Inject private service: ApiService;
@Inject private config: Configuration;

@GET
list( @QueryParam('name') name?: string,
Expand All @@ -23,7 +25,7 @@ export class APIRest {
@POST
addApi(api: ApiConfig): Promise<Return.NewResource<void>> {
return new Promise<Return.NewResource<void>>((resolve, reject) => {
validateApiConfig(api)
validateApiConfig(api, this.config.gateway.disableApiIdValidation)
.then(() => this.service.create(api))
.then((apiId) => resolve(new Return.NewResource<void>(`apis/${apiId}`)))
.catch(reject);
Expand All @@ -36,7 +38,7 @@ export class APIRest {
return new Promise<void>((resolve, reject) => {
api.id = id;

validateApiConfig(api)
validateApiConfig(api, this.config.gateway.disableApiIdValidation)
.then(() => this.service.update(api))
.then(() => resolve())
.catch(reject);
Expand Down
2 changes: 1 addition & 1 deletion src/admin/config/cli-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const parser = new ArgumentParser({
parser.addArgument(
['-c', '--config'],
{
help: 'The Tree-Gateway config file (tree-gateway.json).'
help: 'The Tree-Gateway config file (tree-gateway.yml).'
}
);

Expand Down
10 changes: 5 additions & 5 deletions src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ export class Application {
}

cluster(instances: number) {
// tslint:disable:no-console
if (cluster.isMaster) {
const n = instances < 1 ? os.cpus().length : instances;
console.log(`Starting child processes...`);
console.info(`Starting child processes...`);

for (let i = 0; i < n; i++) {
const env = { processNumber: i + 1 };
Expand All @@ -37,11 +36,11 @@ export class Application {
}

cluster.on('online', function(worker) {
console.log(`Child process running PID: ${worker.process.pid} PROCESS_NUMBER: ${(<any>worker).process['env'].processNumber}`);
console.info(`Child process running PID: ${worker.process.pid} PROCESS_NUMBER: ${(<any>worker).process['env'].processNumber}`);
});

cluster.on('exit', function(worker, code, signal) {
console.log(`PID ${worker.process.pid} code: ${code} signal: ${signal}`);
console.info(`PID ${worker.process.pid} code: ${code} signal: ${signal}`);
const env = (<any>worker).process['env'];
const newWorker = cluster.fork(env);
(<any>newWorker).process['env'] = env;
Expand All @@ -55,7 +54,7 @@ export class Application {
}

process.on('uncaughtException', function(err: any) {
console.log(err);
console.error(err);
});
}

Expand All @@ -81,6 +80,7 @@ export class Application {
}
gateway.start()
.then(() => gateway.startAdmin())
.then(() => database.registerGatewayVersion())
.then(resolve)
.catch(reject);

Expand Down
6 changes: 3 additions & 3 deletions src/command-line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ const parser = new ArgumentParser({
parser.addArgument(
['-c', '--config'],
{
help: 'The Tree-Gateway config file (tree-gateway.json).'
help: 'The Tree-Gateway config file (tree-gateway.yaml).'
}
);

parser.addArgument(
['-i', '--instances'],
{
defaultValue: 1,
type: 'int',
help: 'The number of instances to start (0 = all cpus cores)'
help: 'The number of instances to start (0 = all cpus cores)',
type: 'int'
}
);

Expand Down
11 changes: 9 additions & 2 deletions src/config/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CircuitBreakerConfig, circuitBreakerConfigValidatorSchema } from './cir
import { Filter, filterSchema } from './filter';
import { ValidationError } from '../error/errors';
import { MiddlewareConfig, middlewareConfigValidatorSchema } from './middleware';
import { ObjectID } from 'bson';

/**
* The API config descriptor.
Expand Down Expand Up @@ -112,13 +113,19 @@ export let apiConfigValidatorSchema = Joi.object().keys({
version: Joi.alternatives(Joi.string(), Joi.number()).required()
});

export function validateApiConfig(apiConfig: ApiConfig) {
export function validateApiConfig(apiConfig: ApiConfig, disableApiIdValidation: boolean) {
return new Promise((resolve, reject) => {
Joi.validate(apiConfig, apiConfigValidatorSchema, (err, value) => {
if (err) {
reject(new ValidationError(err));
} else {
resolve(value);
if (disableApiIdValidation) {
return resolve(value);
}
if (value.id && !ObjectID.isValid(value.id)) {
return reject(new ValidationError(`Invalid API Id ${value.id}. The Id must be a valid ObjectID. To skip this validation, configure the 'disableApiIdValidation' property on tree-gateway.yml config file.`));
}
return resolve(value);
}
});
});
Expand Down
6 changes: 6 additions & 0 deletions src/config/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export interface GatewayConfig {
* If we are behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)
*/
underProxy?: boolean;
/**
* Force the validation of any API Id. If the id is not validated, the data could not be synchronizable
* to Leanty dashboard.
*/
disableApiIdValidation?: boolean;
/**
* Configurations for gateway logger.
*/
Expand Down Expand Up @@ -138,6 +143,7 @@ export const gatewayConfigValidatorSchema = Joi.object().keys({
accessLogger: accessLoggerConfigSchema,
admin: adminConfigValidatorSchema,
cors: corsConfigSchema,
disableApiIdValidation: Joi.boolean(),
errorHandler: middlewareConfigValidatorSchema,
filter: Joi.array().items(middlewareConfigValidatorSchema),
healthcheck: Joi.string(),
Expand Down
14 changes: 14 additions & 0 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Configuration } from './configuration';
@Singleton
@AutoWired
export class Database {
static GATEWAY_VERSION_KEY: string = '{config}:treegateway:version';

@Inject private config: Configuration;
private client: Redis.Redis;
private events: Redis.Redis;
Expand All @@ -31,6 +33,18 @@ export class Database {
this.redisEvents.disconnect();
}

registerGatewayVersion(): Promise<void> {
return new Promise<void>((resolve, reject) => {
const packageJson = require('../package.json');
this.redisClient.set(Database.GATEWAY_VERSION_KEY, `${packageJson.version}`)
.then(() => {
return resolve();
}).catch((err: any) => {
reject(new Error('It was not possible to register the Tree Gateway version.'));
});
});
}

private initializeRedis(config: RedisConfig) {
let client;

Expand Down
2 changes: 1 addition & 1 deletion src/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export class Gateway extends EventEmitter {

private loadApi(api: ApiConfig): Promise<void> {
return new Promise<void>((resolve, reject) => {
validateApiConfig(api)
validateApiConfig(api, this.config.gateway.disableApiIdValidation)
.then((value: ApiConfig) => {
this.loadValidateApi(value);
resolve();
Expand Down
23 changes: 23 additions & 0 deletions test/unit/install-apis.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,29 @@ describe('Gateway APIs install', () => {
});
});

it('should be able to reject APIs with invalid IDs', () => {
return new Promise<void>((resolve, reject) => {
sdk.apis.addApi({
id: 'INVALID_ID',
name: 'Invalid API',
path: '/invalid',
proxy: {
target: {
host: 'http://httpbin.org'
}
},
version: '1.0.0'
})
.then((apiId) => {
reject('API could not be created with invalid ID');
})
.catch(err => {
expect(err.statusCode).to.eq(403);
resolve();
});
});
});

it('should be able to export Gateway Configuration', () => {
return new Promise<void>((resolve, reject) => {
sdk.config.get()
Expand Down

0 comments on commit 422559b

Please sign in to comment.