diff --git a/packages/unleash-api/lib/client-metrics/index.js b/packages/unleash-api/lib/client-metrics/index.js index c432c32097..c3f0261818 100644 --- a/packages/unleash-api/lib/client-metrics/index.js +++ b/packages/unleash-api/lib/client-metrics/index.js @@ -8,7 +8,6 @@ module.exports = class UnleashClientMetrics { this.globalCount = 0; this.apps = {}; this.clients = {}; - this.strategies = {}; this.buckets = {}; this.hourProjectionValue = new Projection(); @@ -29,7 +28,6 @@ module.exports = class UnleashClientMetrics { globalCount: this.globalCount, apps: this.apps, clients: this.clients, - strategies: this.strategies, }; } @@ -37,11 +35,6 @@ module.exports = class UnleashClientMetrics { return this.hourProjectionValue.getProjection(); } - registerClient (data) { - this.addClient(data.appName, data.instanceId, data.started); - this.addStrategies(data.appName, data.strategies); - } - addPayload (data) { this.addClient(data.appName, data.instanceId); this.addBucket(data.appName, data.instanceId, data.bucket); @@ -63,15 +56,6 @@ module.exports = class UnleashClientMetrics { this.addClientCount(appName, instanceId, count); } - addStrategies (appName, strategyNames) { - strategyNames.forEach((name) => { - if (!this.strategies[name]) { - this.strategies[name] = {}; - } - this.strategies[name][appName] = true; - }); - } - addClientCount (appName, instanceId, count) { if (typeof count === 'number' && count > 0) { this.globalCount += count; diff --git a/packages/unleash-api/lib/db/client-instances.js b/packages/unleash-api/lib/db/client-instances.js index 6cbab6ccdf..b69805390b 100644 --- a/packages/unleash-api/lib/db/client-instances.js +++ b/packages/unleash-api/lib/db/client-instances.js @@ -43,6 +43,7 @@ module.exports = function (db) { return db .select(COLUMNS) .from(TABLE) + .orderBy('last_seen', 'desc') .map(mapRow); } diff --git a/packages/unleash-api/lib/db/client-strategies.js b/packages/unleash-api/lib/db/client-strategies.js index 262b810828..0543c942d8 100644 --- a/packages/unleash-api/lib/db/client-strategies.js +++ b/packages/unleash-api/lib/db/client-strategies.js @@ -4,7 +4,7 @@ const COLUMNS = ['app_name', 'strategies']; const TABLE = 'client_strategies'; module.exports = function (db) { - function update (appName, strategies) { + function updateRow (appName, strategies) { return db(TABLE) .where('app_name', appName) // eslint-disable-line .update({ @@ -13,23 +13,23 @@ module.exports = function (db) { }); } - function insert (appName, strategies) { + function insertNewRow (appName, strategies) { return db(TABLE).insert({ app_name: appName, // eslint-disable-line strategies: JSON.stringify(strategies), }); } - function insertOrUpdate (appName, strategies) { + function insert (appName, strategies) { return db(TABLE) .count('*') .where('app_name', appName) .map(row => ({ count: row.count })) .then(rows => { if (rows[0].count > 0) { - return update(appName, strategies); + return updateRow(appName, strategies); } else { - return insert(appName, strategies); + return insertNewRow(appName, strategies); } }); } @@ -48,5 +48,5 @@ module.exports = function (db) { }; } - return { insertOrUpdate, getAll }; + return { insert, getAll }; }; diff --git a/packages/unleash-api/lib/routes/metrics.js b/packages/unleash-api/lib/routes/metrics.js index 5ccc808e96..acc441813a 100644 --- a/packages/unleash-api/lib/routes/metrics.js +++ b/packages/unleash-api/lib/routes/metrics.js @@ -5,14 +5,14 @@ const ClientMetrics = require('../client-metrics'); const ClientMetricsService = require('../client-metrics/service'); module.exports = function (app, config) { - const { clientMetricsDb, clientStrategiesDb } = config; + const { + clientMetricsDb, + clientStrategiesDb, + clientInstancesDb, + } = config; const metrics = new ClientMetrics(); const service = new ClientMetricsService(clientMetricsDb); - // Just som dummo demo data - clientStrategiesDb.insertOrUpdate('demo-app', ['default', 'test']).then(() => console.log('inserted client_strategies')); - - service.on('metrics', (entries) => { entries.forEach((m) => { metrics.addPayload(m.metrics); @@ -41,12 +41,15 @@ module.exports = function (app, config) { }); app.post('/client/register', (req, res) => { - try { - const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body; - metrics.registerClient(data); - } catch (e) { - logger.error('Error registering client', e); - } + const data = req.body; + clientStrategiesDb.insert(data.appName, data.strategies) + .then(() => clientInstancesDb.insert({ + appName: data.appName, + instanceId: data.instanceId, + clientIp: req.ip, + })) + .then(() => console.log('new client registerd')) + .catch((error) => logger.error('Error registering client', error)); res.end(); }); @@ -54,4 +57,10 @@ module.exports = function (app, config) { app.get('/client/strategies', (req, res) => { clientStrategiesDb.getAll().then(data => res.json(data)); }); + + app.get('/client/instances', (req, res) => { + clientInstancesDb.getAll() + .then(data => res.json(data)) + .catch(err => console.error(err)); + }); }; diff --git a/packages/unleash-frontend-next/src/component/client-instance/client-instance-component.js b/packages/unleash-frontend-next/src/component/client-instance/client-instance-component.js new file mode 100644 index 0000000000..6d22b39433 --- /dev/null +++ b/packages/unleash-frontend-next/src/component/client-instance/client-instance-component.js @@ -0,0 +1,38 @@ +import React, { Component, PropTypes } from 'react'; +import Table from 'react-toolbox/lib/table'; + +const Model = { + appName: { type: String, title: 'Application Name' }, + instanceId: { type: String }, + clientIp: { type: String }, + createdAt: { type: String }, + lastSeen: { type: String }, +}; + +class ClientStrategies extends Component { + static propTypes () { + return { + fetchClientInstances: PropTypes.func.isRequired, + clientInstances: PropTypes.array.isRequired, + }; + } + + componentDidMount () { + this.props.fetchClientInstances(); + } + + render () { + const source = this.props.clientInstances; + + return ( + + ); + } +} + + +export default ClientStrategies; diff --git a/packages/unleash-frontend-next/src/component/client-instance/client-instance-container.js b/packages/unleash-frontend-next/src/component/client-instance/client-instance-container.js new file mode 100644 index 0000000000..4c13df8eab --- /dev/null +++ b/packages/unleash-frontend-next/src/component/client-instance/client-instance-container.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import ClientInstances from './client-instance-component'; +import { fetchClientInstances } from '../../store/client-instance-actions'; + +const mapStateToProps = (state) => ({ clientInstances: state.clientInstances.toJS() }); + +const StrategiesContainer = connect(mapStateToProps, { fetchClientInstances })(ClientInstances); + +export default StrategiesContainer; diff --git a/packages/unleash-frontend-next/src/data/client-instance-api.js b/packages/unleash-frontend-next/src/data/client-instance-api.js new file mode 100644 index 0000000000..bb56fd43a2 --- /dev/null +++ b/packages/unleash-frontend-next/src/data/client-instance-api.js @@ -0,0 +1,13 @@ +import { throwIfNotSuccess, headers } from './helper'; + +const URI = '/client/instances'; + +function fetchAll () { + return fetch(URI, { headers }) + .then(throwIfNotSuccess) + .then(response => response.json()); +} + +module.exports = { + fetchAll, +}; diff --git a/packages/unleash-frontend-next/src/page/client-instances/index.js b/packages/unleash-frontend-next/src/page/client-instances/index.js index 604f719047..75b27b52da 100644 --- a/packages/unleash-frontend-next/src/page/client-instances/index.js +++ b/packages/unleash-frontend-next/src/page/client-instances/index.js @@ -1,6 +1,6 @@ import React from 'react'; -import ClientStrategy from '../../component/client-strategy/strategy-container'; +import ClientInstance from '../../component/client-instance/client-instance-container'; -const render = () => ; +const render = () => ; export default render; diff --git a/packages/unleash-frontend-next/src/store/client-instance-actions.js b/packages/unleash-frontend-next/src/store/client-instance-actions.js new file mode 100644 index 0000000000..03de9edcf5 --- /dev/null +++ b/packages/unleash-frontend-next/src/store/client-instance-actions.js @@ -0,0 +1,20 @@ +import api from '../data/client-instance-api'; + +export const RECEIVE_CLIENT_INSTANCES = 'RECEIVE_CLIENT_INSTANCES'; +export const ERROR_RECEIVE_CLIENT_INSTANCES = 'ERROR_RECEIVE_CLIENT_INSTANCES'; + +const receiveClientInstances = (json) => ({ + type: RECEIVE_CLIENT_INSTANCES, + value: json, +}); + +const errorReceiveClientInstances = (statusCode) => ({ + type: RECEIVE_CLIENT_INSTANCES, + statusCode, +}); + +export function fetchClientInstances () { + return dispatch => api.fetchAll() + .then(json => dispatch(receiveClientInstances(json))) + .catch(error => dispatch(errorReceiveClientInstances(error))); +} diff --git a/packages/unleash-frontend-next/src/store/client-instance-store.js b/packages/unleash-frontend-next/src/store/client-instance-store.js new file mode 100644 index 0000000000..d075fbf841 --- /dev/null +++ b/packages/unleash-frontend-next/src/store/client-instance-store.js @@ -0,0 +1,17 @@ +import { fromJS } from 'immutable'; +import { RECEIVE_CLIENT_INSTANCES } from './client-instance-actions'; + +function getInitState () { + return fromJS([]); +} + +const store = (state = getInitState(), action) => { + switch (action.type) { + case RECEIVE_CLIENT_INSTANCES: + return fromJS(action.value); + default: + return state; + } +}; + +export default store; diff --git a/packages/unleash-frontend-next/src/store/index.js b/packages/unleash-frontend-next/src/store/index.js index c440251a93..c073cdb738 100644 --- a/packages/unleash-frontend-next/src/store/index.js +++ b/packages/unleash-frontend-next/src/store/index.js @@ -7,6 +7,7 @@ import archive from './archive-store'; import error from './error-store'; import metrics from './metrics-store'; import clientStrategies from './client-strategy-store'; +import clientInstances from './client-instance-store'; const unleashStore = combineReducers({ features, @@ -17,6 +18,7 @@ const unleashStore = combineReducers({ error, metrics, clientStrategies, + clientInstances, }); export default unleashStore; diff --git a/packages/unleash-frontend-next/webpack.config.js b/packages/unleash-frontend-next/webpack.config.js index 2d422fd471..b3d338f878 100644 --- a/packages/unleash-frontend-next/webpack.config.js +++ b/packages/unleash-frontend-next/webpack.config.js @@ -77,7 +77,7 @@ module.exports = { target: 'http://localhost:4242', secure: false, }, - '/client/strategies': { + '/client': { target: 'http://localhost:4242', secure: false, },