mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
client applications
This commit is contained in:
parent
baf2c62f25
commit
80d3f5be1c
@ -54,7 +54,7 @@ module.exports = class UnleashClientMetrics {
|
||||
if (!toggles[seenToggleName]) {
|
||||
toggles[seenToggleName] = [];
|
||||
}
|
||||
toggles[seenToggleName].push(appName);
|
||||
toggles[seenToggleName].push({ appName });
|
||||
});
|
||||
});
|
||||
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 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),
|
||||
|
@ -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));
|
||||
});
|
||||
};
|
||||
|
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