mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Statefull modules should be injected from top
This commit is contained in:
		
							parent
							
								
									b85d9eb6d6
								
							
						
					
					
						commit
						2d8fa7ee6b
					
				
							
								
								
									
										3
									
								
								app.js
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								app.js
									
									
									
									
									
								
							| @ -31,7 +31,8 @@ module.exports = function(config) { | |||||||
| 
 | 
 | ||||||
|     app.use(cookieParser()); |     app.use(cookieParser()); | ||||||
| 
 | 
 | ||||||
|     routes.create(router); |     // Setup API routes
 | ||||||
|  |     routes.create(router, config); | ||||||
| 
 | 
 | ||||||
|     app.use(baseUriPath, router); |     app.use(baseUriPath, router); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										29
									
								
								lib/databaseConfig.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/databaseConfig.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | var nconf  = require('nconf'); | ||||||
|  | var fs     = require('fs'); | ||||||
|  | var ini    = require('ini'); | ||||||
|  | var logger = require('./logger'); | ||||||
|  | 
 | ||||||
|  | function getDatabaseIniUrl() { | ||||||
|  |     // Finn specific way of delivering env variables
 | ||||||
|  |     var databaseini = nconf.argv().get('databaseini'); | ||||||
|  |     var config = ini.parse(fs.readFileSync(databaseini, 'utf-8')); | ||||||
|  | 
 | ||||||
|  |     logger.info('unleash started with databaseini: ' + databaseini); | ||||||
|  | 
 | ||||||
|  |     return config.DATABASE_URL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getDatabaseUrl() { | ||||||
|  |     if (process.env.DATABASE_URL) { | ||||||
|  |         logger.info('unleash started with DATABASE_URL'); | ||||||
|  |         return process.env.DATABASE_URL; | ||||||
|  |     } else if (nconf.argv().get('databaseini') !== undefined) { | ||||||
|  |         return getDatabaseIniUrl(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     throw new Error('please set DATABASE_URL or pass --databaseini'); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports =  { | ||||||
|  |     getDatabaseUrl: getDatabaseUrl | ||||||
|  | }; | ||||||
| @ -1,52 +1,9 @@ | |||||||
| var logger = require('../logger'); |  | ||||||
| var nconf  = require('nconf'); |  | ||||||
| var fs     = require('fs'); |  | ||||||
| var ini    = require('ini'); |  | ||||||
| var knex   = require('knex'); | var knex   = require('knex'); | ||||||
| 
 | 
 | ||||||
| function isTestEnv() { | module.exports = function(databaseConnection) { | ||||||
|     return process.env.NODE_ENV === 'test'; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function getDatabaseIniUrl() { |  | ||||||
|     // Finn specific way of delivering env variables
 |  | ||||||
|     var databaseini = nconf.argv().get('databaseini'); |  | ||||||
|     var config = ini.parse(fs.readFileSync(databaseini, 'utf-8')); |  | ||||||
| 
 |  | ||||||
|     logger.info('unleash started with databaseini: ' + databaseini); |  | ||||||
| 
 |  | ||||||
|     return config.DATABASE_URL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function getTestDatabaseUrl() { |  | ||||||
|     if (process.env.TEST_DATABASE_URL) { |  | ||||||
|         logger.info('unleash started with TEST_DATABASE_URL'); |  | ||||||
|         return process.env.TEST_DATABASE_URL; |  | ||||||
|     } else { |  | ||||||
|         throw new Error('please set TEST_DATABASE_URL'); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function getDatabaseUrl() { |  | ||||||
|     if (process.env.DATABASE_URL) { |  | ||||||
|         logger.info('unleash started with DATABASE_URL'); |  | ||||||
|         return process.env.DATABASE_URL; |  | ||||||
|     } else if (nconf.argv().get('databaseini') !== undefined) { |  | ||||||
|         return getDatabaseIniUrl(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     throw new Error('please set DATABASE_URL or pass --databaseini'); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function createDbPool() { |  | ||||||
|     return knex({ |     return knex({ | ||||||
|         client: 'pg', |         client: 'pg', | ||||||
|         connection: isTestEnv() ? getTestDatabaseUrl() : getDatabaseUrl(), |         connection: databaseConnection, | ||||||
|         pool: {  |         pool: { min: 2, max: 20 } | ||||||
|             min: 2,  |  | ||||||
|             max: 20 |  | ||||||
|         } |  | ||||||
|     }); |     }); | ||||||
| } | }; | ||||||
| 
 |  | ||||||
| module.exports = createDbPool(); |  | ||||||
|  | |||||||
| @ -1,43 +1,45 @@ | |||||||
| var knex          = require('./dbPool'); |  | ||||||
| var EVENT_COLUMNS = ['id', 'type', 'created_by', 'created_at', 'data']; | var EVENT_COLUMNS = ['id', 'type', 'created_by', 'created_at', 'data']; | ||||||
| 
 | 
 | ||||||
| function storeEvent(event) { | module.exports = function(db) { | ||||||
|     return knex('events').insert({ |     function storeEvent(event) { | ||||||
|         type: event.type, |         return db('events').insert({ | ||||||
|         created_by: event.createdBy, // eslint-disable-line
 |             type: event.type, | ||||||
|         data: event.data |             created_by: event.createdBy, // eslint-disable-line
 | ||||||
|     }); |             data: event.data | ||||||
| } |         }); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| function getEvents() { |     function getEvents() { | ||||||
|     return knex |         return db | ||||||
|  |             .select(EVENT_COLUMNS) | ||||||
|  |             .from('events') | ||||||
|  |             .orderBy('created_at', 'desc') | ||||||
|  |             .map(rowToEvent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getEventsFilterByName(name) { | ||||||
|  |         return db | ||||||
|         .select(EVENT_COLUMNS) |         .select(EVENT_COLUMNS) | ||||||
|         .from('events') |         .from('events') | ||||||
|  |         .whereRaw("data ->> 'name' = ?", [name]) | ||||||
|         .orderBy('created_at', 'desc') |         .orderBy('created_at', 'desc') | ||||||
|         .map(rowToEvent); |         .map(rowToEvent); | ||||||
| } |     } | ||||||
| 
 | 
 | ||||||
| function getEventsFilterByName(name) { |     function rowToEvent(row) { | ||||||
|     return knex |         return { | ||||||
|       .select(EVENT_COLUMNS) |             id: row.id, | ||||||
|       .from('events') |             type: row.type, | ||||||
|       .whereRaw("data ->> 'name' = ?", [name]) |             createdBy: row.created_by, | ||||||
|       .orderBy('created_at', 'desc') |             createdAt: row.created_at, | ||||||
|       .map(rowToEvent); |             data: row.data | ||||||
| } |         }; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| function rowToEvent(row) { |  | ||||||
|     return { |     return { | ||||||
|         id: row.id, |         store: storeEvent, | ||||||
|         type: row.type, |         getEvents: getEvents, | ||||||
|         createdBy: row.created_by, |         getEventsFilterByName: getEventsFilterByName | ||||||
|         createdAt: row.created_at, |  | ||||||
|         data: row.data |  | ||||||
|     }; |     }; | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = { |  | ||||||
|     store: storeEvent, |  | ||||||
|     getEvents: getEvents, |  | ||||||
|     getEventsFilterByName: getEventsFilterByName |  | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,118 +1,118 @@ | |||||||
| var eventStore      = require('../eventStore'); |  | ||||||
| var eventType       = require('../eventType'); | var eventType       = require('../eventType'); | ||||||
| var logger          = require('../logger'); | var logger          = require('../logger'); | ||||||
| var knex            = require('./dbPool'); |  | ||||||
| var NotFoundError   = require('../error/NotFoundError'); | var NotFoundError   = require('../error/NotFoundError'); | ||||||
| var FEATURE_COLUMNS = ['name', 'description', 'enabled', 'strategy_name', 'parameters']; | var FEATURE_COLUMNS = ['name', 'description', 'enabled', 'strategy_name', 'parameters']; | ||||||
| 
 | 
 | ||||||
| eventStore.on(eventType.featureCreated, function (event) { | module.exports = function(db, eventStore) { | ||||||
|     return createFeature(event.data); |     eventStore.on(eventType.featureCreated, function (event) { | ||||||
| }); |         return createFeature(event.data); | ||||||
|  |     }); | ||||||
| 
 | 
 | ||||||
| eventStore.on(eventType.featureUpdated, function (event) { |     eventStore.on(eventType.featureUpdated, function (event) { | ||||||
|     return updateFeature(event.data); |         return updateFeature(event.data); | ||||||
| }); |     }); | ||||||
| 
 | 
 | ||||||
| eventStore.on(eventType.featureArchived, function (event) { |     eventStore.on(eventType.featureArchived, function (event) { | ||||||
|     return archiveFeature(event.data); |         return archiveFeature(event.data); | ||||||
| }); |     }); | ||||||
| 
 | 
 | ||||||
| eventStore.on(eventType.featureRevived, function (event) { |     eventStore.on(eventType.featureRevived, function (event) { | ||||||
|     return reviveFeature(event.data); |         return reviveFeature(event.data); | ||||||
| }); |     }); | ||||||
| 
 | 
 | ||||||
| function getFeatures() { |     function getFeatures() { | ||||||
|     return knex |         return db | ||||||
|         .select(FEATURE_COLUMNS) |             .select(FEATURE_COLUMNS) | ||||||
|         .from('features') |             .from('features') | ||||||
|         .where({ archived: 0 }) |             .where({ archived: 0 }) | ||||||
|         .orderBy('name', 'asc') |             .orderBy('name', 'asc') | ||||||
|         .map(rowToFeature); |             .map(rowToFeature); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function getFeature(name) { |  | ||||||
|     return knex |  | ||||||
|         .first(FEATURE_COLUMNS) |  | ||||||
|         .from('features') |  | ||||||
|         .where({ name: name }) |  | ||||||
|         .then(rowToFeature); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function getArchivedFeatures() { |  | ||||||
|     return knex |  | ||||||
|         .select(FEATURE_COLUMNS) |  | ||||||
|         .from('features') |  | ||||||
|         .where({ archived: 1 }) |  | ||||||
|         .orderBy('name', 'asc') |  | ||||||
|         .map(rowToFeature); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| function rowToFeature(row) { |  | ||||||
|     if (!row) { |  | ||||||
|         throw new NotFoundError('No feature toggle found'); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     function getFeature(name) { | ||||||
|  |         return db | ||||||
|  |             .first(FEATURE_COLUMNS) | ||||||
|  |             .from('features') | ||||||
|  |             .where({ name: name }) | ||||||
|  |             .then(rowToFeature); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getArchivedFeatures() { | ||||||
|  |         return db | ||||||
|  |             .select(FEATURE_COLUMNS) | ||||||
|  |             .from('features') | ||||||
|  |             .where({ archived: 1 }) | ||||||
|  |             .orderBy('name', 'asc') | ||||||
|  |             .map(rowToFeature); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function rowToFeature(row) { | ||||||
|  |         if (!row) { | ||||||
|  |             throw new NotFoundError('No feature toggle found'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return { | ||||||
|  |             name: row.name, | ||||||
|  |             description: row.description, | ||||||
|  |             enabled: row.enabled > 0, | ||||||
|  |             strategy: row.strategy_name, // eslint-disable-line
 | ||||||
|  |             parameters: row.parameters | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function eventDataToRow(data) { | ||||||
|  |         return { | ||||||
|  |             name: data.name, | ||||||
|  |             description: data.description, | ||||||
|  |             enabled: data.enabled ? 1 : 0, | ||||||
|  |             archived: data.archived ? 1 :0, | ||||||
|  |             strategy_name: data.strategy, // eslint-disable-line
 | ||||||
|  |             parameters: data.parameters | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function createFeature(data) { | ||||||
|  |         return db('features') | ||||||
|  |             .insert(eventDataToRow(data)) | ||||||
|  |             .catch(function (err) { | ||||||
|  |                 logger.error('Could not insert feature, error was: ', err); | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function updateFeature(data) { | ||||||
|  |         return db('features') | ||||||
|  |             .where({ name: data.name }) | ||||||
|  |             .update(eventDataToRow(data)) | ||||||
|  |             .catch(function (err) { | ||||||
|  |                 logger.error('Could not update feature, error was: ', err); | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function archiveFeature(data) { | ||||||
|  |         return db('features') | ||||||
|  |             .where({ name: data.name }) | ||||||
|  |             .update({ archived: 1 }) | ||||||
|  |             .catch(function (err) { | ||||||
|  |                 logger.error('Could not archive feature, error was: ', err); | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function reviveFeature(data) { | ||||||
|  |         return db('features') | ||||||
|  |             .where({ name: data.name }) | ||||||
|  |             .update({ archived: 0, enabled: 0 }) | ||||||
|  |             .catch(function (err) { | ||||||
|  |                 logger.error('Could not archive feature, error was: ', err); | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     return { |     return { | ||||||
|         name: row.name, |         getFeatures: getFeatures, | ||||||
|         description: row.description, |         getFeature: getFeature, | ||||||
|         enabled: row.enabled > 0, |         getArchivedFeatures: getArchivedFeatures, | ||||||
|         strategy: row.strategy_name, // eslint-disable-line
 |         _createFeature: createFeature, // visible for testing
 | ||||||
|         parameters: row.parameters |         _updateFeature: updateFeature  // visible for testing
 | ||||||
|     }; |     }; | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function eventDataToRow(data) { |  | ||||||
|     return { |  | ||||||
|         name: data.name, |  | ||||||
|         description: data.description || '', |  | ||||||
|         enabled: data.enabled ? 1 : 0, |  | ||||||
|         archived: data.archived ? 1 :0, |  | ||||||
|         strategy_name: data.strategy || 'default', // eslint-disable-line
 |  | ||||||
|         parameters: data.parameters || {} |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function createFeature(data) { |  | ||||||
|     return knex('features') |  | ||||||
|         .insert(eventDataToRow(data)) |  | ||||||
|         .catch(function (err) { |  | ||||||
|             logger.error('Could not insert feature, error was: ', err); |  | ||||||
|         }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function updateFeature(data) { |  | ||||||
|     return knex('features') |  | ||||||
|         .where({ name: data.name }) |  | ||||||
|         .update(eventDataToRow(data)) |  | ||||||
|         .catch(function (err) { |  | ||||||
|             logger.error('Could not update feature, error was: ', err); |  | ||||||
|         }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function archiveFeature(data) { |  | ||||||
|     return knex('features') |  | ||||||
|         .where({ name: data.name }) |  | ||||||
|         .update({ archived: 1 }) |  | ||||||
|         .catch(function (err) { |  | ||||||
|             logger.error('Could not archive feature, error was: ', err); |  | ||||||
|         }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function reviveFeature(data) { |  | ||||||
|     return knex('features') |  | ||||||
|         .where({ name: data.name }) |  | ||||||
|         .update({ archived: 0, enabled: 0 }) |  | ||||||
|         .catch(function (err) { |  | ||||||
|             logger.error('Could not archive feature, error was: ', err); |  | ||||||
|         }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| module.exports = { |  | ||||||
|     getFeatures: getFeatures, |  | ||||||
|     getFeature: getFeature, |  | ||||||
|     getArchivedFeatures: getArchivedFeatures, |  | ||||||
|     _createFeature: createFeature, // visible for testing
 |  | ||||||
|     _updateFeature: updateFeature  // visible for testing
 |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,70 +1,70 @@ | |||||||
| var eventStore      = require('../eventStore'); |  | ||||||
| var eventType       = require('../eventType'); | var eventType       = require('../eventType'); | ||||||
| var logger          = require('../logger'); | var logger          = require('../logger'); | ||||||
| var knex            = require('./dbPool'); |  | ||||||
| var NotFoundError   = require('../error/NotFoundError'); | var NotFoundError   = require('../error/NotFoundError'); | ||||||
| var STRATEGY_COLUMNS = ['name', 'description', 'parameters_template']; | var STRATEGY_COLUMNS = ['name', 'description', 'parameters_template']; | ||||||
| 
 | 
 | ||||||
| eventStore.on(eventType.strategyCreated, function (event) { | module.exports = function(db, eventStore) { | ||||||
|     return createStrategy(event.data); |     eventStore.on(eventType.strategyCreated, function (event) { | ||||||
| }); |         return createStrategy(event.data); | ||||||
|  |     }); | ||||||
| 
 | 
 | ||||||
| eventStore.on(eventType.strategyDeleted, function (event) { |     eventStore.on(eventType.strategyDeleted, function (event) { | ||||||
|     knex('strategies') |         db('strategies') | ||||||
|         .where('name', event.data.name) |             .where('name', event.data.name) | ||||||
|         .del() |             .del() | ||||||
|         .catch(function (err) { |             .catch(function (err) { | ||||||
|             logger.error('Could not delete strategy, error was: ', err); |                 logger.error('Could not delete strategy, error was: ', err); | ||||||
|         }); |             }); | ||||||
| }); |     }); | ||||||
| 
 | 
 | ||||||
| function getStrategies() { |     function getStrategies() { | ||||||
|     return knex |         return db | ||||||
|         .select(STRATEGY_COLUMNS) |             .select(STRATEGY_COLUMNS) | ||||||
|         .from('strategies') |             .from('strategies') | ||||||
|         .orderBy('created_at', 'asc') |             .orderBy('created_at', 'asc') | ||||||
|         .map(rowToStrategy); |             .map(rowToStrategy); | ||||||
| } |     } | ||||||
| 
 | 
 | ||||||
| function getStrategy(name) { |     function getStrategy(name) { | ||||||
|     return knex |         return db | ||||||
|         .first(STRATEGY_COLUMNS) |             .first(STRATEGY_COLUMNS) | ||||||
|         .from('strategies') |             .from('strategies') | ||||||
|         .where({ name: name }) |             .where({ name: name }) | ||||||
|         .then(rowToStrategy); |             .then(rowToStrategy); | ||||||
| } |     } | ||||||
| 
 | 
 | ||||||
| function rowToStrategy(row) { |     function rowToStrategy(row) { | ||||||
|     if (!row) { |         if (!row) { | ||||||
|         throw new NotFoundError('No strategy found'); |             throw new NotFoundError('No strategy found'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return { | ||||||
|  |             name: row.name, | ||||||
|  |             description: row.description, | ||||||
|  |             parametersTemplate: row.parameters_template | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function eventDataToRow(data) { | ||||||
|  |         return { | ||||||
|  |             name: data.name, | ||||||
|  |             description: data.description, | ||||||
|  |             parameters_template: data.parametersTemplate // eslint-disable-line
 | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function createStrategy(data) { | ||||||
|  |         db('strategies') | ||||||
|  |             .insert(eventDataToRow(data)) | ||||||
|  |             .catch(function (err) { | ||||||
|  |                 logger.error('Could not insert strategy, error was: ', err); | ||||||
|  |             }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return { |     return { | ||||||
|         name: row.name, |         getStrategies: getStrategies, | ||||||
|         description: row.description, |         getStrategy: getStrategy, | ||||||
|         parametersTemplate: row.parameters_template |         _createStrategy: createStrategy // visible for testing
 | ||||||
|     }; |     }; | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function eventDataToRow(data) { |  | ||||||
|     return { |  | ||||||
|         name: data.name, |  | ||||||
|         description: data.description, |  | ||||||
|         parameters_template: data.parametersTemplate || {} // eslint-disable-line
 |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function createStrategy(data) { |  | ||||||
|     knex('strategies') |  | ||||||
|         .insert(eventDataToRow(data)) |  | ||||||
|         .catch(function (err) { |  | ||||||
|             logger.error('Could not insert strategy, error was: ', err); |  | ||||||
|         }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = { |  | ||||||
|     getStrategies: getStrategies, |  | ||||||
|     getStrategy: getStrategy, |  | ||||||
|     _createStrategy: createStrategy // visible for testing
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,17 +1,17 @@ | |||||||
| var util = require('util'), | var util = require('util'); | ||||||
|     eventDb = require('./db/event'), | var EventEmitter = require('events').EventEmitter; | ||||||
|     EventEmitter = require('events').EventEmitter; |  | ||||||
| 
 | 
 | ||||||
| function EventStore() { | function EventStore(eventDb) { | ||||||
|  |     this.eventDb = eventDb; | ||||||
|     EventEmitter.call(this); |     EventEmitter.call(this); | ||||||
| } | } | ||||||
| util.inherits(EventStore, EventEmitter); | util.inherits(EventStore, EventEmitter); | ||||||
| 
 | 
 | ||||||
| EventStore.prototype.create = function (event) { | EventStore.prototype.create = function (event) { | ||||||
|     var that = this; |     var that = this; | ||||||
|     return eventDb.store(event).then(function() { |     return this.eventDb.store(event).then(function() { | ||||||
|         return that.emit(event.type, event); |         that.emit(event.type, event); | ||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| module.exports = new EventStore(); | module.exports = EventStore; | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| var eventDb     = require('../db/event'); |  | ||||||
| var eventDiffer = require('../eventDiffer'); | var eventDiffer = require('../eventDiffer'); | ||||||
| 
 | 
 | ||||||
| module.exports = function (app) { | module.exports = function (app, config) { | ||||||
|  |     var eventDb = config.eventDb; | ||||||
|  | 
 | ||||||
|     app.get('/events', function (req, res) { |     app.get('/events', function (req, res) { | ||||||
|         eventDb.getEvents().then(function (events) { |         eventDb.getEvents().then(function (events) { | ||||||
|             eventDiffer.addDiffs(events); |             eventDiffer.addDiffs(events); | ||||||
|  | |||||||
| @ -1,11 +1,12 @@ | |||||||
| var logger              = require('../logger'); | var logger              = require('../logger'); | ||||||
| var eventStore          = require('../eventStore'); |  | ||||||
| var eventType           = require('../eventType'); | var eventType           = require('../eventType'); | ||||||
| var featureDb           = require('../db/feature'); |  | ||||||
| var ValidationError     = require('../error/ValidationError'); | var ValidationError     = require('../error/ValidationError'); | ||||||
| var validateRequest     = require('../error/validateRequest'); | var validateRequest     = require('../error/validateRequest'); | ||||||
| 
 | 
 | ||||||
| module.exports = function (app) { | module.exports = function (app, config) { | ||||||
|  |     var featureDb = config.featureDb; | ||||||
|  |     var eventStore = config.eventStore; | ||||||
|  | 
 | ||||||
|     app.get('/archive/features', function (req, res) { |     app.get('/archive/features', function (req, res) { | ||||||
|         featureDb.getArchivedFeatures().then(function (archivedFeatures) { |         featureDb.getArchivedFeatures().then(function (archivedFeatures) { | ||||||
|             res.json({ 'features': archivedFeatures }); |             res.json({ 'features': archivedFeatures }); | ||||||
|  | |||||||
| @ -1,15 +1,16 @@ | |||||||
| var Promise             = require("bluebird"); | var Promise             = require("bluebird"); | ||||||
| var logger              = require('../logger'); | var logger              = require('../logger'); | ||||||
| var eventStore          = require('../eventStore'); |  | ||||||
| var eventType           = require('../eventType'); | var eventType           = require('../eventType'); | ||||||
| var featureDb           = require('../db/feature'); |  | ||||||
| var NameExistsError     = require('../error/NameExistsError'); | var NameExistsError     = require('../error/NameExistsError'); | ||||||
| var NotFoundError       = require('../error/NotFoundError'); | var NotFoundError       = require('../error/NotFoundError'); | ||||||
| var ValidationError     = require('../error/ValidationError'); | var ValidationError     = require('../error/ValidationError'); | ||||||
| var validateRequest     = require('../error/validateRequest'); | var validateRequest     = require('../error/validateRequest'); | ||||||
| var extractUser         = require('../extractUser'); | var extractUser         = require('../extractUser'); | ||||||
| 
 | 
 | ||||||
| module.exports = function (app) { | module.exports = function (app, config) { | ||||||
|  |     var featureDb = config.featureDb; | ||||||
|  |     var eventStore = config.eventStore; | ||||||
|  | 
 | ||||||
|     app.get('/features', function (req, res) { |     app.get('/features', function (req, res) { | ||||||
|         featureDb.getFeatures().then(function (features) { |         featureDb.getFeatures().then(function (features) { | ||||||
|             res.json({ features: features }); |             res.json({ features: features }); | ||||||
|  | |||||||
| @ -1,9 +1,8 @@ | |||||||
| var knex = require('../db/dbPool'); |  | ||||||
| var logger = require('../logger'); | var logger = require('../logger'); | ||||||
| 
 | 
 | ||||||
| module.exports = function (app) { | module.exports = function (app, config) { | ||||||
|     app.get('/health', function (req, res) { |     app.get('/health', function (req, res) { | ||||||
|         knex.select(1) |         config.db.select(1) | ||||||
|             .from('features') |             .from('features') | ||||||
|             .then(function() { |             .then(function() { | ||||||
|                 res.json({ health: 'GOOD' }); |                 res.json({ health: 'GOOD' }); | ||||||
|  | |||||||
| @ -2,10 +2,10 @@ | |||||||
|  * TODO: we should also inject config and |  * TODO: we should also inject config and | ||||||
|  * services to the routes to ease testing. |  * services to the routes to ease testing. | ||||||
| **/ | **/ | ||||||
| exports.create = function (app) { | exports.create = function (app, config) { | ||||||
|     require('./event')(app); |     require('./event')(app, config); | ||||||
|     require('./feature')(app); |     require('./feature')(app, config); | ||||||
|     require('./feature-archive')(app); |     require('./feature-archive')(app, config); | ||||||
|     require('./strategy')(app); |     require('./strategy')(app, config); | ||||||
|     require('./health-check')(app); |     require('./health-check')(app, config); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,7 +1,5 @@ | |||||||
| var Promise             = require("bluebird"); | var Promise             = require("bluebird"); | ||||||
| var eventStore          = require('../eventStore'); |  | ||||||
| var eventType           = require('../eventType'); | var eventType           = require('../eventType'); | ||||||
| var strategyDb          = require('../db/strategy'); |  | ||||||
| var logger              = require('../logger'); | var logger              = require('../logger'); | ||||||
| var NameExistsError     = require('../error/NameExistsError'); | var NameExistsError     = require('../error/NameExistsError'); | ||||||
| var ValidationError     = require('../error/ValidationError'); | var ValidationError     = require('../error/ValidationError'); | ||||||
| @ -9,7 +7,10 @@ var NotFoundError       = require('../error/NotFoundError'); | |||||||
| var validateRequest     = require('../error/validateRequest'); | var validateRequest     = require('../error/validateRequest'); | ||||||
| var extractUser         = require('../extractUser'); | var extractUser         = require('../extractUser'); | ||||||
| 
 | 
 | ||||||
| module.exports = function (app) { | module.exports = function (app, config) { | ||||||
|  |     var strategyDb = config.strategyDb; | ||||||
|  |     var eventStore = config.eventStore; | ||||||
|  | 
 | ||||||
|     app.get('/strategies', function (req, res) { |     app.get('/strategies', function (req, res) { | ||||||
|         strategyDb.getStrategies().then(function (strategies) { |         strategyDb.getStrategies().then(function (strategies) { | ||||||
|             res.json({ strategies: strategies }); |             res.json({ strategies: strategies }); | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								server.js
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								server.js
									
									
									
									
									
								
							| @ -1,8 +1,22 @@ | |||||||
| var logger = require('./lib/logger'); | var logger = require('./lib/logger'); | ||||||
|  | var databaseUri = require('./lib/databaseConfig').getDatabaseUrl(); | ||||||
|  | 
 | ||||||
|  | // Database dependecies (statefull)
 | ||||||
|  | var db = require('./lib/db/dbPool')(databaseUri); | ||||||
|  | var eventDb = require('./lib/db/event')(db); | ||||||
|  | var EventStore = require('./lib/eventStore'); | ||||||
|  | var eventStore = new EventStore(eventDb); | ||||||
|  | var featureDb = require('./lib/db/feature')(db, eventStore); | ||||||
|  | var strategyDb = require('./lib/db/strategy')(db, eventStore); | ||||||
| 
 | 
 | ||||||
| var config = { | var config = { | ||||||
|     baseUriPath: process.env.BASE_URI_PATH || '', |     baseUriPath: process.env.BASE_URI_PATH || '', | ||||||
|     port: process.env.HTTP_PORT || process.env.PORT || 4242 |     port: process.env.HTTP_PORT || process.env.PORT || 4242, | ||||||
|  |     db: db, | ||||||
|  |     eventDb: eventDb, | ||||||
|  |     eventStore: eventStore, | ||||||
|  |     featureDb: featureDb, | ||||||
|  |     strategyDb: strategyDb | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| var app = require('./app')(config); | var app = require('./app')(config); | ||||||
| @ -25,7 +39,6 @@ if (app.get('env') === 'development') { | |||||||
|     })); |     })); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| process.on('uncaughtException', function(err) { | process.on('uncaughtException', function(err) { | ||||||
|     logger.error('Uncaught Exception:', err.message); |     logger.error('Uncaught Exception:', err.message); | ||||||
|     logger.error(err.stack); |     logger.error(err.stack); | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								test/databaseConfig.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								test/databaseConfig.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | 'use strict'; | ||||||
|  | function getDatabaseUri() { | ||||||
|  |     if (!process.env.TEST_DATABASE_URL) { | ||||||
|  |         throw new Error('please set TEST_DATABASE_URL'); | ||||||
|  |     } else { | ||||||
|  |         return process.env.TEST_DATABASE_URL; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | module.exports = { | ||||||
|  |     getDatabaseUri: getDatabaseUri | ||||||
|  | }; | ||||||
| @ -1,4 +1,5 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  | var logger = require('../lib/logger'); | ||||||
| var assert     = require('assert'); | var assert     = require('assert'); | ||||||
| var specHelper = require('./specHelper'); | var specHelper = require('./specHelper'); | ||||||
| var request    = specHelper.request; | var request    = specHelper.request; | ||||||
| @ -32,6 +33,7 @@ describe('The features api', function () { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('cant get feature that dose not exist', function (done) { |     it('cant get feature that dose not exist', function (done) { | ||||||
|  |         logger.setLevel('FATAL'); | ||||||
|         request |         request | ||||||
|             .get('/features/myfeature') |             .get('/features/myfeature') | ||||||
|             .expect('Content-Type', /json/) |             .expect('Content-Type', /json/) | ||||||
| @ -47,6 +49,7 @@ describe('The features api', function () { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('creates new feature toggle with createdBy', function (done) { |     it('creates new feature toggle with createdBy', function (done) { | ||||||
|  |         logger.setLevel('FATAL'); | ||||||
|         request |         request | ||||||
|             .post('/features') |             .post('/features') | ||||||
|             .send({ name: 'com.test.Username', enabled: false }) |             .send({ name: 'com.test.Username', enabled: false }) | ||||||
| @ -63,6 +66,7 @@ describe('The features api', function () { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('require new feature toggle to have a name', function (done) { |     it('require new feature toggle to have a name', function (done) { | ||||||
|  |         logger.setLevel('FATAL'); | ||||||
|         request |         request | ||||||
|             .post('/features') |             .post('/features') | ||||||
|             .send({ name: '' }) |             .send({ name: '' }) | ||||||
| @ -71,6 +75,7 @@ describe('The features api', function () { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('can not change status of feature toggle that does not exist', function (done) { |     it('can not change status of feature toggle that does not exist', function (done) { | ||||||
|  |         logger.setLevel('FATAL'); | ||||||
|         request |         request | ||||||
|             .put('/features/should-not-exist') |             .put('/features/should-not-exist') | ||||||
|             .send({ name: 'should-not-exist', enabled: false }) |             .send({ name: 'should-not-exist', enabled: false }) | ||||||
| @ -79,6 +84,7 @@ describe('The features api', function () { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('can change status of feature toggle that does exist', function (done) { |     it('can change status of feature toggle that does exist', function (done) { | ||||||
|  |         logger.setLevel('FATAL'); | ||||||
|         request |         request | ||||||
|             .put('/features/featureY') |             .put('/features/featureY') | ||||||
|             .send({ name: 'featureY', enabled: true }) |             .send({ name: 'featureY', enabled: true }) | ||||||
|  | |||||||
| @ -3,10 +3,22 @@ process.env.NODE_ENV = 'test'; | |||||||
| 
 | 
 | ||||||
| var Promise = require('bluebird'); | var Promise = require('bluebird'); | ||||||
| var request = require('supertest'); | var request = require('supertest'); | ||||||
| var app = require('../app')({ baseUriPath: '' }); | var databaseUri = require('./databaseConfig').getDatabaseUri(); | ||||||
| var knex = require('../lib/db/dbPool'); | var knex = require('../lib/db/dbPool')(databaseUri); | ||||||
| var featureDb = require('../lib/db/feature'); | var eventDb = require('../lib/db/event')(knex); | ||||||
| var strategyDb = require('../lib/db/strategy'); | var EventStore = require('../lib/eventStore'); | ||||||
|  | var eventStore = new EventStore(eventDb); | ||||||
|  | var featureDb = require('../lib/db/feature')(knex, eventStore); | ||||||
|  | var strategyDb = require('../lib/db/strategy')(knex, eventStore); | ||||||
|  | 
 | ||||||
|  | var app = require('../app')({ | ||||||
|  |     baseUriPath: '', | ||||||
|  |     db: knex, | ||||||
|  |     eventDb: eventDb, | ||||||
|  |     eventStore: eventStore, | ||||||
|  |     featureDb: featureDb, | ||||||
|  |     strategyDb: strategyDb | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| Promise.promisifyAll(request); | Promise.promisifyAll(request); | ||||||
| request = request(app); | request = request(app); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user