Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: Adds support for blocking queries on the node detail page #5489

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions ui-v2/app/controllers/dc/nodes/show.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { get, set, computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import WithSearching from 'consul-ui/mixins/with-searching';
export default Controller.extend(WithSearching, {
import WithEventSource, { listen } from 'consul-ui/mixins/with-event-source';

export default Controller.extend(WithEventSource, WithSearching, {
dom: service('dom'),
notify: service('flashMessages'),
items: alias('item.Services'),
queryParams: {
s: {
as: 'filter',
Expand All @@ -16,6 +21,21 @@ export default Controller.extend(WithSearching, {
};
this._super(...arguments);
},
item: listen('item').catch(function(e) {
if (e.target.readyState === 1) {
// OPEN
if (get(e, 'error.errors.firstObject.status') === '404') {
get(this, 'notify').add({
destroyOnClick: false,
sticky: true,
type: 'warning',
action: 'update',
});
get(this, 'tomography').close();
get(this, 'sessions').close();
}
}
}),
searchable: computed('items', function() {
return get(this, 'searchables.nodeservice')
.add(get(this, 'items'))
Expand All @@ -28,7 +48,7 @@ export default Controller.extend(WithSearching, {
// This method is called immediately after `Route::setupController`, and done here rather than there
// as this is a variable used purely for view level things, if the view was different we might not
// need this variable
set(this, 'selectedTab', get(this.item, 'Checks.length') > 0 ? 'health-checks' : 'services');
set(this, 'selectedTab', get(this, 'item.Checks.length') > 0 ? 'health-checks' : 'services');
},
actions: {
change: function(e) {
Expand Down
12 changes: 10 additions & 2 deletions ui-v2/app/instance-initializers/event-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function initialize(container) {
if (config[enabled] || window.localStorage.getItem(enabled) !== null) {
return;
}
['node', 'service', 'proxy']
['node', 'coordinate', 'session', 'service', 'proxy']
.map(function(item) {
// create repositories that return a promise resolving to an EventSource
return {
Expand All @@ -20,14 +20,22 @@ export function initialize(container) {
})
.concat([
// These are the routes where we overwrite the 'default'
// repo service. Default repos are repos that return a promise resovlving to
// repo service. Default repos are repos that return a promise resolving to
// an ember-data record or recordset
{
route: 'dc/nodes/index',
services: {
repo: 'repository/node/event-source',
},
},
{
route: 'dc/nodes/show',
services: {
repo: 'repository/node/event-source',
coordinateRepo: 'repository/coordinate/event-source',
sessionRepo: 'repository/session/event-source',
},
},
{
route: 'dc/services/index',
services: {
Expand Down
1 change: 1 addition & 0 deletions ui-v2/app/models/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default Model.extend({
Datacenter: attr('string'),
Segment: attr(),
Coord: attr(),
meta: attr(),
hasStatus: function(status) {
return hasStatus(get(this, 'Checks'), status);
},
Expand Down
32 changes: 9 additions & 23 deletions ui-v2/app/routes/dc/nodes/show.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { hash } from 'rsvp';
import { get, set } from '@ember/object';
import { get } from '@ember/object';

import distance from 'consul-ui/utils/distance';
import tomographyFactory from 'consul-ui/utils/tomography';
import WithBlockingActions from 'consul-ui/mixins/with-blocking-actions';

const tomography = tomographyFactory(distance);

export default Route.extend(WithBlockingActions, {
repo: service('repository/node'),
sessionRepo: service('repository/session'),
coordinateRepo: service('repository/coordinate'),
queryParams: {
s: {
as: 'filter',
Expand All @@ -20,24 +17,11 @@ export default Route.extend(WithBlockingActions, {
},
model: function(params) {
const dc = this.modelFor('dc').dc.Name;
const repo = get(this, 'repo');
const sessionRepo = get(this, 'sessionRepo');
const name = params.name;
return hash({
item: repo.findBySlug(params.name, dc),
}).then(function(model) {
// TODO: Consider loading this after initial page load
const coordinates = get(model.item, 'Coordinates');
return hash({
...model,
...{
tomography:
get(coordinates, 'length') > 1
? tomography(params.name, coordinates.map(item => get(item, 'data')))
: null,
items: get(model.item, 'Services'),
sessions: sessionRepo.findByNode(get(model.item, 'Node'), dc),
},
});
item: get(this, 'repo').findBySlug(name, dc),
tomography: get(this, 'coordinateRepo').findAllByNode(name, dc),
sessions: get(this, 'sessionRepo').findByNode(name, dc),
});
},
setupController: function(controller, model) {
Expand All @@ -52,7 +36,9 @@ export default Route.extend(WithBlockingActions, {
const node = get(item, 'Node');
return repo.remove(item).then(() => {
return repo.findByNode(node, dc).then(function(sessions) {
set(controller, 'sessions', sessions);
controller.setProperties({
sessions: sessions,
});
});
});
}, 'delete');
Expand Down
15 changes: 15 additions & 0 deletions ui-v2/app/services/repository/coordinate.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import { get } from '@ember/object';
import RepositoryService from 'consul-ui/services/repository';

import tomographyFactory from 'consul-ui/utils/tomography';
import distance from 'consul-ui/utils/distance';
const tomography = tomographyFactory(distance);

const modelName = 'coordinate';
export default RepositoryService.extend({
getModelName: function() {
return modelName;
},
findAllByNode: function(node, dc, configuration) {
return this.findAllByDatacenter(dc, configuration).then(function(coordinates) {
let results = {};
if (get(coordinates, 'length') > 1) {
results = tomography(node, coordinates.map(item => get(item, 'data')));
}
results.meta = get(coordinates, 'meta');
return results;
});
},
});
11 changes: 0 additions & 11 deletions ui-v2/app/services/repository/node.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import RepositoryService from 'consul-ui/services/repository';
import { inject as service } from '@ember/service';
import { get } from '@ember/object';
const modelName = 'node';
export default RepositoryService.extend({
coordinates: service('repository/coordinate'),
getModelName: function() {
return modelName;
},
findBySlug: function(slug, dc) {
return this._super(...arguments).then(node => {
return get(this, 'coordinates')
.findAllByDatacenter(dc)
.then(function(res) {
node.Coordinates = res;
return node;
});
});
},
});
6 changes: 5 additions & 1 deletion ui-v2/app/templates/dc/nodes/-notifications.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
{{else}}
There was an error invalidating the session.
{{/if}}
{{else if (eq type 'update')}}
{{#if (eq status 'warning') }}
This node no longer exists in the catalog.
{{else}}
{{/if}}
{{/if}}

10 changes: 5 additions & 5 deletions ui-v2/app/templates/dc/nodes/show.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
(array
'Health Checks'
'Services'
(if tomography 'Round Trip Time' '')
(if tomography.distances 'Round Trip Time' '')
'Lock Sessions'
)
)
Expand Down Expand Up @@ -48,10 +48,10 @@
{{#each
(compact
(array
(hash id=(slugify 'Health Checks') partial='dc/nodes/healthchecks')
(hash id=(slugify 'Services') partial='dc/nodes/services')
(if tomography (hash id=(slugify 'Round Trip Time') partial='dc/nodes/rtt') '')
(hash id=(slugify 'Lock Sessions') partial='dc/nodes/sessions')
(hash id=(slugify 'Health Checks') partial='dc/nodes/healthchecks')
(hash id=(slugify 'Services') partial='dc/nodes/services')
(if tomography.distances (hash id=(slugify 'Round Trip Time') partial='dc/nodes/rtt') '')
(hash id=(slugify 'Lock Sessions') partial='dc/nodes/sessions')
)
) as |panel|
}}
Expand Down
32 changes: 26 additions & 6 deletions ui-v2/tests/acceptance/dc/nodes/show.feature
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
@setupApplicationTest
Feature: dc / nodes / show: Show node
Scenario: Given 2 nodes all the tabs are visible and clickable
Background:
Given 1 datacenter model with the value "dc1"
And 2 node models from yaml
Scenario: Given 2 nodes all the tabs are visible and clickable
Given 2 node models from yaml
When I visit the node page for yaml
---
dc: dc1
Expand All @@ -19,8 +20,7 @@ Feature: dc / nodes / show: Show node
When I click lockSessions on the tabs
And I see lockSessionsIsSelected on the tabs
Scenario: Given 1 node all the tabs are visible and clickable and the RTT one isn't there
Given 1 datacenter model with the value "dc1"
And 1 node models from yaml
Given 1 node models from yaml
---
ID: node-0
---
Expand All @@ -39,8 +39,7 @@ Feature: dc / nodes / show: Show node
When I click lockSessions on the tabs
And I see lockSessionsIsSelected on the tabs
Scenario: Given 1 node with no checks all the tabs are visible but the Services tab is selected
Given 1 datacenter model with the value "dc1"
And 1 node models from yaml
Given 1 node models from yaml
---
ID: node-0
Checks: []
Expand All @@ -55,3 +54,24 @@ Feature: dc / nodes / show: Show node
And I see roundTripTime on the tabs
And I see lockSessions on the tabs
And I see servicesIsSelected on the tabs
Scenario: A node warns when deregistered whilst blocking
Given 1 node model from yaml
---
ID: node-0
---
And settings from yaml
---
consul:client:
blocking: 1
throttle: 200
---
And a network latency of 100
When I visit the node page for yaml
---
dc: dc1
node: node-0
---
Then the url should be /dc1/nodes/node-0
And the url "/v1/internal/ui/node/node-0" responds with a 404 status
And pause until I see the text "no longer exists" in "[data-notification]"

4 changes: 4 additions & 0 deletions ui-v2/tests/integration/services/repository/node-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ test('findBySlug returns the correct data for item endpoint', function(assert) {
return Object.assign({}, item, {
Datacenter: dc,
uid: `["${dc}","${item.ID}"]`,
meta: {
date: undefined,
cursor: undefined,
},
});
})
);
Expand Down
2 changes: 1 addition & 1 deletion ui-v2/tests/unit/controllers/dc/nodes/show-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { moduleFor, test } from 'ember-qunit';

moduleFor('controller:dc/nodes/show', 'Unit | Controller | dc/nodes/show', {
// Specify the other units that are required for this test.
needs: ['service:search', 'service:dom'],
needs: ['service:search', 'service:dom', 'service:flashMessages'],
});

// Replace this with your real tests.
Expand Down
1 change: 1 addition & 0 deletions ui-v2/tests/unit/routes/dc/nodes/show-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ moduleFor('route:dc/nodes/show', 'Unit | Route | dc/nodes/show', {
// Specify the other units that are required for this test.
needs: [
'service:repository/node',
'service:repository/coordinate',
'service:repository/session',
'service:feedback',
'service:logger',
Expand Down