Commit 23e378c5 authored by Dhiraj Bodicherla's avatar Dhiraj Bodicherla Committed by Paul Slaughter

Fix project-defined dashboard not rendering

Project defined dashboards display no data found
message even when there is data. Metrics in such
dashboards do not have metric_id. Added another
normalization step to add unique metric_id to all
metrics
parent 0f601842
import Vue from 'vue';
import * as types from './mutation_types';
import { normalizeMetrics, sortMetrics, normalizeQueryResult } from './utils';
import { normalizeMetrics, sortMetrics, normalizeMetric, normalizeQueryResult } from './utils';
const normalizePanel = panel => panel.metrics.map(normalizeMetric);
export default {
[types.REQUEST_METRICS_DATA](state) {
......@@ -9,13 +11,19 @@ export default {
},
[types.RECEIVE_METRICS_DATA_SUCCESS](state, groupData) {
state.groups = groupData.map(group => {
let { metrics } = group;
let { metrics = [], panels = [] } = group;
// each panel has metric information that needs to be normalized
panels = panels.map(panel => ({
...panel,
metrics: normalizePanel(panel),
}));
// for backwards compatibility, and to limit Vue template changes:
// for each group alias panels to metrics
// for each panel alias metrics to queries
if (state.useDashboardEndpoint) {
metrics = group.panels.map(panel => ({
metrics = panels.map(panel => ({
...panel,
queries: panel.metrics,
}));
......@@ -23,6 +31,7 @@ export default {
return {
...group,
panels,
metrics: normalizeMetrics(sortMetrics(metrics)),
};
});
......
......@@ -63,6 +63,25 @@ export function groupQueriesByChartInfo(metrics) {
return Object.values(metricsByChart);
}
export const uniqMetricsId = metric => `${metric.metric_id}_${metric.id}`;
/**
* Not to confuse with normalizeMetrics (plural)
* Metrics loaded from project-defined dashboards do not have a metric_id.
* This method creates a unique ID combining metric_id and id, if either is present.
* This is hopefully a temporary solution until BE processes metrics before passing to fE
* @param {Object} metric - metric
* @returns {Object} - normalized metric with a uniqueID
*/
export const normalizeMetric = (metric = {}) =>
_.omit(
{
...metric,
metric_id: uniqMetricsId(metric),
},
'id',
);
export const sortMetrics = metrics =>
_.chain(metrics)
.sortBy('title')
......
---
title: Fix project-defined metrics dashboards not rendering
merge_request: 16589
author:
type: fixed
......@@ -7,6 +7,7 @@ import {
metricsDashboardResponse,
dashboardGitResponse,
} from '../mock_data';
import { uniqMetricsId } from '~/monitoring/stores/utils';
describe('Monitoring mutations', () => {
let stateCopy;
......@@ -128,6 +129,7 @@ describe('Monitoring mutations', () => {
describe('SET_QUERY_RESULT', () => {
const metricId = 12;
const id = 'system_metrics_kubernetes_container_memory_total';
const result = [{ values: [[0, 1], [1, 1], [1, 3]] }];
beforeEach(() => {
......@@ -146,12 +148,13 @@ describe('Monitoring mutations', () => {
});
it('sets metricsWithData value', () => {
const uniqId = uniqMetricsId({ metric_id: metricId, id });
mutations[types.SET_QUERY_RESULT](stateCopy, {
metricId,
metricId: uniqId,
result,
});
expect(stateCopy.metricsWithData).toEqual([12]);
expect(stateCopy.metricsWithData).toEqual([uniqId]);
});
it('does not store empty results', () => {
......
import { groupQueriesByChartInfo } from '~/monitoring/stores/utils';
import { groupQueriesByChartInfo, normalizeMetric, uniqMetricsId } from '~/monitoring/stores/utils';
describe('groupQueriesByChartInfo', () => {
let input;
......@@ -12,7 +12,11 @@ describe('groupQueriesByChartInfo', () => {
];
output = [
{ title: 'title', y_label: 'MB', queries: [{ metricId: null }, { metricId: null }] },
{
title: 'title',
y_label: 'MB',
queries: [{ metricId: null }, { metricId: null }],
},
{ title: 'new title', y_label: 'MB', queries: [{ metricId: null }] },
];
......@@ -35,3 +39,36 @@ describe('groupQueriesByChartInfo', () => {
expect(groupQueriesByChartInfo(input)).toEqual(output);
});
});
describe('normalizeMetric', () => {
[
{ args: [], expected: 'undefined_undefined' },
{ args: [undefined], expected: 'undefined_undefined' },
{ args: [{ id: 'something' }], expected: 'undefined_something' },
{ args: [{ id: 45 }], expected: 'undefined_45' },
{ args: [{ metric_id: 5 }], expected: '5_undefined' },
{ args: [{ metric_id: 'something' }], expected: 'something_undefined' },
{
args: [{ metric_id: 5, id: 'system_metrics_kubernetes_container_memory_total' }],
expected: '5_system_metrics_kubernetes_container_memory_total',
},
].forEach(({ args, expected }) => {
it(`normalizes metric to "${expected}" with args=${JSON.stringify(args)}`, () => {
expect(normalizeMetric(...args)).toEqual({ metric_id: expected });
});
});
});
describe('uniqMetricsId', () => {
[
{ input: { id: 1 }, expected: 'undefined_1' },
{ input: { metric_id: 2 }, expected: '2_undefined' },
{ input: { metric_id: 2, id: 21 }, expected: '2_21' },
{ input: { metric_id: 22, id: 1 }, expected: '22_1' },
{ input: { metric_id: 'aaa', id: '_a' }, expected: 'aaa__a' },
].forEach(({ input, expected }) => {
it(`creates unique metric ID with ${JSON.stringify(input)}`, () => {
expect(uniqMetricsId(input)).toEqual(expected);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment