ui: Asyncify Service Model Hooks (#9312)
* ui: Add Kind grouping computed properties * Use new computed properties and move model hooks to async methods
This commit is contained in:
parent
297210ad93
commit
a0edd6d664
|
@ -38,6 +38,27 @@ export default class ServiceInstance extends Model {
|
||||||
return [...new Set(sources)];
|
return [...new Set(sources)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@computed('Service.Kind')
|
||||||
|
get IsProxy() {
|
||||||
|
return ['connect-proxy', 'mesh-gateway', 'ingress-gateway', 'terminating-gateway'].includes(
|
||||||
|
this.Service.Kind
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsOrigin means that the service can have associated up or down streams,
|
||||||
|
// this service being the origin point of those streams
|
||||||
|
@computed('Service.Kind')
|
||||||
|
get IsOrigin() {
|
||||||
|
return !['connect-proxy', 'mesh-gateway'].includes(this.Service.Kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsMeshOrigin means that the service can have associated up or downstreams
|
||||||
|
// that are in the Consul mesh itself
|
||||||
|
@computed('IsOrigin')
|
||||||
|
get IsMeshOrigin() {
|
||||||
|
return this.IsOrigin && !['terminating-gateway'].includes(this.Service.Kind);
|
||||||
|
}
|
||||||
|
|
||||||
@computed('ChecksPassing', 'ChecksWarning', 'ChecksCritical')
|
@computed('ChecksPassing', 'ChecksWarning', 'ChecksCritical')
|
||||||
get Status() {
|
get Status() {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import Route from 'consul-ui/routing/route';
|
import Route from 'consul-ui/routing/route';
|
||||||
import { hash } from 'rsvp';
|
|
||||||
|
|
||||||
export default class IndexRoute extends Route {
|
export default class IndexRoute extends Route {
|
||||||
@service('data-source/service') data;
|
@service('data-source/service') data;
|
||||||
|
@ -20,14 +19,15 @@ export default class IndexRoute extends Route {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
model(params) {
|
async model(params, transition) {
|
||||||
const nspace = this.modelFor('nspace').nspace.substr(1);
|
const nspace = this.modelFor('nspace').nspace.substr(1);
|
||||||
const dc = this.modelFor('dc').dc.Name;
|
const dc = this.modelFor('dc').dc.Name;
|
||||||
return hash({
|
const items = await this.data.source(uri => uri`/${nspace}/${dc}/services`);
|
||||||
nspace: nspace,
|
return {
|
||||||
dc: dc,
|
dc,
|
||||||
items: this.data.source(uri => uri`/${nspace}/${dc}/services`),
|
nspace,
|
||||||
});
|
items,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
|
|
|
@ -1,54 +1,46 @@
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import Route from 'consul-ui/routing/route';
|
import Route from 'consul-ui/routing/route';
|
||||||
import { hash } from 'rsvp';
|
|
||||||
import { get } from '@ember/object';
|
import { get } from '@ember/object';
|
||||||
|
|
||||||
export default class InstanceRoute extends Route {
|
export default class InstanceRoute extends Route {
|
||||||
@service('data-source/service')
|
@service('data-source/service') data;
|
||||||
data;
|
|
||||||
|
|
||||||
model(params) {
|
async model(params, transition) {
|
||||||
const dc = this.modelFor('dc').dc.Name;
|
const dc = this.modelFor('dc').dc.Name;
|
||||||
const nspace = this.modelFor('nspace').nspace.substr(1) || 'default';
|
const nspace = this.modelFor('nspace').nspace.substr(1) || 'default';
|
||||||
return hash({
|
|
||||||
dc: dc,
|
const item = await this.data.source(
|
||||||
nspace: nspace,
|
|
||||||
item: this.data.source(
|
|
||||||
uri => uri`/${nspace}/${dc}/service-instance/${params.id}/${params.node}/${params.name}`
|
uri => uri`/${nspace}/${dc}/service-instance/${params.id}/${params.node}/${params.name}`
|
||||||
),
|
);
|
||||||
}).then(model => {
|
|
||||||
// this will not be run in a blocking loop, but this is ok as
|
let proxyMeta, proxy;
|
||||||
// its highly unlikely that a service will suddenly change to being a
|
if (get(item, 'IsOrigin')) {
|
||||||
// connect-proxy or vice versa so leave as is for now
|
proxyMeta = await this.data.source(
|
||||||
return hash({
|
uri => uri`/${nspace}/${dc}/proxy-instance/${params.id}/${params.node}/${params.name}`
|
||||||
...model,
|
);
|
||||||
proxyMeta:
|
if (typeof get(proxyMeta, 'ServiceID') !== 'undefined') {
|
||||||
// proxies and mesh-gateways can't have proxies themselves so don't even look
|
const proxyParams = {
|
||||||
['connect-proxy', 'mesh-gateway'].includes(get(model.item, 'Kind'))
|
id: get(proxyMeta, 'ServiceID'),
|
||||||
? null
|
node: get(proxyMeta, 'Node'),
|
||||||
: this.data.source(
|
name: get(proxyMeta, 'ServiceName'),
|
||||||
uri =>
|
|
||||||
uri`/${nspace}/${dc}/proxy-instance/${params.id}/${params.node}/${params.name}`
|
|
||||||
),
|
|
||||||
}).then(model => {
|
|
||||||
if (typeof get(model, 'proxyMeta.ServiceID') === 'undefined') {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
const proxy = {
|
|
||||||
id: get(model, 'proxyMeta.ServiceID'),
|
|
||||||
node: get(model, 'proxyMeta.Node'),
|
|
||||||
name: get(model, 'proxyMeta.ServiceName'),
|
|
||||||
};
|
};
|
||||||
return hash({
|
|
||||||
...model,
|
|
||||||
// Proxies have identical dc/nspace as their parent instance
|
// Proxies have identical dc/nspace as their parent instance
|
||||||
// No need to use Proxy's dc/nspace response
|
// so no need to use Proxy's dc/nspace response
|
||||||
proxy: this.data.source(
|
// the proxy itself is just a normal service model
|
||||||
uri => uri`/${nspace}/${dc}/service-instance/${proxy.id}/${proxy.node}/${proxy.name}`
|
proxy = await this.data.source(
|
||||||
),
|
uri =>
|
||||||
});
|
uri`/${nspace}/${dc}/service-instance/${proxyParams.id}/${proxyParams.node}/${proxyParams.name}`
|
||||||
});
|
);
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
dc,
|
||||||
|
nspace,
|
||||||
|
item,
|
||||||
|
proxyMeta,
|
||||||
|
proxy,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import Route from 'consul-ui/routing/route';
|
import Route from 'consul-ui/routing/route';
|
||||||
import { hash } from 'rsvp';
|
|
||||||
import { get } from '@ember/object';
|
import { get } from '@ember/object';
|
||||||
import { action, setProperties } from '@ember/object';
|
import { action, setProperties } from '@ember/object';
|
||||||
|
|
||||||
|
@ -24,54 +23,48 @@ export default class ShowRoute extends Route {
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
model(params, transition) {
|
async model(params, transition) {
|
||||||
const dc = this.modelFor('dc').dc.Name;
|
const dc = this.modelFor('dc').dc.Name;
|
||||||
const nspace = this.modelFor('nspace').nspace.substr(1);
|
const nspace = this.modelFor('nspace').nspace.substr(1);
|
||||||
return hash({
|
const slug = params.name;
|
||||||
slug: params.name,
|
|
||||||
dc: dc,
|
let chain = null;
|
||||||
nspace: nspace,
|
let topology = null;
|
||||||
items: this.data.source(
|
let proxies = [];
|
||||||
|
|
||||||
|
const urls = this.config.get().dashboard_url_templates;
|
||||||
|
const items = await this.data.source(
|
||||||
uri => uri`/${nspace}/${dc}/service-instances/for-service/${params.name}`
|
uri => uri`/${nspace}/${dc}/service-instances/for-service/${params.name}`
|
||||||
),
|
);
|
||||||
urls: this.config.get().dashboard_url_templates,
|
|
||||||
chain: null,
|
const item = get(items, 'firstObject');
|
||||||
proxies: [],
|
if (get(item, 'IsOrigin')) {
|
||||||
topology: null,
|
chain = await this.data.source(uri => uri`/${nspace}/${dc}/discovery-chain/${params.name}`);
|
||||||
})
|
proxies = await this.data.source(
|
||||||
.then(model => {
|
|
||||||
return ['connect-proxy', 'mesh-gateway', 'ingress-gateway', 'terminating-gateway'].includes(
|
|
||||||
get(model, 'items.firstObject.Service.Kind')
|
|
||||||
)
|
|
||||||
? model
|
|
||||||
: hash({
|
|
||||||
...model,
|
|
||||||
chain: this.data.source(uri => uri`/${nspace}/${dc}/discovery-chain/${params.name}`),
|
|
||||||
// Whilst `proxies` isn't used anywhere in the show templates
|
|
||||||
// it provides a relationship of ProxyInstance on the ServiceInstance
|
|
||||||
// which can respond at a completely different blocking rate to
|
|
||||||
// the ServiceInstance itself
|
|
||||||
proxies: this.data.source(
|
|
||||||
uri => uri`/${nspace}/${dc}/proxies/for-service/${params.name}`
|
uri => uri`/${nspace}/${dc}/proxies/for-service/${params.name}`
|
||||||
),
|
);
|
||||||
});
|
|
||||||
})
|
if (get(item, 'IsMeshOrigin')) {
|
||||||
.then(model => {
|
let kind = get(item, 'Service.Kind');
|
||||||
let kind = get(model, 'items.firstObject.Service.Kind');
|
|
||||||
if (typeof kind === 'undefined') {
|
if (typeof kind === 'undefined') {
|
||||||
kind = '';
|
kind = '';
|
||||||
}
|
}
|
||||||
return ['mesh-gateway', 'terminating-gateway'].includes(
|
topology = await this.data.source(
|
||||||
get(model, 'items.firstObject.Service.Kind')
|
|
||||||
)
|
|
||||||
? model
|
|
||||||
: hash({
|
|
||||||
...model,
|
|
||||||
topology: this.data.source(
|
|
||||||
uri => uri`/${nspace}/${dc}/topology/${params.name}/${kind}`
|
uri => uri`/${nspace}/${dc}/topology/${params.name}/${kind}`
|
||||||
),
|
);
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
dc,
|
||||||
|
nspace,
|
||||||
|
slug,
|
||||||
|
items,
|
||||||
|
urls,
|
||||||
|
chain,
|
||||||
|
proxies,
|
||||||
|
topology,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import Route from 'consul-ui/routing/route';
|
import Route from 'consul-ui/routing/route';
|
||||||
import { hash } from 'rsvp';
|
|
||||||
|
|
||||||
export default class ServicesRoute extends Route {
|
export default class ServicesRoute extends Route {
|
||||||
@service('data-source/service') data;
|
@service('data-source/service') data;
|
||||||
|
@ -18,7 +17,7 @@ export default class ServicesRoute extends Route {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
model() {
|
async model(params, transition) {
|
||||||
const dc = this.modelFor('dc').dc.Name;
|
const dc = this.modelFor('dc').dc.Name;
|
||||||
const nspace = this.modelFor('nspace').nspace.substr(1);
|
const nspace = this.modelFor('nspace').nspace.substr(1);
|
||||||
const parent = this.routeName
|
const parent = this.routeName
|
||||||
|
@ -26,11 +25,14 @@ export default class ServicesRoute extends Route {
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
.join('.');
|
.join('.');
|
||||||
const name = this.modelFor(parent).slug;
|
const name = this.modelFor(parent).slug;
|
||||||
return hash({
|
const gatewayServices = await this.data.source(
|
||||||
dc: dc,
|
uri => uri`/${nspace}/${dc}/gateways/for-service/${name}`
|
||||||
nspace: nspace,
|
);
|
||||||
gatewayServices: this.data.source(uri => uri`/${nspace}/${dc}/gateways/for-service/${name}`),
|
return {
|
||||||
});
|
dc,
|
||||||
|
nspace,
|
||||||
|
gatewayServices,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
|
|
Loading…
Reference in New Issue