1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

client applications

This commit is contained in:
sveisvei 2016-12-06 09:19:15 +01:00 committed by ivaosthu
parent baf2c62f25
commit 80d3f5be1c
7 changed files with 143 additions and 22 deletions

View File

@ -54,7 +54,7 @@ module.exports = class UnleashClientMetrics {
if (!toggles[seenToggleName]) {
toggles[seenToggleName] = [];
}
toggles[seenToggleName].push(appName);
toggles[seenToggleName].push({ appName });
});
});
return toggles;

View 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;

View File

@ -8,6 +8,7 @@ const ClientInstanceStore = require('./client-instance-store');
const ClientMetricsDb = require('./client-metrics-db');
const ClientMetricsStore = require('./client-metrics-store');
const ClientStrategyStore = require('./client-strategy-store');
const ClientApplicationsStore = require('./client-applications-store');
module.exports.createStores = (config) => {
const db = createDb(config);
@ -19,6 +20,7 @@ module.exports.createStores = (config) => {
eventStore,
featureToggleStore: new FeatureToggleStore(db, eventStore),
strategyStore: new StrategyStore(db, eventStore),
clientApplicationsStore: new ClientApplicationsStore(db),
clientInstanceStore: new ClientInstanceStore(db),
clientMetricsStore: new ClientMetricsStore(clientMetricsDb),
clientStrategyStore: new ClientStrategyStore(db),

View File

@ -11,6 +11,7 @@ module.exports = function (app, config) {
clientMetricsStore,
clientStrategyStore,
clientInstanceStore,
clientApplicationsStore,
} = config.stores;
const metrics = new ClientMetrics(clientMetricsStore);
@ -22,7 +23,19 @@ module.exports = function (app, config) {
app.get('/client/seen-apps', (req, res) => {
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) => {
@ -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) => {
const strategyName = req.query.strategyName;
let appsPromise;
if (strategyName) {
appsPromise = clientStrategyStore.getAppsForStrategy(strategyName);
} else {
appsPromise = clientStrategyStore.getApplications();
}
appsPromise
.then(apps => {
const applications = apps.map(appName => ({
appName,
links: {
appDetails: `/api/client/applications/${appName}`,
},
}));
res.json({ applications });
})
.catch(err => catchLogAndSendErrorResponse(err, res));
Promise.all([
strategyName ? clientStrategyStore.getAppsForStrategy(strategyName) : clientStrategyStore.getApplications(),
clientApplicationsStore.getApplicationMetaData().then(toLookup),
])
.then(([apps, metaData]) => {
const applications = apps.map(({ appName }) => ({
appName,
data: metaData[appName],
links: {
appDetails: `/api/client/applications/${appName}`,
},
}));
res.json({ applications });
})
.catch(err => catchLogAndSendErrorResponse(err, res));
});
app.get('/client/applications/:appName', (req, res) => {
@ -128,8 +157,11 @@ module.exports = function (app, config) {
Promise.all([
clientInstanceStore.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));
});
};

View File

@ -0,0 +1,3 @@
'use strict';
module.exports = require('../scripts/migration-runner').create('011-create-client-applications');

View File

@ -0,0 +1 @@
DROP TABLE client_applications;

View 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)
);