mirror of
https://github.com/status-im/consul.git
synced 2025-01-26 05:29:55 +00:00
27c74f7141
* Model layer changes to turn Node:ServiceInstances into hasMany We tried to make something that feels a little like ember-data yet not leave our approach of re-shaping the JSON directly from the response. 1. We added transformHasManyResponse for re-shaping JSON for hasMany relationships. we avoided the normalize word as ember-data serialize methods usually return something JSON:API shaped and we distinctly don't want to do that. Transform was the best word we could think of. 2. The integration tests across all of our models here feel very much like those types of tests that aren't really testing much, or assert too much to an extent that they get in the way rather than be of any use. I'd very much like to move a lot of this to unit tests. Currently most of the fingerprinting functionality is unit tested and these integration tests were originally to give confidence that IDs and related properties were being added correctly. 3. We've added a hasMany relationship, but not the corresponding belongsTo - yet at least. We don't require the belongsTo right now, and if we do we can add it later. * Integrate ServiceInstance search bar for Node:ServiceInstances * Hide Node.Meta when on the Node:ServiceINstance page We use a little string replace hack here for a human-like label, this is soon to be replaced with proper i10n replacement * Always ensure that a Namespace is set, and add comment explaining
103 lines
2.9 KiB
JavaScript
103 lines
2.9 KiB
JavaScript
import Serializer from './application';
|
|
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
|
|
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/node';
|
|
import { classify } from '@ember/string';
|
|
|
|
// TODO: Looks like ID just isn't used at all consider just using .Node for
|
|
// the SLUG_KEY
|
|
const fillSlug = function(item) {
|
|
if (item[SLUG_KEY] === '') {
|
|
item[SLUG_KEY] = item['Node'];
|
|
}
|
|
return item;
|
|
};
|
|
|
|
export default class NodeSerializer extends Serializer.extend(EmbeddedRecordsMixin) {
|
|
primaryKey = PRIMARY_KEY;
|
|
slugKey = SLUG_KEY;
|
|
|
|
attrs = {
|
|
Services: {
|
|
embedded: 'always',
|
|
},
|
|
};
|
|
|
|
transformHasManyResponse(store, relationship, item, parent = null) {
|
|
switch (relationship.key) {
|
|
case 'Services':
|
|
const checks = {};
|
|
(item.Checks || [])
|
|
.filter(item => {
|
|
return item.ServiceID !== '';
|
|
})
|
|
.forEach(item => {
|
|
if (typeof checks[item.ServiceID] === 'undefined') {
|
|
checks[item.ServiceID] = [];
|
|
}
|
|
checks[item.ServiceID].push(item);
|
|
});
|
|
const serializer = this.store.serializerFor(relationship.type);
|
|
item.Services = item.Services.map(service =>
|
|
serializer.transformHasManyResponseFromNode(item, service, checks)
|
|
);
|
|
return item;
|
|
}
|
|
return super.transformHasManyResponse(...arguments);
|
|
}
|
|
|
|
respondForQuery(respond, query, data, modelClass) {
|
|
const body = super.respondForQuery(
|
|
cb => respond((headers, body) => cb(headers, body.map(fillSlug))),
|
|
query
|
|
);
|
|
modelClass.eachRelationship((key, relationship) => {
|
|
body.forEach(item =>
|
|
this[`transform${classify(relationship.kind)}Response`](
|
|
this.store,
|
|
relationship,
|
|
item,
|
|
body
|
|
)
|
|
);
|
|
});
|
|
return body;
|
|
}
|
|
|
|
respondForQueryRecord(respond, query, data, modelClass) {
|
|
const body = super.respondForQueryRecord(
|
|
cb =>
|
|
respond((headers, body) => {
|
|
return cb(headers, fillSlug(body));
|
|
}),
|
|
query
|
|
);
|
|
|
|
modelClass.eachRelationship((key, relationship) => {
|
|
this[`transform${classify(relationship.kind)}Response`](this.store, relationship, body);
|
|
});
|
|
return body;
|
|
}
|
|
|
|
respondForQueryLeader(respond, query) {
|
|
// don't call super here we don't care about
|
|
// ids/fingerprinting
|
|
return respond((headers, body) => {
|
|
// This response/body is just an ip:port like `"10.0.0.1:8500"`
|
|
// split it and make it look like a `C`onsul.`R`esponse
|
|
// popping off the end for ports should cover us for IPv6 addresses
|
|
// as we should always get a `address:port` or `[a:dd:re:ss]:port` combo
|
|
const temp = body.split(':');
|
|
const port = temp.pop();
|
|
const address = temp.join(':');
|
|
return this.attachHeaders(
|
|
headers,
|
|
{
|
|
Address: address,
|
|
Port: port,
|
|
},
|
|
query
|
|
);
|
|
});
|
|
}
|
|
}
|