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
							
								
									066fe5fdd2
								
							
						
					
					
						commit
						3a6e7d02ef
					
				@ -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,8 +23,20 @@ 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();
 | 
				
			||||||
 | 
					        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);
 | 
					                res.json(seenApps);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    app.get('/client/metrics/feature-toggles', (req, res) => {
 | 
					    app.get('/client/metrics/feature-toggles', (req, res) => {
 | 
				
			||||||
        res.json(metrics.getTogglesMetrics());
 | 
					        res.json(metrics.getTogglesMetrics());
 | 
				
			||||||
@ -99,20 +112,36 @@ module.exports = function (app, config) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    app.get('/client/applications/', (req, res) => {
 | 
					    app.post('/client/applications/:appName', (req, res) => {
 | 
				
			||||||
        const strategyName = req.query.strategyName;
 | 
					        const input = Object.assign({}, req.body, {
 | 
				
			||||||
        let appsPromise;
 | 
					            appName: req.params.appName,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        clientApplicationsStore
 | 
				
			||||||
 | 
					            .upsert(input)
 | 
				
			||||||
 | 
					            .then(() => res.status(202).end())
 | 
				
			||||||
 | 
					            .catch((e) => {
 | 
				
			||||||
 | 
					                logger.error(e);
 | 
				
			||||||
 | 
					                res.status(500).end();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (strategyName) {
 | 
					    function toLookup (metaData) {
 | 
				
			||||||
            appsPromise = clientStrategyStore.getAppsForStrategy(strategyName);
 | 
					        return metaData.reduce((result, entry) => {
 | 
				
			||||||
        } else {
 | 
					            result[entry.appName] = entry;
 | 
				
			||||||
            appsPromise = clientStrategyStore.getApplications();
 | 
					            return result;
 | 
				
			||||||
 | 
					        }, {});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        appsPromise
 | 
					    app.get('/client/applications/', (req, res) => {
 | 
				
			||||||
            .then(apps => {
 | 
					        const strategyName = req.query.strategyName;
 | 
				
			||||||
                const applications = apps.map(appName => ({
 | 
					        Promise.all([
 | 
				
			||||||
 | 
					            strategyName ? clientStrategyStore.getAppsForStrategy(strategyName) : clientStrategyStore.getApplications(),
 | 
				
			||||||
 | 
					            clientApplicationsStore.getApplicationMetaData().then(toLookup),
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					        .then(([apps, metaData]) => {
 | 
				
			||||||
 | 
					            const applications = apps.map(({ appName }) => ({
 | 
				
			||||||
                appName,
 | 
					                appName,
 | 
				
			||||||
 | 
					                data: metaData[appName],
 | 
				
			||||||
                links: {
 | 
					                links: {
 | 
				
			||||||
                    appDetails: `/api/client/applications/${appName}`,
 | 
					                    appDetails: `/api/client/applications/${appName}`,
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@ -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