mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	client applications
This commit is contained in:
		
							parent
							
								
									baf2c62f25
								
							
						
					
					
						commit
						80d3f5be1c
					
				| @ -54,7 +54,7 @@ module.exports = class UnleashClientMetrics { | |||||||
|                 if (!toggles[seenToggleName]) { |                 if (!toggles[seenToggleName]) { | ||||||
|                     toggles[seenToggleName] = []; |                     toggles[seenToggleName] = []; | ||||||
|                 } |                 } | ||||||
|                 toggles[seenToggleName].push(appName); |                 toggles[seenToggleName].push({ appName }); | ||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
|         return toggles; |         return toggles; | ||||||
|  | |||||||
							
								
								
									
										74
									
								
								lib/db/client-applications-store.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								lib/db/client-applications-store.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const COLUMNS = ['app_name', 'created_at', 'updated_at', 'description', 'url', 'color', 'icon']; | ||||||
|  | const TABLE = 'client_applications'; | ||||||
|  | 
 | ||||||
|  | const mapRow = (row) => ({ | ||||||
|  |     appName: row.app_name, | ||||||
|  |     createdAt: row.created_at, | ||||||
|  |     updatedAt: row.updated_at, | ||||||
|  |     description: row.description, | ||||||
|  |     url: row.url, | ||||||
|  |     color: row.color, | ||||||
|  |     icon: row.icon, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const remapRow = (input, old = {}) => ({ | ||||||
|  |     app_name: input.appName, | ||||||
|  |     updated_at: input.updatedAt, | ||||||
|  |     description: input.description || old.description, | ||||||
|  |     url: input.url || old.url, | ||||||
|  |     color: input.color || old.color, | ||||||
|  |     icon: input.icon || old.icon, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ClientApplicationsDb { | ||||||
|  |     constructor (db) { | ||||||
|  |         this.db = db; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     updateRow (details, prev) { | ||||||
|  |         details.updatedAt = 'now()'; | ||||||
|  |         return this.db(TABLE) | ||||||
|  |             .where('app_name', details.appName) | ||||||
|  |             .update(remapRow(details, prev)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     insertNewRow (details) { | ||||||
|  |         return this.db(TABLE).insert(remapRow(details)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     upsert (data) { | ||||||
|  |         if (!data) { | ||||||
|  |             throw new Error('Missing data to add / update'); | ||||||
|  |         } | ||||||
|  |         return this.db(TABLE) | ||||||
|  |             .select(COLUMNS) | ||||||
|  |             .where('app_name', data.appName) | ||||||
|  |             .then(result => { | ||||||
|  |                 if (result && result[0]) { | ||||||
|  |                     return this.updateRow(data, result[0]); | ||||||
|  |                 } else { | ||||||
|  |                     return this.insertNewRow(data); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     getApplicationMetaData (appName) { | ||||||
|  |         if (appName) { | ||||||
|  |             return this.db | ||||||
|  |                 .select(COLUMNS) | ||||||
|  |                 .where('app_name', appName) | ||||||
|  |                 .from(TABLE) | ||||||
|  |                 .map(mapRow); | ||||||
|  |         } | ||||||
|  |         return this.db | ||||||
|  |             .select(COLUMNS) | ||||||
|  |             .from(TABLE) | ||||||
|  |             .orderBy('created_at', 'asc') | ||||||
|  |             .map(mapRow); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | module.exports = ClientApplicationsDb; | ||||||
| @ -8,6 +8,7 @@ const ClientInstanceStore = require('./client-instance-store'); | |||||||
| const ClientMetricsDb = require('./client-metrics-db'); | const ClientMetricsDb = require('./client-metrics-db'); | ||||||
| const ClientMetricsStore = require('./client-metrics-store'); | const ClientMetricsStore = require('./client-metrics-store'); | ||||||
| const ClientStrategyStore = require('./client-strategy-store'); | const ClientStrategyStore = require('./client-strategy-store'); | ||||||
|  | const ClientApplicationsStore = require('./client-applications-store'); | ||||||
| 
 | 
 | ||||||
| module.exports.createStores = (config) => { | module.exports.createStores = (config) => { | ||||||
|     const db = createDb(config); |     const db = createDb(config); | ||||||
| @ -19,6 +20,7 @@ module.exports.createStores = (config) => { | |||||||
|         eventStore, |         eventStore, | ||||||
|         featureToggleStore: new FeatureToggleStore(db, eventStore), |         featureToggleStore: new FeatureToggleStore(db, eventStore), | ||||||
|         strategyStore: new StrategyStore(db, eventStore), |         strategyStore: new StrategyStore(db, eventStore), | ||||||
|  |         clientApplicationsStore: new ClientApplicationsStore(db), | ||||||
|         clientInstanceStore: new ClientInstanceStore(db), |         clientInstanceStore: new ClientInstanceStore(db), | ||||||
|         clientMetricsStore: new ClientMetricsStore(clientMetricsDb), |         clientMetricsStore: new ClientMetricsStore(clientMetricsDb), | ||||||
|         clientStrategyStore: new ClientStrategyStore(db), |         clientStrategyStore: new ClientStrategyStore(db), | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ module.exports = function (app, config) { | |||||||
|         clientMetricsStore, |         clientMetricsStore, | ||||||
|         clientStrategyStore, |         clientStrategyStore, | ||||||
|         clientInstanceStore, |         clientInstanceStore, | ||||||
|  |         clientApplicationsStore, | ||||||
|     } = config.stores; |     } = config.stores; | ||||||
| 
 | 
 | ||||||
|     const metrics = new ClientMetrics(clientMetricsStore); |     const metrics = new ClientMetrics(clientMetricsStore); | ||||||
| @ -22,7 +23,19 @@ module.exports = function (app, config) { | |||||||
| 
 | 
 | ||||||
|     app.get('/client/seen-apps', (req, res) => { |     app.get('/client/seen-apps', (req, res) => { | ||||||
|         const seenApps = metrics.getSeenAppsPerToggle(); |         const seenApps = metrics.getSeenAppsPerToggle(); | ||||||
|         res.json(seenApps); |         clientApplicationsStore.getApplicationMetaData() | ||||||
|  |             .then(toLookup) | ||||||
|  |             .then(metaData => { | ||||||
|  |                 Object.keys(seenApps).forEach(key => { | ||||||
|  |                     seenApps[key] = seenApps[key].map(entry => { | ||||||
|  |                         if (metaData[entry.appName]) { | ||||||
|  |                             entry.data = metaData[entry.appName]; | ||||||
|  |                         } | ||||||
|  |                         return entry; | ||||||
|  |                     }); | ||||||
|  |                 }); | ||||||
|  |                 res.json(seenApps); | ||||||
|  |             }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     app.get('/client/metrics/feature-toggles', (req, res) => { |     app.get('/client/metrics/feature-toggles', (req, res) => { | ||||||
| @ -99,27 +112,43 @@ module.exports = function (app, config) { | |||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  |     app.post('/client/applications/:appName', (req, res) => { | ||||||
|  |         const input = Object.assign({}, req.body, { | ||||||
|  |             appName: req.params.appName, | ||||||
|  |         }); | ||||||
|  |         clientApplicationsStore | ||||||
|  |             .upsert(input) | ||||||
|  |             .then(() => res.status(202).end()) | ||||||
|  |             .catch((e) => { | ||||||
|  |                 logger.error(e); | ||||||
|  |                 res.status(500).end(); | ||||||
|  |             }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     function toLookup (metaData) { | ||||||
|  |         return metaData.reduce((result, entry) => { | ||||||
|  |             result[entry.appName] = entry; | ||||||
|  |             return result; | ||||||
|  |         }, {}); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     app.get('/client/applications/', (req, res) => { |     app.get('/client/applications/', (req, res) => { | ||||||
|         const strategyName = req.query.strategyName; |         const strategyName = req.query.strategyName; | ||||||
|         let appsPromise; |         Promise.all([ | ||||||
| 
 |             strategyName ? clientStrategyStore.getAppsForStrategy(strategyName) : clientStrategyStore.getApplications(), | ||||||
|         if (strategyName) { |             clientApplicationsStore.getApplicationMetaData().then(toLookup), | ||||||
|             appsPromise = clientStrategyStore.getAppsForStrategy(strategyName); |         ]) | ||||||
|         } else { |         .then(([apps, metaData]) => { | ||||||
|             appsPromise = clientStrategyStore.getApplications(); |             const applications = apps.map(({ appName }) => ({ | ||||||
|         } |                 appName, | ||||||
| 
 |                 data: metaData[appName], | ||||||
|         appsPromise |                 links: { | ||||||
|             .then(apps => { |                     appDetails: `/api/client/applications/${appName}`, | ||||||
|                 const applications = apps.map(appName => ({ |                 }, | ||||||
|                     appName, |             })); | ||||||
|                     links: { |             res.json({ applications }); | ||||||
|                         appDetails: `/api/client/applications/${appName}`, |         }) | ||||||
|                     }, |         .catch(err => catchLogAndSendErrorResponse(err, res)); | ||||||
|                 })); |  | ||||||
|                 res.json({ applications }); |  | ||||||
|             }) |  | ||||||
|             .catch(err => catchLogAndSendErrorResponse(err, res)); |  | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     app.get('/client/applications/:appName', (req, res) => { |     app.get('/client/applications/:appName', (req, res) => { | ||||||
| @ -128,8 +157,11 @@ module.exports = function (app, config) { | |||||||
|         Promise.all([ |         Promise.all([ | ||||||
|             clientInstanceStore.getByAppName(appName), |             clientInstanceStore.getByAppName(appName), | ||||||
|             clientStrategyStore.getByAppName(appName), |             clientStrategyStore.getByAppName(appName), | ||||||
|  |             clientApplicationsStore.getApplicationMetaData(appName), | ||||||
|         ]) |         ]) | ||||||
|             .then(([instances, strategies]) => res.json({ appName, instances, strategies, seenToggles })) |             .then(([instances, strategies, [metaData]]) => | ||||||
|  |                 res.json({ appName, instances, strategies, seenToggles, data: metaData }) | ||||||
|  |             ) | ||||||
|             .catch(err => catchLogAndSendErrorResponse(err, res)); |             .catch(err => catchLogAndSendErrorResponse(err, res)); | ||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								migrations/20161205203516-create-client-applications.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								migrations/20161205203516-create-client-applications.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | module.exports = require('../scripts/migration-runner').create('011-create-client-applications'); | ||||||
							
								
								
									
										1
									
								
								migrations/sql/011-create-client-applications.down.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								migrations/sql/011-create-client-applications.down.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | DROP TABLE client_applications; | ||||||
							
								
								
									
										9
									
								
								migrations/sql/011-create-client-applications.up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								migrations/sql/011-create-client-applications.up.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | CREATE TABLE client_applications ( | ||||||
|  |   app_name varchar(255) PRIMARY KEY NOT NULL, | ||||||
|  |   created_at timestamp default now(), | ||||||
|  |   updated_at timestamp default now(), | ||||||
|  |   description varchar(255), | ||||||
|  |   icon varchar(255), | ||||||
|  |   url varchar(255), | ||||||
|  |   color varchar(255) | ||||||
|  | ); | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user