Skip to content

Commit

Permalink
ui: Fixes DC switching when blocking queries are enabled (#6808)
Browse files Browse the repository at this point in the history
This is the same fix as #6555
but for the 1.7 version of the UI with additional nspace support
  • Loading branch information
johncowen authored and John Cowen committed Nov 19, 2019
1 parent 41ab816 commit b043d57
Show file tree
Hide file tree
Showing 20 changed files with 159 additions and 28 deletions.
23 changes: 20 additions & 3 deletions ui-v2/app/serializers/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import config from 'consul-ui/config/environment';
import {
HEADERS_SYMBOL as HTTP_HEADERS_SYMBOL,
HEADERS_INDEX as HTTP_HEADERS_INDEX,
HEADERS_DATACENTER as HTTP_HEADERS_DATACENTER,
HEADERS_NAMESPACE as HTTP_HEADERS_NAMESPACE,
} from 'consul-ui/utils/http/consul';
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
import { NSPACE_KEY } from 'consul-ui/models/nspace';
Expand All @@ -17,12 +19,21 @@ const map = function(obj, cb) {
return obj.map(cb);
};

const attachHeaders = function(headers, body) {
const attachHeaders = function(headers, body, query = {}) {
// lowercase everything incase we get browser inconsistencies
const lower = {};
Object.keys(headers).forEach(function(key) {
lower[key.toLowerCase()] = headers[key];
});
// Add a 'pretend' Datacenter/Nspace header, they are not headers
// the come from the request but we add them here so we can use them later
// for store reconciliation
if (typeof query.dc !== 'undefined') {
lower[HTTP_HEADERS_DATACENTER.toLowerCase()] = query.dc;
}
lower[HTTP_HEADERS_NAMESPACE.toLowerCase()] =
typeof query.ns !== 'undefined' ? query.ns : config.CONSUL_NSPACES_UNDEFINED_NAME;
//
body[HTTP_HEADERS_SYMBOL] = lower;
return body;
};
Expand All @@ -36,12 +47,16 @@ export default Serializer.extend({
),
respondForQuery: function(respond, query) {
return respond((headers, body) =>
attachHeaders(headers, map(body, this.fingerprint(this.primaryKey, this.slugKey, query.dc)))
attachHeaders(
headers,
map(body, this.fingerprint(this.primaryKey, this.slugKey, query.dc)),
query
)
);
},
respondForQueryRecord: function(respond, query) {
return respond((headers, body) =>
attachHeaders(headers, this.fingerprint(this.primaryKey, this.slugKey, query.dc)(body))
attachHeaders(headers, this.fingerprint(this.primaryKey, this.slugKey, query.dc)(body), query)
);
},
respondForCreateRecord: function(respond, serialized, data) {
Expand Down Expand Up @@ -127,6 +142,8 @@ export default Serializer.extend({
normalizeMeta: function(store, primaryModelClass, headers, payload, id, requestType) {
const meta = {
cursor: headers[HTTP_HEADERS_INDEX],
dc: headers[HTTP_HEADERS_DATACENTER.toLowerCase()],
nspace: headers[HTTP_HEADERS_NAMESPACE.toLowerCase()],
};
if (requestType === 'query') {
meta.date = this.timestamp();
Expand Down
10 changes: 7 additions & 3 deletions ui-v2/app/services/repository/type/event-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ const createProxy = function(repo, find, settings, cache, serialize = JSON.strin
if (typeof meta.date !== 'undefined') {
// unload anything older than our current sync date/time
store.peekAll(repo.getModelName()).forEach(function(item) {
const date = get(item, 'SyncTime');
if (typeof date !== 'undefined' && date != meta.date) {
store.unloadRecord(item);
const dc = get(item, 'Datacenter');
const nspace = get(item, 'Namespace');
if (dc === meta.dc && nspace === meta.nspace) {
const date = get(item, 'SyncTime');
if (typeof date !== 'undefined' && date != meta.date) {
store.unloadRecord(item);
}
}
});
}
Expand Down
1 change: 1 addition & 0 deletions ui-v2/app/utils/http/consul.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// TODO: Need to make all these headers capital case
export const HEADERS_NAMESPACE = 'X-Consul-Namespace';
export const HEADERS_DATACENTER = 'x-consul-datacenter';
export const HEADERS_INDEX = 'x-consul-index';
export const HEADERS_DIGEST = 'x-consul-contenthash';
//
Expand Down
27 changes: 27 additions & 0 deletions ui-v2/tests/acceptance/dc/services/dc-switch.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@setupApplicationTest
Feature: dc / services / dc-switch : Switching Datacenters
Scenario: Seeing all services when switching datacenters
Given 2 datacenter models from yaml
---
- dc-1
- dc-2
---
And 6 service models
When I visit the services page for yaml
---
dc: dc-1
---
Then the url should be /dc-1/services
Then I see 6 service models
When I click dc on the navigation
And I click dcs.1.name
Then the url should be /dc-2/services
Then I see 6 service models
When I click dc on the navigation
And I click dcs.0.name
Then the url should be /dc-1/services
Then I see 6 service models
When I click dc on the navigation
And I click dcs.1.name
Then the url should be /dc-2/services
Then I see 6 service models
10 changes: 10 additions & 0 deletions ui-v2/tests/acceptance/steps/dc/services/dc-switch-steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import steps from '../../steps';

// step definitions that are shared between features should be moved to the
// tests/acceptance/steps/steps.js file

export default function(assert) {
return steps(assert).then('I should find a file', function() {
assert.ok(true, this.step);
});
}
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/acl-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';
module('Integration | Serializer | acl', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
Expand Down Expand Up @@ -43,7 +47,10 @@ module('Integration | Serializer | acl', function(hooks) {
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload[0], {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: nspace,
},
// TODO: default isn't required here, once we've
// refactored out our Serializer this can go
Namespace: nspace,
Expand Down
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/intention-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';
module('Integration | Serializer | intention', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
Expand Down Expand Up @@ -43,7 +47,10 @@ module('Integration | Serializer | intention', function(hooks) {
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload, {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: nspace,
},
// TODO: default isn't required here, once we've
// refactored out our Serializer this can go
Namespace: nspace,
Expand Down
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/kv-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';
module('Integration | Serializer | kv', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
Expand Down Expand Up @@ -51,7 +55,10 @@ module('Integration | Serializer | kv', function(hooks) {
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload[0], {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: payload[0].Namespace || undefinedNspace,
},
Namespace: payload[0].Namespace || undefinedNspace,
uid: `["${payload[0].Namespace || undefinedNspace}","${dc}","${id}"]`,
});
Expand Down
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/node-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';
module('Integration | Serializer | node', function(hooks) {
setupTest(hooks);
const nspace = 'default';
Expand Down Expand Up @@ -44,7 +48,10 @@ module('Integration | Serializer | node', function(hooks) {
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload, {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: nspace,
},
// TODO: default isn't required here, once we've
// refactored out our Serializer this can go
Namespace: nspace,
Expand Down
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/policy-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';
module('Integration | Serializer | policy', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
Expand Down Expand Up @@ -43,7 +47,10 @@ module('Integration | Serializer | policy', function(hooks) {
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload, {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: payload.Namespace || undefinedNspace,
},
Namespace: payload.Namespace || undefinedNspace,
uid: `["${payload.Namespace || undefinedNspace}","${dc}","${id}"]`,
});
Expand Down
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/role-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';
import { createPolicies } from 'consul-ui/tests/helpers/normalizers';

module('Integration | Serializer | role', function(hooks) {
Expand Down Expand Up @@ -47,7 +51,10 @@ module('Integration | Serializer | role', function(hooks) {
const expected = Object.assign({}, payload, {
Datacenter: dc,
Policies: createPolicies(payload),
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: payload.Namespace || undefinedNspace,
},
Namespace: payload.Namespace || undefinedNspace,
uid: `["${payload.Namespace || undefinedNspace}","${dc}","${id}"]`,
});
Expand Down
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/service-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';
module('Integration | Serializer | service', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
Expand Down Expand Up @@ -47,7 +51,10 @@ module('Integration | Serializer | service', function(hooks) {
return get(request.url).then(function(payload) {
const expected = {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: payload[0].Service.Namespace || undefinedNspace,
},
Namespace: payload[0].Service.Namespace || undefinedNspace,
uid: `["${payload[0].Service.Namespace || undefinedNspace}","${dc}","${id}"]`,
Name: id,
Expand Down
6 changes: 4 additions & 2 deletions ui-v2/tests/integration/serializers/session-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import { HEADERS_SYMBOL as META, HEADERS_DATACENTER as DC } from 'consul-ui/utils/http/consul';
module('Integration | Adapter | session | response', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
Expand Down Expand Up @@ -48,7 +48,9 @@ module('Integration | Adapter | session | response', function(hooks) {
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload[0], {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
},
Namespace: payload[0].Namespace || undefinedNspace,
uid: `["${payload[0].Namespace || undefinedNspace}","${dc}","${id}"]`,
});
Expand Down
11 changes: 9 additions & 2 deletions ui-v2/tests/integration/serializers/token-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { get } from 'consul-ui/tests/helpers/api';
import { HEADERS_SYMBOL as META } from 'consul-ui/utils/http/consul';
import {
HEADERS_SYMBOL as META,
HEADERS_DATACENTER as DC,
HEADERS_NAMESPACE as NSPACE,
} from 'consul-ui/utils/http/consul';

import { createPolicies } from 'consul-ui/tests/helpers/normalizers';

Expand Down Expand Up @@ -47,7 +51,10 @@ module('Integration | Serializer | token', function(hooks) {
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload, {
Datacenter: dc,
[META]: {},
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: payload.Namespace || undefinedNspace,
},
Namespace: payload.Namespace || undefinedNspace,
uid: `["${payload.Namespace || undefinedNspace}","${dc}","${id}"]`,
Policies: createPolicies(payload),
Expand Down
1 change: 1 addition & 0 deletions ui-v2/tests/integration/services/repository/node-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ test('findBySlug returns the correct data for item endpoint', function(assert) {
uid: `["${nspace}","${dc}","${item.ID}"]`,
meta: {
cursor: undefined,
dc: dc,
},
});
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const undefinedNspace = 'default';
service.Namespace = payload.Namespace;
service.meta = {
cursor: undefined,
dc: dc,
};

return service;
Expand Down
4 changes: 3 additions & 1 deletion ui-v2/tests/pages/components/page.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { clickable } from 'ember-cli-page-object';
export default {
const page = {
navigation: ['services', 'nodes', 'kvs', 'acls', 'intentions', 'docs', 'settings'].reduce(
function(prev, item, i, arr) {
const key = item;
Expand All @@ -23,3 +23,5 @@ export default {
}
),
};
page.navigation.dc = clickable('[data-test-toggle-button="datacenters"]');
export default page;
4 changes: 3 additions & 1 deletion ui-v2/tests/pages/dc/services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export default function(visitable, clickable, attribute, collection, page, filte
service: clickable('a'),
externalSource: attribute('data-test-external-source', 'a span'),
}),
dcs: collection('[data-test-datacenter-picker]'),
dcs: collection('[data-test-datacenter-picker]', {
name: clickable('a'),
}),
navigation: page.navigation,
filter: filter,
};
Expand Down
2 changes: 1 addition & 1 deletion ui-v2/tests/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function(assert, library, pages, utils) {
if (isNaN(parseInt(prop))) {
return (obj = obj[prop]);
} else {
return (obj = obj.objectAt(prop));
return (obj = obj.objectAt(parseInt(prop)));
}
}) && obj
);
Expand Down
Loading

0 comments on commit b043d57

Please sign in to comment.