Skip to content

Commit

Permalink
Merge pull request juju#3814 from huwshimi/split-delta-handlers
Browse files Browse the repository at this point in the history
Move delta handlers to their own module.
  • Loading branch information
huwshimi authored Sep 21, 2018
2 parents a5d6a63 + bdab6ac commit e97742a
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 83 deletions.
104 changes: 104 additions & 0 deletions jujugui/static/gui/src/app/maraca/delta-handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* Copyright (C) 2018 Canonical Ltd. */
'use strict';

const parsers = require('./parsers');

/**
Get the consolidated updates from the deltas.
@param {Array} deltas - The list of deltas.
@returns {Object} return - The delta updates.
@returns {Object} return.changed - The entities to change.
@returns {Object} return.removed - The entities to remove.
*/
function processDeltas(deltas) {
let updates = {
changed: {},
removed: {}
};
deltas.forEach(delta => {
const entityType = delta[0];
const changeType = delta[1];
const entity = delta[2];
const key = _getEntityKey(entityType, entity);
if (!key) {
// We don't know how to manage this entity, so ignore it.
return;
}
const entityGroup = _getEntityGroup(entityType);
const updateCollection = updates[changeType + 'd'];
if (!updateCollection[entityGroup]) {
updateCollection[entityGroup] = {};
}
updateCollection[entityGroup][key] = _parseEntity(entityType, entity);
});
return updates;
}

/**
Get the identifier for the entity based upon its type.
@param {String} entityType - The type of entity.
@param {Object} entity - The entity details.
@returns {String} The entity key.
*/
function _getEntityKey(entityType, entity) {
switch (entityType) {
case 'remote-application':
case 'application':
case 'unit':
return entity.name;
case 'machine':
case 'relation':
return entity.id;
case 'annotation':
return entity.tag;
default:
// This is an unknown entity type so ignore it as we don't know how to
// handle it.
return null;
}
}

/**
Get the group entity belongs to.
@param {String} entityType - The type of entity.
@returns {String} The entity group.
*/
function _getEntityGroup(entityType) {
switch (entityType) {
case 'remote-application':
return 'remoteApplications';
default:
return entityType + 's';
}
}

/**
Parse the entity response into a friendly format.
@param {String} entityType - The type of entity.
@param {Object} entity - The entity details.
@returns {Object} The parsed entity.
*/
function _parseEntity(entityType, entity) {
switch (entityType) {
case 'remote-application':
return parsers.parseRemoteApplication(entity);
case 'application':
return parsers.parseApplication(entity);
case 'unit':
return parsers.parseUnit(entity);
case 'machine':
return parsers.parseMachine(entity);
case 'relation':
return parsers.parseRelation(entity);
case 'annotation':
return parsers.parseAnnotation(entity);
default:
// This is an unknown entity type so ignore it as we don't know how to
// handle it.
return null;
}
}

module.exports = {
processDeltas
};
106 changes: 23 additions & 83 deletions jujugui/static/gui/src/app/maraca/maraca.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
const clonedeep = require('lodash.clonedeep');
const deepmerge = require('deepmerge');

const parsers = require('./parsers');
const {processDeltas} = require('./delta-handlers');

class Maraca {
constructor(config) {
Expand Down Expand Up @@ -56,95 +56,35 @@ class Maraca {
}

/**
Consolidate the deltas.
@param deltas {Array} The list of deltas.
Update the store with the changes from the deltas.
@param evt {Object} The megawatcher event.
*/
_handleDeltas(deltas) {
deltas.forEach(delta => {
const entityType = delta[0];
const changeType = delta[1];
const entity = delta[2];
const key = this._getEntityKey(entityType, entity);
if (!key) {
// We don't know how to manage this entity, so ignore it.
return;
}
const entityGroup = this._valueStore[this._getEntityGroup(entityType)];
if (changeType === 'change') {
if (!entityGroup[key]) {
entityGroup[key] = {};
_updateStore(updates, updateType) {
Object.keys(updates).forEach(collectionKey => {
const collection = updates[collectionKey];
Object.keys(collection).forEach(entityKey => {
const entity = collection[entityKey];
const storeCollection = this._valueStore[collectionKey];
if (updateType === 'changed') {
if (!storeCollection[entityKey]) {
storeCollection[entityKey] = {};
}
storeCollection[entityKey] = deepmerge(storeCollection[entityKey], entity);
} else {
delete storeCollection[entityKey];
}
const parsedEntity = this._parseEntity(entityType, entity);
entityGroup[key] = deepmerge(entityGroup[key], parsedEntity);
} else if (changeType === 'remove') {
delete entityGroup[key];
}
});
});
}

/**
Get the identifier for the entity based upon its type.
@param entityType {String} The type of entity.
@param entity {Object} The entity details.
@returns {String} The entity key.
*/
_getEntityKey(entityType, entity) {
switch (entityType) {
case 'remote-application':
case 'application':
case 'unit':
return entity.name;
case 'machine':
case 'relation':
return entity.id;
case 'annotation':
return entity.tag;
default:
// This is an unknown entity type so ignore it as we don't know how to
// handle it.
return null;
}
}

/**
Get the group entity belongs to.
@param entityType {String} The type of entity.
@returns {String} The entity group.
*/
_getEntityGroup(entityType) {
switch (entityType) {
case 'remote-application':
return 'remoteApplications';
default:
return entityType + 's';
}
}

/**
Parse the entity response into a friendly format.
@param entityType {String} The type of entity.
@param entity {Object} The entity details.
@returns {Object} The parsed entity.
Consolidate the deltas.
@param deltas {Array} The list of deltas.
*/
_parseEntity(entityType, entity) {
switch (entityType) {
case 'remote-application':
return parsers.parseRemoteApplication(entity);
case 'application':
return parsers.parseApplication(entity);
case 'unit':
return parsers.parseUnit(entity);
case 'machine':
return parsers.parseMachine(entity);
case 'relation':
return parsers.parseRelation(entity);
case 'annotation':
return parsers.parseAnnotation(entity);
default:
// This is an unknown entity type so ignore it as we don't know how to
// handle it.
return null;
}
_handleDeltas(deltas) {
const updates = processDeltas(deltas);
this._updateStore(updates.changed, 'changed');
this._updateStore(updates.removed, 'removed');
}
}

Expand Down
120 changes: 120 additions & 0 deletions jujugui/static/gui/src/app/maraca/test-delta-handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* Copyright (C) 2018 Canonical Ltd. */
'use strict';

const handlers = require('./delta-handlers');
const parsers = require('./parsers');

describe('delta handlers', () => {
it('adds/updates entities', () => {
const updates = handlers.processDeltas([[
'unit', 'change', {
name: 'apache2/0'
}
]]);
assert.deepEqual(updates.changed.units, {
'apache2/0': parsers.parseUnit({
name: 'apache2/0'
})
});
});

it('removes entities', () => {
const updates = handlers.processDeltas([[
'unit', 'remove', {
name: 'apache2/0'
}
]]);
assert.deepEqual(updates.removed.units, {
'apache2/0': parsers.parseUnit({
name: 'apache2/0'
})
});
});

it('can handle remote applications', () => {
const updates = handlers.processDeltas([[
'remote-application', 'change', {
name: 'apache2'
}
]]);
assert.deepEqual(updates.changed.remoteApplications, {
apache2: parsers.parseRemoteApplication({
name: 'apache2'
})
});
});

it('can handle applications', () => {
const updates = handlers.processDeltas([[
'application', 'change', {
name: 'apache2'
}
]]);
assert.deepEqual(updates.changed.applications, {
apache2: parsers.parseApplication({
name: 'apache2'
})
});
});

it('can handle units', () => {
const updates = handlers.processDeltas([[
'unit', 'change', {
name: 'apache2/0'
}
]]);
assert.deepEqual(updates.changed.units, {
'apache2/0': parsers.parseUnit({
name: 'apache2/0'
})
});
});

it('can handle machines', () => {
const updates = handlers.processDeltas([[
'machine', 'change', {
id: '0'
}
]]);
assert.deepEqual(updates.changed.machines, {
0: parsers.parseMachine({
id: '0'
})
});
});

it('can handle relations', () => {
const updates = handlers.processDeltas([[
'relation', 'change', {
id: '1'
}
]]);
assert.deepEqual(updates.changed.relations, {
1: parsers.parseRelation({
id: '1'
})
});
});

it('can handle annotations', () => {
const updates = handlers.processDeltas([[
'annotation', 'change', {
tag: 'application-apache2'
}
]]);
assert.deepEqual(updates.changed.annotations, {
'application-apache2': parsers.parseAnnotation({
tag: 'application-apache2'
})
});
});

it('can handle unkown entities', () => {
const updates = handlers.processDeltas([[
'nothing-here', 'change', {
id: '1'
}
]]);
assert.deepEqual(updates.changed, {});
});
});

0 comments on commit e97742a

Please sign in to comment.