summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/monitoring/stores/actions.js
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 18:42:06 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 18:42:06 +0000
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /app/assets/javascripts/monitoring/stores/actions.js
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
downloadgitlab-ce-6e4e1050d9dba2b7b2523fdd1768823ab85feef4.tar.gz
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'app/assets/javascripts/monitoring/stores/actions.js')
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js130
1 files changed, 84 insertions, 46 deletions
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index a441882a47d..16a685305dc 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -1,7 +1,7 @@
import * as Sentry from '@sentry/browser';
import * as types from './mutation_types';
import axios from '~/lib/utils/axios_utils';
-import createFlash from '~/flash';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
import {
gqClient,
@@ -13,16 +13,14 @@ import trackDashboardLoad from '../monitoring_tracking_helper';
import getEnvironments from '../queries/getEnvironments.query.graphql';
import getAnnotations from '../queries/getAnnotations.query.graphql';
import getDashboardValidationWarnings from '../queries/getDashboardValidationWarnings.query.graphql';
-import statusCodes from '../../lib/utils/http_status';
-import { backOff, convertObjectPropsToCamelCase } from '../../lib/utils/common_utils';
+import { convertObjectPropsToCamelCase } from '../../lib/utils/common_utils';
import { s__, sprintf } from '../../locale';
+import { getDashboard, getPrometheusQueryData } from '../requests';
-import {
- PROMETHEUS_TIMEOUT,
- ENVIRONMENT_AVAILABLE_STATE,
- DEFAULT_DASHBOARD_PATH,
- VARIABLE_TYPES,
-} from '../constants';
+import { ENVIRONMENT_AVAILABLE_STATE, OVERVIEW_DASHBOARD_PATH, VARIABLE_TYPES } from '../constants';
+
+const axiosCancelToken = axios.CancelToken;
+let cancelTokenSource;
function prometheusMetricQueryParams(timeRange) {
const { start, end } = convertToFixedRange(timeRange);
@@ -38,29 +36,18 @@ function prometheusMetricQueryParams(timeRange) {
};
}
-function backOffRequest(makeRequestCallback) {
- return backOff((next, stop) => {
- makeRequestCallback()
- .then(resp => {
- if (resp.status === statusCodes.NO_CONTENT) {
- next();
- } else {
- stop(resp);
- }
- })
- .catch(stop);
- }, PROMETHEUS_TIMEOUT);
-}
-
-function getPrometheusQueryData(prometheusEndpoint, params) {
- return backOffRequest(() => axios.get(prometheusEndpoint, { params }))
- .then(res => res.data)
- .then(response => {
- if (response.status === 'error') {
- throw new Error(response.error);
- }
- return response.data;
- });
+/**
+ * Extract error messages from API or HTTP request errors.
+ *
+ * - API errors are in `error.response.data.message`
+ * - HTTP (axios) errors are in `error.messsage`
+ *
+ * @param {Object} error
+ * @returns {String} User friendly error message
+ */
+function extractErrorMessage(error) {
+ const message = error?.response?.data?.message;
+ return message ?? error.message;
}
// Setup
@@ -126,8 +113,7 @@ export const fetchDashboard = ({ state, commit, dispatch, getters }) => {
params.dashboard = getters.fullDashboardPath;
}
- return backOffRequest(() => axios.get(state.dashboardEndpoint, { params }))
- .then(resp => resp.data)
+ return getDashboard(state.dashboardEndpoint, params)
.then(response => {
dispatch('receiveMetricsDashboardSuccess', { response });
/**
@@ -329,7 +315,7 @@ export const receiveEnvironmentsDataFailure = ({ commit }) => {
export const fetchAnnotations = ({ state, dispatch, getters }) => {
const { start } = convertToFixedRange(state.timeRange);
- const dashboardPath = getters.fullDashboardPath || DEFAULT_DASHBOARD_PATH;
+ const dashboardPath = getters.fullDashboardPath || OVERVIEW_DASHBOARD_PATH;
return gqClient
.mutate({
mutation: getAnnotations,
@@ -362,12 +348,12 @@ export const receiveAnnotationsFailure = ({ commit }) => commit(types.RECEIVE_AN
export const fetchDashboardValidationWarnings = ({ state, dispatch, getters }) => {
/**
- * Normally, the default dashboard won't throw any validation warnings.
+ * Normally, the overview dashboard won't throw any validation warnings.
*
- * However, if a bug sneaks into the default dashboard making it invalid,
+ * However, if a bug sneaks into the overview dashboard making it invalid,
* this might come handy for our clients
*/
- const dashboardPath = getters.fullDashboardPath || DEFAULT_DASHBOARD_PATH;
+ const dashboardPath = getters.fullDashboardPath || OVERVIEW_DASHBOARD_PATH;
return gqClient
.mutate({
mutation: getDashboardValidationWarnings,
@@ -484,12 +470,10 @@ export const fetchVariableMetricLabelValues = ({ state, commit }, { defaultQuery
if (variable.type === VARIABLE_TYPES.metric_label_values) {
const { prometheusEndpointPath, label } = variable.options;
- const optionsRequest = backOffRequest(() =>
- axios.get(prometheusEndpointPath, {
- params: { start_time, end_time },
- }),
- )
- .then(({ data }) => data.data)
+ const optionsRequest = getPrometheusQueryData(prometheusEndpointPath, {
+ start_time,
+ end_time,
+ })
.then(data => {
commit(types.UPDATE_VARIABLE_METRIC_LABEL_VALUES, { variable, label, data });
})
@@ -507,5 +491,59 @@ export const fetchVariableMetricLabelValues = ({ state, commit }, { defaultQuery
return Promise.all(optionsRequests);
};
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
+// Panel Builder
+
+export const setPanelPreviewTimeRange = ({ commit }, timeRange) => {
+ commit(types.SET_PANEL_PREVIEW_TIME_RANGE, timeRange);
+};
+
+export const fetchPanelPreview = ({ state, commit, dispatch }, panelPreviewYml) => {
+ if (!panelPreviewYml) {
+ return null;
+ }
+
+ commit(types.SET_PANEL_PREVIEW_IS_SHOWN, true);
+ commit(types.REQUEST_PANEL_PREVIEW, panelPreviewYml);
+
+ return axios
+ .post(state.panelPreviewEndpoint, { panel_yaml: panelPreviewYml })
+ .then(({ data }) => {
+ commit(types.RECEIVE_PANEL_PREVIEW_SUCCESS, data);
+
+ dispatch('fetchPanelPreviewMetrics');
+ })
+ .catch(error => {
+ commit(types.RECEIVE_PANEL_PREVIEW_FAILURE, extractErrorMessage(error));
+ });
+};
+
+export const fetchPanelPreviewMetrics = ({ state, commit }) => {
+ if (cancelTokenSource) {
+ cancelTokenSource.cancel();
+ }
+ cancelTokenSource = axiosCancelToken.source();
+
+ const defaultQueryParams = prometheusMetricQueryParams(state.panelPreviewTimeRange);
+
+ state.panelPreviewGraphData.metrics.forEach((metric, index) => {
+ commit(types.REQUEST_PANEL_PREVIEW_METRIC_RESULT, { index });
+
+ const params = { ...defaultQueryParams };
+ if (metric.step) {
+ params.step = metric.step;
+ }
+ return getPrometheusQueryData(metric.prometheusEndpointPath, params, {
+ cancelToken: cancelTokenSource.token,
+ })
+ .then(data => {
+ commit(types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS, { index, data });
+ })
+ .catch(error => {
+ Sentry.captureException(error);
+
+ commit(types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE, { index, error });
+ // Continue to throw error so the panel builder can notify using createFlash
+ throw error;
+ });
+ });
+};