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

Added view for client-instances

This commit is contained in:
ivaosthu 2016-11-04 23:02:55 +01:00
parent 5f6b118fd7
commit 9eb365b512
12 changed files with 129 additions and 36 deletions

View File

@ -8,7 +8,6 @@ module.exports = class UnleashClientMetrics {
this.globalCount = 0; this.globalCount = 0;
this.apps = {}; this.apps = {};
this.clients = {}; this.clients = {};
this.strategies = {};
this.buckets = {}; this.buckets = {};
this.hourProjectionValue = new Projection(); this.hourProjectionValue = new Projection();
@ -29,7 +28,6 @@ module.exports = class UnleashClientMetrics {
globalCount: this.globalCount, globalCount: this.globalCount,
apps: this.apps, apps: this.apps,
clients: this.clients, clients: this.clients,
strategies: this.strategies,
}; };
} }
@ -37,11 +35,6 @@ module.exports = class UnleashClientMetrics {
return this.hourProjectionValue.getProjection(); return this.hourProjectionValue.getProjection();
} }
registerClient (data) {
this.addClient(data.appName, data.instanceId, data.started);
this.addStrategies(data.appName, data.strategies);
}
addPayload (data) { addPayload (data) {
this.addClient(data.appName, data.instanceId); this.addClient(data.appName, data.instanceId);
this.addBucket(data.appName, data.instanceId, data.bucket); this.addBucket(data.appName, data.instanceId, data.bucket);
@ -63,15 +56,6 @@ module.exports = class UnleashClientMetrics {
this.addClientCount(appName, instanceId, count); 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) { addClientCount (appName, instanceId, count) {
if (typeof count === 'number' && count > 0) { if (typeof count === 'number' && count > 0) {
this.globalCount += count; this.globalCount += count;

View File

@ -43,6 +43,7 @@ module.exports = function (db) {
return db return db
.select(COLUMNS) .select(COLUMNS)
.from(TABLE) .from(TABLE)
.orderBy('last_seen', 'desc')
.map(mapRow); .map(mapRow);
} }

View File

@ -4,7 +4,7 @@ const COLUMNS = ['app_name', 'strategies'];
const TABLE = 'client_strategies'; const TABLE = 'client_strategies';
module.exports = function (db) { module.exports = function (db) {
function update (appName, strategies) { function updateRow (appName, strategies) {
return db(TABLE) return db(TABLE)
.where('app_name', appName) // eslint-disable-line .where('app_name', appName) // eslint-disable-line
.update({ .update({
@ -13,23 +13,23 @@ module.exports = function (db) {
}); });
} }
function insert (appName, strategies) { function insertNewRow (appName, strategies) {
return db(TABLE).insert({ return db(TABLE).insert({
app_name: appName, // eslint-disable-line app_name: appName, // eslint-disable-line
strategies: JSON.stringify(strategies), strategies: JSON.stringify(strategies),
}); });
} }
function insertOrUpdate (appName, strategies) { function insert (appName, strategies) {
return db(TABLE) return db(TABLE)
.count('*') .count('*')
.where('app_name', appName) .where('app_name', appName)
.map(row => ({ count: row.count })) .map(row => ({ count: row.count }))
.then(rows => { .then(rows => {
if (rows[0].count > 0) { if (rows[0].count > 0) {
return update(appName, strategies); return updateRow(appName, strategies);
} else { } else {
return insert(appName, strategies); return insertNewRow(appName, strategies);
} }
}); });
} }
@ -48,5 +48,5 @@ module.exports = function (db) {
}; };
} }
return { insertOrUpdate, getAll }; return { insert, getAll };
}; };

View File

@ -5,14 +5,14 @@ const ClientMetrics = require('../client-metrics');
const ClientMetricsService = require('../client-metrics/service'); const ClientMetricsService = require('../client-metrics/service');
module.exports = function (app, config) { module.exports = function (app, config) {
const { clientMetricsDb, clientStrategiesDb } = config; const {
clientMetricsDb,
clientStrategiesDb,
clientInstancesDb,
} = config;
const metrics = new ClientMetrics(); const metrics = new ClientMetrics();
const service = new ClientMetricsService(clientMetricsDb); 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) => { service.on('metrics', (entries) => {
entries.forEach((m) => { entries.forEach((m) => {
metrics.addPayload(m.metrics); metrics.addPayload(m.metrics);
@ -41,12 +41,15 @@ module.exports = function (app, config) {
}); });
app.post('/client/register', (req, res) => { app.post('/client/register', (req, res) => {
try { const data = req.body;
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body; clientStrategiesDb.insert(data.appName, data.strategies)
metrics.registerClient(data); .then(() => clientInstancesDb.insert({
} catch (e) { appName: data.appName,
logger.error('Error registering client', e); instanceId: data.instanceId,
} clientIp: req.ip,
}))
.then(() => console.log('new client registerd'))
.catch((error) => logger.error('Error registering client', error));
res.end(); res.end();
}); });
@ -54,4 +57,10 @@ module.exports = function (app, config) {
app.get('/client/strategies', (req, res) => { app.get('/client/strategies', (req, res) => {
clientStrategiesDb.getAll().then(data => res.json(data)); 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));
});
}; };

View File

@ -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 (
<Table
model={Model}
source={source}
selectable={false}
/>
);
}
}
export default ClientStrategies;

View File

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

View File

@ -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,
};

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import ClientStrategy from '../../component/client-strategy/strategy-container'; import ClientInstance from '../../component/client-instance/client-instance-container';
const render = () => <ClientStrategy />; const render = () => <ClientInstance />;
export default render; export default render;

View File

@ -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)));
}

View File

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

View File

@ -7,6 +7,7 @@ import archive from './archive-store';
import error from './error-store'; import error from './error-store';
import metrics from './metrics-store'; import metrics from './metrics-store';
import clientStrategies from './client-strategy-store'; import clientStrategies from './client-strategy-store';
import clientInstances from './client-instance-store';
const unleashStore = combineReducers({ const unleashStore = combineReducers({
features, features,
@ -17,6 +18,7 @@ const unleashStore = combineReducers({
error, error,
metrics, metrics,
clientStrategies, clientStrategies,
clientInstances,
}); });
export default unleashStore; export default unleashStore;

View File

@ -77,7 +77,7 @@ module.exports = {
target: 'http://localhost:4242', target: 'http://localhost:4242',
secure: false, secure: false,
}, },
'/client/strategies': { '/client': {
target: 'http://localhost:4242', target: 'http://localhost:4242',
secure: false, secure: false,
}, },