diff --git a/licenses.yaml b/licenses.yaml
index e684073d81d..465605fa4e3 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -4751,7 +4751,7 @@ license_category: binary
module: web-console
license_name: Apache License version 2.0
copyright: Imply Data
-version: 0.9.15
+version: 0.10.4
---
diff --git a/web-console/package-lock.json b/web-console/package-lock.json
index cd7673d0a2b..fccd993c3f0 100644
--- a/web-console/package-lock.json
+++ b/web-console/package-lock.json
@@ -4265,11 +4265,18 @@
}
},
"druid-query-toolkit": {
- "version": "0.9.15",
- "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.9.15.tgz",
- "integrity": "sha512-HiJVqa6X6z/LeEU3GVxbkaP/X8JCn/9n8txoG1tSgk6edc1BZXj7F7hZpaNlAThVcZcFOYeE1gFOHzMMjK4U0A==",
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.10.4.tgz",
+ "integrity": "sha512-feIRTC2paOkGpWvymseMs/wn+8XfbLjlcBsXJXKxgsJtqMKBYy3f8YiN3SV/xv6CQP9Vv4nBMEoa5q8OM5KHsg==",
"requires": {
- "tslib": "^1.10.0"
+ "tslib": "^2.0.2"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+ "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
+ }
}
},
"duplexer": {
diff --git a/web-console/package.json b/web-console/package.json
index f7cc8368063..c5c29f80082 100644
--- a/web-console/package.json
+++ b/web-console/package.json
@@ -68,7 +68,7 @@
"d3-axis": "^1.0.12",
"d3-scale": "^3.2.0",
"d3-selection": "^1.4.0",
- "druid-query-toolkit": "^0.9.15",
+ "druid-query-toolkit": "^0.10.4",
"file-saver": "^2.0.2",
"fontsource-open-sans": "^3.0.9",
"has-own-prop": "^2.0.0",
diff --git a/web-console/script/create-sql-docs.js b/web-console/script/create-sql-docs.js
index ce09be33c81..86ec0d70d75 100755
--- a/web-console/script/create-sql-docs.js
+++ b/web-console/script/create-sql-docs.js
@@ -61,7 +61,7 @@ const readDoc = async () => {
);
}
- // Make sure there are at least 5 data types for sanity
+ // Make sure there are at least 10 data types for sanity
if (dataTypeDocs.length < 10) {
throw new Error(
`Did not find enough data type entries did the structure of '${readfile}' change? (found ${dataTypeDocs.length})`,
diff --git a/web-console/src/bootstrap/ace.ts b/web-console/src/bootstrap/ace.ts
new file mode 100644
index 00000000000..f3689a14516
--- /dev/null
+++ b/web-console/src/bootstrap/ace.ts
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import 'brace'; // Import Ace editor and all the sub components used in the app
+import 'brace/ext/language_tools';
+import 'brace/theme/solarized_dark';
+
+import '../ace-modes/dsql';
+import '../ace-modes/hjson';
diff --git a/web-console/src/bootstrap/react-table-defaults.tsx b/web-console/src/bootstrap/react-table-defaults.tsx
index e397d3b9ea1..b85a0666063 100644
--- a/web-console/src/bootstrap/react-table-defaults.tsx
+++ b/web-console/src/bootstrap/react-table-defaults.tsx
@@ -24,37 +24,39 @@ import { booleanCustomTableFilter, countBy, makeTextFilter } from '../utils';
import { ReactTableCustomPagination } from './react-table-custom-pagination';
-export const NoData = React.memo(function NoData(props) {
+const NoData = React.memo(function NoData(props) {
const { children } = props;
if (!children) return null;
return
{children}
;
});
-Object.assign(ReactTableDefaults, {
- className: '-striped -highlight',
- defaultFilterMethod: (filter: Filter, row: any) => {
- const id = filter.pivotId || filter.id;
- return booleanCustomTableFilter(filter, row[id]);
- },
- LoadingComponent: Loader,
- loadingText: '',
- NoDataComponent: NoData,
- FilterComponent: makeTextFilter(),
- PaginationComponent: ReactTableCustomPagination,
- AggregatedComponent: (opt: any) => {
- const { subRows, column } = opt;
- const previewValues = subRows
- .filter((d: any) => typeof d[column.id] !== 'undefined')
- .map((row: any) => row[column.id]);
- const previewCount = countBy(previewValues);
- return (
-
- {Object.keys(previewCount)
- .sort()
- .map(v => `${v} (${previewCount[v]})`)
- .join(', ')}
-
- );
- },
- defaultPageSize: 20,
-});
+export function bootstrapReactTable() {
+ Object.assign(ReactTableDefaults, {
+ className: '-striped -highlight',
+ defaultFilterMethod: (filter: Filter, row: any) => {
+ const id = filter.pivotId || filter.id;
+ return booleanCustomTableFilter(filter, row[id]);
+ },
+ LoadingComponent: Loader,
+ loadingText: '',
+ NoDataComponent: NoData,
+ FilterComponent: makeTextFilter(),
+ PaginationComponent: ReactTableCustomPagination,
+ AggregatedComponent: (opt: any) => {
+ const { subRows, column } = opt;
+ const previewValues = subRows
+ .filter((d: any) => typeof d[column.id] !== 'undefined')
+ .map((row: any) => row[column.id]);
+ const previewCount = countBy(previewValues);
+ return (
+
+ {Object.keys(previewCount)
+ .sort()
+ .map(v => `${v} (${previewCount[v]})`)
+ .join(', ')}
+
+ );
+ },
+ defaultPageSize: 20,
+ });
+}
diff --git a/web-console/src/components/header-bar/header-bar.spec.tsx b/web-console/src/components/header-bar/header-bar.spec.tsx
index fc840320473..a5ca3dcb5a9 100644
--- a/web-console/src/components/header-bar/header-bar.spec.tsx
+++ b/web-console/src/components/header-bar/header-bar.spec.tsx
@@ -19,7 +19,7 @@
import { shallow } from 'enzyme';
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { HeaderBar } from './header-bar';
diff --git a/web-console/src/components/header-bar/header-bar.tsx b/web-console/src/components/header-bar/header-bar.tsx
index 01e48a88162..76bb378fe78 100644
--- a/web-console/src/components/header-bar/header-bar.tsx
+++ b/web-console/src/components/header-bar/header-bar.tsx
@@ -39,7 +39,7 @@ import {
OverlordDynamicConfigDialog,
} from '../../dialogs';
import { getLink } from '../../links';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { ExternalLink } from '../external-link/external-link';
import { PopoverText } from '../popover-text/popover-text';
diff --git a/web-console/src/components/segment-timeline/segment-timeline.spec.tsx b/web-console/src/components/segment-timeline/segment-timeline.spec.tsx
index 83440d31461..1a9e8f9252b 100644
--- a/web-console/src/components/segment-timeline/segment-timeline.spec.tsx
+++ b/web-console/src/components/segment-timeline/segment-timeline.spec.tsx
@@ -21,7 +21,7 @@ import { mount } from 'enzyme';
import React from 'react';
import { QueryManager } from '../../utils';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { SegmentTimeline } from './segment-timeline';
diff --git a/web-console/src/components/segment-timeline/segment-timeline.tsx b/web-console/src/components/segment-timeline/segment-timeline.tsx
index b928d15528d..4ccddcba648 100644
--- a/web-console/src/components/segment-timeline/segment-timeline.tsx
+++ b/web-console/src/components/segment-timeline/segment-timeline.tsx
@@ -17,12 +17,12 @@
*/
import { FormGroup, HTMLSelect, Radio, RadioGroup } from '@blueprintjs/core';
-import axios from 'axios';
import { AxisScale } from 'd3-axis';
import { scaleLinear, scaleTime } from 'd3-scale';
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Api } from '../../singletons';
+import { Capabilities } from '../../utils';
import { formatBytes, queryDruidSql, QueryManager, uniq } from '../../utils/index';
import { StackedBarChart } from '../../visualization/stacked-bar-chart';
import { Loader } from '../loader/loader';
@@ -266,10 +266,10 @@ ORDER BY "start" DESC`;
before.setMonth(before.getMonth() - timeSpan);
const beforeIso = before.toISOString();
- datasources = (await axios.get(`/druid/coordinator/v1/datasources`)).data;
+ datasources = (await Api.instance.get(`/druid/coordinator/v1/datasources`)).data;
intervals = (await Promise.all(
datasources.map(async datasource => {
- const intervalMap = (await axios.get(
+ const intervalMap = (await Api.instance.get(
`/druid/coordinator/v1/datasources/${datasource}/intervals?simple`,
)).data;
diff --git a/web-console/src/components/show-history/show-history.tsx b/web-console/src/components/show-history/show-history.tsx
index 9f55d299a92..a6086e66117 100644
--- a/web-console/src/components/show-history/show-history.tsx
+++ b/web-console/src/components/show-history/show-history.tsx
@@ -17,10 +17,10 @@
*/
import { Tab, Tabs } from '@blueprintjs/core';
-import axios from 'axios';
import React from 'react';
import { useQueryManager } from '../../hooks';
+import { Api } from '../../singletons';
import { Loader } from '../loader/loader';
import { ShowValue } from '../show-value/show-value';
@@ -41,7 +41,7 @@ export const ShowHistory = React.memo(function ShowHistory(props: ShowHistoryPro
const [historyState] = useQueryManager({
processQuery: async (endpoint: string) => {
- const resp = await axios.get(endpoint);
+ const resp = await Api.instance.get(endpoint);
return resp.data;
},
initQuery: endpoint,
diff --git a/web-console/src/components/show-json/show-json.tsx b/web-console/src/components/show-json/show-json.tsx
index c178afcce84..726fc1fac25 100644
--- a/web-console/src/components/show-json/show-json.tsx
+++ b/web-console/src/components/show-json/show-json.tsx
@@ -17,13 +17,11 @@
*/
import { Button, ButtonGroup, Intent, TextArea } from '@blueprintjs/core';
-import axios from 'axios';
import copy from 'copy-to-clipboard';
import React from 'react';
import { useQueryManager } from '../../hooks';
-import { AppToaster } from '../../singletons/toaster';
-import { UrlBaser } from '../../singletons/url-baser';
+import { Api, AppToaster, UrlBaser } from '../../singletons';
import { downloadFile } from '../../utils';
import { Loader } from '../loader/loader';
@@ -40,7 +38,7 @@ export const ShowJson = React.memo(function ShowJson(props: ShowJsonProps) {
const [jsonState] = useQueryManager({
processQuery: async () => {
- const resp = await axios.get(endpoint);
+ const resp = await Api.instance.get(endpoint);
let data = resp.data;
if (transform) data = transform(data);
return typeof data === 'string' ? data : JSON.stringify(data, undefined, 2);
diff --git a/web-console/src/components/show-log/show-log.tsx b/web-console/src/components/show-log/show-log.tsx
index a4409d2c464..e9d248cc4e7 100644
--- a/web-console/src/components/show-log/show-log.tsx
+++ b/web-console/src/components/show-log/show-log.tsx
@@ -17,13 +17,11 @@
*/
import { AnchorButton, Button, ButtonGroup, Intent, Switch } from '@blueprintjs/core';
-import axios from 'axios';
import copy from 'copy-to-clipboard';
import React from 'react';
import { Loader } from '../../components';
-import { AppToaster } from '../../singletons/toaster';
-import { UrlBaser } from '../../singletons/url-baser';
+import { Api, AppToaster, UrlBaser } from '../../singletons';
import { QueryManager, QueryState } from '../../utils';
import './show-log.scss';
@@ -65,7 +63,9 @@ export class ShowLog extends React.PureComponent {
this.showLogQueryManager = new QueryManager({
processQuery: async () => {
const { endpoint, tailOffset } = this.props;
- const resp = await axios.get(endpoint + (tailOffset ? `?offset=-${tailOffset}` : ''));
+ const resp = await Api.instance.get(
+ endpoint + (tailOffset ? `?offset=-${tailOffset}` : ''),
+ );
const data = resp.data;
let logValue = typeof data === 'string' ? data : JSON.stringify(data, undefined, 2);
diff --git a/web-console/src/components/show-value/show-value.tsx b/web-console/src/components/show-value/show-value.tsx
index 59afd2f07de..d41bdb52852 100644
--- a/web-console/src/components/show-value/show-value.tsx
+++ b/web-console/src/components/show-value/show-value.tsx
@@ -19,7 +19,7 @@
import { Button, ButtonGroup, TextArea } from '@blueprintjs/core';
import React from 'react';
-import { UrlBaser } from '../../singletons/url-baser';
+import { UrlBaser } from '../../singletons';
import { downloadFile } from '../../utils';
import './show-value.scss';
diff --git a/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.tsx b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.tsx
index a8c5383bc08..f7514a64189 100644
--- a/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.tsx
+++ b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.tsx
@@ -17,12 +17,11 @@
*/
import { Button, ButtonGroup } from '@blueprintjs/core';
-import axios from 'axios';
import React from 'react';
import ReactTable, { CellInfo, Column } from 'react-table';
import { useQueryManager } from '../../hooks';
-import { UrlBaser } from '../../singletons/url-baser';
+import { Api, UrlBaser } from '../../singletons';
import { deepGet } from '../../utils';
import { Loader } from '../loader/loader';
@@ -65,7 +64,7 @@ export const SupervisorStatisticsTable = React.memo(function SupervisorStatistic
const [supervisorStatisticsState] = useQueryManager({
processQuery: async () => {
- const resp = await axios.get(endpoint);
+ const resp = await Api.instance.get(endpoint);
return normalizeSupervisorStatisticsResults(resp.data);
},
initQuery: null,
diff --git a/web-console/src/console-application.tsx b/web-console/src/console-application.tsx
index c09100a6a77..84d8a3385ac 100644
--- a/web-console/src/console-application.tsx
+++ b/web-console/src/console-application.tsx
@@ -23,9 +23,8 @@ import React from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
import { HeaderActiveTab, HeaderBar, Loader } from './components';
-import { AppToaster } from './singletons/toaster';
-import { QueryManager } from './utils';
-import { Capabilities } from './utils/capabilities';
+import { AppToaster } from './singletons';
+import { Capabilities, QueryManager } from './utils';
import {
DatasourcesView,
HomeView,
diff --git a/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx b/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx
index 7e07d467a70..ada4620e58f 100644
--- a/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx
+++ b/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx
@@ -31,7 +31,7 @@ import classNames from 'classnames';
import React, { ReactNode, useState } from 'react';
import { WarningChecklist } from '../../components/warning-checklist/warning-checklist';
-import { AppToaster } from '../../singletons/toaster';
+import { AppToaster } from '../../singletons';
import './async-action-dialog.scss';
diff --git a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx
index 0ec905463a1..83538dd82c1 100644
--- a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx
+++ b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx
@@ -18,7 +18,6 @@
import { Intent } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React, { useState } from 'react';
import { SnitchDialog } from '..';
@@ -32,7 +31,7 @@ import {
import { COORDINATOR_DYNAMIC_CONFIG_FIELDS, CoordinatorDynamicConfig } from '../../druid-models';
import { useQueryManager } from '../../hooks';
import { getLink } from '../../links';
-import { AppToaster } from '../../singletons/toaster';
+import { Api, AppToaster } from '../../singletons';
import { getDruidErrorMessage } from '../../utils';
import './coordinator-dynamic-config-dialog.scss';
@@ -50,7 +49,7 @@ export const CoordinatorDynamicConfigDialog = React.memo(function CoordinatorDyn
const [historyRecordsState] = useQueryManager({
processQuery: async () => {
- const historyResp = await axios(`/druid/coordinator/v1/config/history?count=100`);
+ const historyResp = await Api.instance.get(`/druid/coordinator/v1/config/history?count=100`);
return historyResp.data;
},
initQuery: null,
@@ -59,7 +58,7 @@ export const CoordinatorDynamicConfigDialog = React.memo(function CoordinatorDyn
useQueryManager>({
processQuery: async () => {
try {
- const configResp = await axios.get('/druid/coordinator/v1/config');
+ const configResp = await Api.instance.get('/druid/coordinator/v1/config');
setDynamicConfig(configResp.data || {});
} catch (e) {
AppToaster.show({
@@ -77,7 +76,7 @@ export const CoordinatorDynamicConfigDialog = React.memo(function CoordinatorDyn
async function saveConfig(comment: string) {
try {
- await axios.post('/druid/coordinator/v1/config', dynamicConfig, {
+ await Api.instance.post('/druid/coordinator/v1/config', dynamicConfig, {
headers: {
'X-Druid-Author': 'console',
'X-Druid-Comment': comment,
diff --git a/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx b/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx
index a5ecb853616..4fea19b9b3b 100644
--- a/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx
+++ b/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx
@@ -16,8 +16,7 @@
* limitations under the License.
*/
-import axios from 'axios';
-
+import { Api } from '../../singletons';
import { deepGet, pluralIfNeeded, queryDruidSql } from '../../utils';
import { postToSampler } from '../../utils/sampler';
@@ -56,7 +55,7 @@ export const DOCTOR_CHECKS: DoctorCheck[] = [
// Make sure that the router responds to /status and gives some valid info back
let status: any;
try {
- status = (await axios.get(`/status`)).data;
+ status = (await Api.instance.get(`/status`)).data;
} catch (e) {
controls.addIssue(
`Did not get a /status response from the Router service. Try confirming that it is running and accessible. Got: ${e.message}`,
@@ -76,7 +75,7 @@ export const DOCTOR_CHECKS: DoctorCheck[] = [
// Make sure that everything in /status/properties is above board
let properties: Record;
try {
- properties = (await axios.get(`/status/properties`)).data;
+ properties = (await Api.instance.get(`/status/properties`)).data;
} catch (e) {
controls.addIssue(
`Did not get a /status/properties response from the Router. Message: ${e.message}`,
@@ -126,14 +125,14 @@ export const DOCTOR_CHECKS: DoctorCheck[] = [
// Make sure that everything in Coordinator's /status is good
let myStatus: any;
try {
- myStatus = (await axios.get(`/status`)).data;
+ myStatus = (await Api.instance.get(`/status`)).data;
} catch {
return;
}
let coordinatorStatus: any;
try {
- coordinatorStatus = (await axios.get(`/proxy/coordinator/status`)).data;
+ coordinatorStatus = (await Api.instance.get(`/proxy/coordinator/status`)).data;
} catch (e) {
controls.addIssue(
'Did not get a /status response from the Coordinator service. Try confirming that it is running and accessible.',
@@ -143,7 +142,7 @@ export const DOCTOR_CHECKS: DoctorCheck[] = [
let overlordStatus: any;
try {
- overlordStatus = (await axios.get(`/proxy/overlord/status`)).data;
+ overlordStatus = (await Api.instance.get(`/proxy/overlord/status`)).data;
} catch (e) {
controls.addIssue(
'Did not get a /status response from the Overlord service. Try confirming that it is running and accessible.',
@@ -170,14 +169,15 @@ export const DOCTOR_CHECKS: DoctorCheck[] = [
// Make sure that everything in coordinator and overlord /status/properties is good and matches where needed
let myProperties: Record;
try {
- myProperties = (await axios.get(`/status/properties`)).data;
+ myProperties = (await Api.instance.get(`/status/properties`)).data;
} catch {
return;
}
let coordinatorProperties: Record;
try {
- coordinatorProperties = (await axios.get(`/proxy/coordinator/status/properties`)).data;
+ coordinatorProperties = (await Api.instance.get(`/proxy/coordinator/status/properties`))
+ .data;
} catch (e) {
controls.addIssue(
'Did not get a /status response from the coordinator. Try confirming that it is running and accessible.',
@@ -187,7 +187,7 @@ export const DOCTOR_CHECKS: DoctorCheck[] = [
let overlordProperties: Record;
try {
- overlordProperties = (await axios.get(`/proxy/overlord/status/properties`)).data;
+ overlordProperties = (await Api.instance.get(`/proxy/overlord/status/properties`)).data;
} catch (e) {
controls.addIssue(
'Did not get a /status response from the overlord. Try confirming that it is running and accessible.',
@@ -384,7 +384,8 @@ ORDER BY "num_bad_time_chunks"`,
// Grab the auto-compaction definitions and ignore dataSources that already have auto-compaction
let compactionResult: any;
try {
- compactionResult = (await axios.get('/druid/coordinator/v1/config/compaction')).data;
+ compactionResult = (await Api.instance.get('/druid/coordinator/v1/config/compaction'))
+ .data;
} catch (e) {
controls.addIssue(`Could not get compaction config. Something is wrong.`);
return;
diff --git a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx
index d54cba60521..81fcafd3b45 100644
--- a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx
+++ b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx
@@ -18,7 +18,6 @@
import { Intent } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React, { useState } from 'react';
import { SnitchDialog } from '..';
@@ -26,7 +25,7 @@ import { AutoForm, ExternalLink } from '../../components';
import { OVERLORD_DYNAMIC_CONFIG_FIELDS, OverlordDynamicConfig } from '../../druid-models';
import { useQueryManager } from '../../hooks';
import { getLink } from '../../links';
-import { AppToaster } from '../../singletons/toaster';
+import { Api, AppToaster } from '../../singletons';
import { getDruidErrorMessage } from '../../utils';
import './overlord-dynamic-config-dialog.scss';
@@ -43,7 +42,7 @@ export const OverlordDynamicConfigDialog = React.memo(function OverlordDynamicCo
const [historyRecordsState] = useQueryManager({
processQuery: async () => {
- const historyResp = await axios(`/druid/indexer/v1/worker/history?count=100`);
+ const historyResp = await Api.instance.get(`/druid/indexer/v1/worker/history?count=100`);
return historyResp.data;
},
initQuery: null,
@@ -52,7 +51,7 @@ export const OverlordDynamicConfigDialog = React.memo(function OverlordDynamicCo
useQueryManager>({
processQuery: async () => {
try {
- const configResp = await axios(`/druid/indexer/v1/worker`);
+ const configResp = await Api.instance.get(`/druid/indexer/v1/worker`);
setDynamicConfig(configResp.data || {});
} catch (e) {
AppToaster.show({
@@ -70,7 +69,7 @@ export const OverlordDynamicConfigDialog = React.memo(function OverlordDynamicCo
async function saveConfig(comment: string) {
try {
- await axios.post('/druid/indexer/v1/worker', dynamicConfig, {
+ await Api.instance.post('/druid/indexer/v1/worker', dynamicConfig, {
headers: {
'X-Druid-Author': 'console',
'X-Druid-Comment': comment,
diff --git a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
index 4e9819540b1..c11d345a759 100644
--- a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
+++ b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
@@ -18,13 +18,13 @@
import { Button, Divider, FormGroup } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React, { useState } from 'react';
import { SnitchDialog } from '..';
import { ExternalLink, RuleEditor } from '../../components';
import { useQueryManager } from '../../hooks';
import { getLink } from '../../links';
+import { Api } from '../../singletons';
import { swapElements } from '../../utils';
import { Rule, RuleUtil } from '../../utils/load-rule';
@@ -46,7 +46,9 @@ export const RetentionDialog = React.memo(function RetentionDialog(props: Retent
const [historyQueryState] = useQueryManager({
processQuery: async datasource => {
- const historyResp = await axios(`/druid/coordinator/v1/rules/${datasource}/history`);
+ const historyResp = await Api.instance.get(
+ `/druid/coordinator/v1/rules/${datasource}/history`,
+ );
return historyResp.data;
},
initQuery: props.datasource,
diff --git a/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx b/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx
index 504c7a75e4f..e6adc16c0f7 100644
--- a/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx
+++ b/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx
@@ -21,7 +21,7 @@ import { IconNames } from '@blueprintjs/icons';
import copy from 'copy-to-clipboard';
import React from 'react';
-import { AppToaster } from '../../singletons/toaster';
+import { AppToaster } from '../../singletons';
import './show-value-dialog.scss';
diff --git a/web-console/src/dialogs/status-dialog/status-dialog.tsx b/web-console/src/dialogs/status-dialog/status-dialog.tsx
index 5d6aac55572..356895b6e82 100644
--- a/web-console/src/dialogs/status-dialog/status-dialog.tsx
+++ b/web-console/src/dialogs/status-dialog/status-dialog.tsx
@@ -17,13 +17,12 @@
*/
import { Button, Classes, Dialog, Intent } from '@blueprintjs/core';
-import axios from 'axios';
import React from 'react';
import ReactTable, { Filter } from 'react-table';
import { Loader } from '../../components';
import { useQueryManager } from '../../hooks';
-import { UrlBaser } from '../../singletons/url-baser';
+import { Api, UrlBaser } from '../../singletons';
import './status-dialog.scss';
@@ -50,7 +49,7 @@ export const StatusDialog = React.memo(function StatusDialog(props: StatusDialog
const { onClose } = props;
const [responseState] = useQueryManager({
processQuery: async () => {
- const resp = await axios.get(`/status`);
+ const resp = await Api.instance.get(`/status`);
return resp.data;
},
initQuery: null,
diff --git a/web-console/src/entry.ts b/web-console/src/entry.ts
index bebb5ff71bd..45fe09364b9 100644
--- a/web-console/src/entry.ts
+++ b/web-console/src/entry.ts
@@ -16,24 +16,22 @@
* limitations under the License.
*/
-import axios from 'axios';
-import 'brace'; // Import Ace editor and all the sub components used in the app
-import 'brace/ext/language_tools';
-import 'brace/theme/solarized_dark';
+import { AxiosRequestConfig } from 'axios';
import 'core-js/stable';
import React from 'react';
import ReactDOM from 'react-dom';
import 'regenerator-runtime/runtime';
-import './ace-modes/dsql';
-import './ace-modes/hjson';
-import './bootstrap/react-table-defaults';
+import './bootstrap/ace';
+import { bootstrapReactTable } from './bootstrap/react-table-defaults';
import { ConsoleApplication } from './console-application';
import { Links, setLinkOverrides } from './links';
-import { UrlBaser } from './singletons/url-baser';
+import { Api, UrlBaser } from './singletons';
import './entry.scss';
+bootstrapReactTable();
+
const container = document.getElementsByClassName('app-container')[0];
if (!container) throw new Error('container not found');
@@ -69,16 +67,23 @@ if (typeof consoleConfig.title === 'string') {
window.document.title = consoleConfig.title;
}
+const apiConfig: AxiosRequestConfig = {
+ headers: {},
+};
+
if (consoleConfig.baseURL) {
- axios.defaults.baseURL = consoleConfig.baseURL;
+ apiConfig.baseURL = consoleConfig.baseURL;
UrlBaser.baseUrl = consoleConfig.baseURL;
}
if (consoleConfig.customHeaderName && consoleConfig.customHeaderValue) {
- axios.defaults.headers.common[consoleConfig.customHeaderName] = consoleConfig.customHeaderValue;
+ apiConfig.headers.common[consoleConfig.customHeaderName] = consoleConfig.customHeaderValue;
}
if (consoleConfig.customHeaders) {
- Object.assign(axios.defaults.headers, consoleConfig.customHeaders);
+ Object.assign(apiConfig.headers, consoleConfig.customHeaders);
}
+
+Api.initialize(apiConfig);
+
if (consoleConfig.linkOverrides) {
setLinkOverrides(consoleConfig.linkOverrides);
}
diff --git a/web-console/src/setup-tests.ts b/web-console/src/setup-tests.ts
index 9f60d0444f8..e52845b6018 100644
--- a/web-console/src/setup-tests.ts
+++ b/web-console/src/setup-tests.ts
@@ -20,7 +20,7 @@ import 'core-js/stable';
import { configure } from 'enzyme';
import enzymeAdapterReact16 from 'enzyme-adapter-react-16';
-import { UrlBaser } from './singletons/url-baser';
+import { UrlBaser } from './singletons';
configure({ adapter: new (enzymeAdapterReact16 as any)() });
diff --git a/web-console/src/singletons/api.ts b/web-console/src/singletons/api.ts
new file mode 100644
index 00000000000..1e8f53750d3
--- /dev/null
+++ b/web-console/src/singletons/api.ts
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
+
+export class Api {
+ static instance: AxiosInstance;
+
+ static initialize(config?: AxiosRequestConfig): void {
+ Api.instance = axios.create(config);
+ }
+}
diff --git a/web-console/src/singletons/index.ts b/web-console/src/singletons/index.ts
new file mode 100644
index 00000000000..bf21dfcfe8a
--- /dev/null
+++ b/web-console/src/singletons/index.ts
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export * from './api';
+export * from './toaster';
+export * from './url-baser';
diff --git a/web-console/src/utils/capabilities.ts b/web-console/src/utils/capabilities.ts
index 738c3a70787..96c01ab5f11 100644
--- a/web-console/src/utils/capabilities.ts
+++ b/web-console/src/utils/capabilities.ts
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-import axios from 'axios';
+import { Api } from '../singletons';
import { localStorageGetJson, LocalStorageKeys } from './local-storage-keys';
@@ -51,7 +51,7 @@ export class Capabilities {
static async detectQueryType(): Promise {
// Check SQL endpoint
try {
- await axios.post(
+ await Api.instance.post(
'/druid/v2/sql',
{ query: 'SELECT 1337', context: { timeout: Capabilities.STATUS_TIMEOUT } },
{ timeout: Capabilities.STATUS_TIMEOUT },
@@ -62,14 +62,14 @@ export class Capabilities {
return; // other failure
}
try {
- await axios.get('/status', { timeout: Capabilities.STATUS_TIMEOUT });
+ await Api.instance.get('/status', { timeout: Capabilities.STATUS_TIMEOUT });
} catch (e) {
return; // total failure
}
// Status works but SQL 405s => the SQL endpoint is disabled
try {
- await axios.post(
+ await Api.instance.post(
'/druid/v2',
{
queryType: 'dataSourceMetadata',
@@ -94,7 +94,7 @@ export class Capabilities {
static async detectNode(node: 'coordinator' | 'overlord'): Promise {
try {
- await axios.get(`/druid/${node === 'overlord' ? 'indexer' : node}/v1/isLeader`, {
+ await Api.instance.get(`/druid/${node === 'overlord' ? 'indexer' : node}/v1/isLeader`, {
timeout: Capabilities.STATUS_TIMEOUT,
});
} catch (e) {
diff --git a/web-console/src/utils/druid-query.ts b/web-console/src/utils/druid-query.ts
index d0865c1bad7..8940332ea79 100644
--- a/web-console/src/utils/druid-query.ts
+++ b/web-console/src/utils/druid-query.ts
@@ -16,8 +16,9 @@
* limitations under the License.
*/
-import axios from 'axios';
-import { AxiosResponse } from 'axios';
+import axios, { AxiosResponse } from 'axios';
+
+import { Api } from '../singletons';
import { assemble } from './general';
import { RowColumn } from './query-cursor';
@@ -213,7 +214,7 @@ export class DruidError extends Error {
export async function queryDruidRune(runeQuery: Record): Promise {
let runeResultResp: AxiosResponse;
try {
- runeResultResp = await axios.post('/druid/v2', runeQuery);
+ runeResultResp = await Api.instance.post('/druid/v2', runeQuery);
} catch (e) {
throw new Error(getDruidErrorMessage(e));
}
@@ -223,7 +224,7 @@ export async function queryDruidRune(runeQuery: Record): Promise(sqlQueryPayload: Record): Promise {
let sqlResultResp: AxiosResponse;
try {
- sqlResultResp = await axios.post('/druid/v2/sql', sqlQueryPayload);
+ sqlResultResp = await Api.instance.post('/druid/v2/sql', sqlQueryPayload);
} catch (e) {
throw new Error(getDruidErrorMessage(e));
}
diff --git a/web-console/src/utils/general.tsx b/web-console/src/utils/general.tsx
index 9ce6e6186e8..8783f084841 100644
--- a/web-console/src/utils/general.tsx
+++ b/web-console/src/utils/general.tsx
@@ -26,7 +26,7 @@ import numeral from 'numeral';
import React from 'react';
import { Filter, FilterRender } from 'react-table';
-import { AppToaster } from '../singletons/toaster';
+import { AppToaster } from '../singletons';
// These constants are used to make sure that they are not constantly recreated thrashing the pure components
export const EMPTY_OBJECT: any = {};
diff --git a/web-console/src/utils/sampler.ts b/web-console/src/utils/sampler.ts
index 4a888600b84..5f8b97eb34e 100644
--- a/web-console/src/utils/sampler.ts
+++ b/web-console/src/utils/sampler.ts
@@ -16,8 +16,6 @@
* limitations under the License.
*/
-import axios from 'axios';
-
import {
DimensionsSpec,
getSpecType,
@@ -34,6 +32,7 @@ import {
TransformSpec,
upgradeSpec,
} from '../druid-models';
+import { Api } from '../singletons';
import { getDruidErrorMessage, queryDruidRune } from './druid-query';
import {
@@ -181,7 +180,7 @@ export function headerAndRowsFromSampleResponse(
export async function getProxyOverlordModules(): Promise {
let statusResp: any;
try {
- statusResp = await axios.get(`/proxy/overlord/status`);
+ statusResp = await Api.instance.get(`/proxy/overlord/status`);
} catch (e) {
throw new Error(getDruidErrorMessage(e));
}
@@ -197,7 +196,7 @@ export async function postToSampler(
let sampleResp: any;
try {
- sampleResp = await axios.post(`${SAMPLER_URL}?for=${forStr}`, sampleSpec);
+ sampleResp = await Api.instance.post(`${SAMPLER_URL}?for=${forStr}`, sampleSpec);
} catch (e) {
throw new Error(getDruidErrorMessage(e));
}
diff --git a/web-console/src/views/datasource-view/datasource-view.spec.tsx b/web-console/src/views/datasource-view/datasource-view.spec.tsx
index 138337dc49e..952d51ffffa 100644
--- a/web-console/src/views/datasource-view/datasource-view.spec.tsx
+++ b/web-console/src/views/datasource-view/datasource-view.spec.tsx
@@ -19,7 +19,7 @@
import { shallow } from 'enzyme';
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { DatasourcesView } from './datasource-view';
diff --git a/web-console/src/views/datasource-view/datasource-view.tsx b/web-console/src/views/datasource-view/datasource-view.tsx
index 8b7e7f8bc88..678f98487f4 100644
--- a/web-console/src/views/datasource-view/datasource-view.tsx
+++ b/web-console/src/views/datasource-view/datasource-view.tsx
@@ -18,7 +18,6 @@
import { FormGroup, InputGroup, Intent, MenuItem, Switch } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import classNames from 'classnames';
import { SqlQuery, SqlRef } from 'druid-query-toolkit';
import React from 'react';
@@ -45,7 +44,7 @@ import {
formatCompactionConfigAndStatus,
zeroCompactionStatus,
} from '../../druid-models';
-import { AppToaster } from '../../singletons/toaster';
+import { Api, AppToaster } from '../../singletons';
import {
addFilter,
Capabilities,
@@ -317,8 +316,10 @@ GROUP BY 1`;
if (capabilities.hasSql()) {
datasources = await queryDruidSql({ query: DatasourcesView.DATASOURCE_SQL });
} else if (capabilities.hasCoordinatorAccess()) {
- const datasourcesResp = await axios.get('/druid/coordinator/v1/datasources?simple');
- const loadstatusResp = await axios.get('/druid/coordinator/v1/loadstatus?simple');
+ const datasourcesResp = await Api.instance.get(
+ '/druid/coordinator/v1/datasources?simple',
+ );
+ const loadstatusResp = await Api.instance.get('/druid/coordinator/v1/loadstatus?simple');
const loadstatus = loadstatusResp.data;
datasources = datasourcesResp.data.map(
(d: any): DatasourceQueryResultRow => {
@@ -367,22 +368,26 @@ GROUP BY 1`;
if (this.state.showUnused) {
// Using 'includeDisabled' parameter for compatibility.
// Should be changed to 'includeUnused' in Druid 0.17
- const unusedResp = await axios.get(
+ const unusedResp = await Api.instance.get(
'/druid/coordinator/v1/metadata/datasources?includeDisabled',
);
unused = unusedResp.data.filter((d: string) => !seen[d]);
}
- const rulesResp = await axios.get('/druid/coordinator/v1/rules');
+ const rulesResp = await Api.instance.get('/druid/coordinator/v1/rules');
const rules = rulesResp.data;
- const compactionConfigsResp = await axios.get('/druid/coordinator/v1/config/compaction');
+ const compactionConfigsResp = await Api.instance.get(
+ '/druid/coordinator/v1/config/compaction',
+ );
const compactionConfigs = lookupBy(
compactionConfigsResp.data.compactionConfigs || [],
(c: CompactionConfig) => c.dataSource,
);
- const compactionStatusesResp = await axios.get('/druid/coordinator/v1/compaction/status');
+ const compactionStatusesResp = await Api.instance.get(
+ '/druid/coordinator/v1/compaction/status',
+ );
const compactionStatuses = lookupBy(
compactionStatusesResp.data.latestStatus || [],
(c: CompactionStatus) => c.dataSource,
@@ -412,7 +417,7 @@ GROUP BY 1`;
this.tiersQueryManager = new QueryManager({
processQuery: async capabilities => {
if (capabilities.hasCoordinatorAccess()) {
- const tiersResp = await axios.get('/druid/coordinator/v1/tiers');
+ const tiersResp = await Api.instance.get('/druid/coordinator/v1/tiers');
return tiersResp.data;
} else {
throw new Error(`must have coordinator access`);
@@ -455,7 +460,7 @@ GROUP BY 1`;
return (
{
- const resp = await axios.delete(
+ const resp = await Api.instance.delete(
`/druid/coordinator/v1/datasources/${datasourceToMarkAsUnusedAllSegmentsIn}`,
{},
);
@@ -486,7 +491,7 @@ GROUP BY 1`;
return (
{
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/coordinator/v1/datasources/${datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn}`,
{},
);
@@ -518,7 +523,7 @@ GROUP BY 1`;
action={async () => {
if (!useUnuseInterval) return;
const param = isUse ? 'markUsed' : 'markUnused';
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/coordinator/v1/datasources/${datasourceToMarkSegmentsByIntervalIn}/${param}`,
{
interval: useUnuseInterval,
@@ -560,7 +565,7 @@ GROUP BY 1`;
return (
{
- const resp = await axios.delete(
+ const resp = await Api.instance.delete(
`/druid/coordinator/v1/datasources/${killDatasource}?kill=true&interval=1000/3000`,
{},
);
@@ -628,7 +633,7 @@ GROUP BY 1`;
return (
{
- const resp = await axios.post(`/druid/coordinator/v1/compaction/compact`, {});
+ const resp = await Api.instance.post(`/druid/coordinator/v1/compaction/compact`, {});
return resp.data;
}}
confirmButtonText="Force compaction run"
@@ -648,7 +653,7 @@ GROUP BY 1`;
private saveRules = async (datasource: string, rules: Rule[], comment: string) => {
try {
- await axios.post(`/druid/coordinator/v1/rules/${datasource}`, rules, {
+ await Api.instance.post(`/druid/coordinator/v1/rules/${datasource}`, rules, {
headers: {
'X-Druid-Author': 'console',
'X-Druid-Comment': comment,
@@ -689,7 +694,7 @@ GROUP BY 1`;
private saveCompaction = async (compactionConfig: any) => {
if (!compactionConfig) return;
try {
- await axios.post(`/druid/coordinator/v1/config/compaction`, compactionConfig);
+ await Api.instance.post(`/druid/coordinator/v1/config/compaction`, compactionConfig);
this.setState({ compactionDialogOpenOn: undefined });
this.datasourceQueryManager.rerunLastQuery();
} catch (e) {
@@ -711,7 +716,7 @@ GROUP BY 1`;
text: 'Confirm',
onClick: async () => {
try {
- await axios.delete(`/druid/coordinator/v1/config/compaction/${datasource}`);
+ await Api.instance.delete(`/druid/coordinator/v1/config/compaction/${datasource}`);
this.setState({ compactionDialogOpenOn: undefined }, () =>
this.datasourceQueryManager.rerunLastQuery(),
);
diff --git a/web-console/src/views/home-view/datasources-card/datasources-card.spec.tsx b/web-console/src/views/home-view/datasources-card/datasources-card.spec.tsx
index 9195c62ad12..b19a901a9bb 100644
--- a/web-console/src/views/home-view/datasources-card/datasources-card.spec.tsx
+++ b/web-console/src/views/home-view/datasources-card/datasources-card.spec.tsx
@@ -19,7 +19,7 @@
import { render } from '@testing-library/react';
import React from 'react';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { DatasourcesCard } from './datasources-card';
diff --git a/web-console/src/views/home-view/datasources-card/datasources-card.tsx b/web-console/src/views/home-view/datasources-card/datasources-card.tsx
index c8ec31a3e95..dfcdefd5526 100644
--- a/web-console/src/views/home-view/datasources-card/datasources-card.tsx
+++ b/web-console/src/views/home-view/datasources-card/datasources-card.tsx
@@ -17,12 +17,12 @@
*/
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React from 'react';
import { useQueryManager } from '../../../hooks';
+import { Api } from '../../../singletons';
import { pluralIfNeeded, queryDruidSql } from '../../../utils';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { HomeViewCard } from '../home-view-card/home-view-card';
export interface DatasourcesCardProps {
@@ -38,7 +38,7 @@ export const DatasourcesCard = React.memo(function DatasourcesCard(props: Dataso
query: `SELECT datasource FROM sys.segments GROUP BY 1`,
});
} else if (capabilities.hasCoordinatorAccess()) {
- const datasourcesResp = await axios.get('/druid/coordinator/v1/datasources');
+ const datasourcesResp = await Api.instance.get('/druid/coordinator/v1/datasources');
datasources = datasourcesResp.data;
} else {
throw new Error(`must have SQL or coordinator access`);
diff --git a/web-console/src/views/home-view/home-view.spec.tsx b/web-console/src/views/home-view/home-view.spec.tsx
index a2820e890cc..65059ebbe10 100644
--- a/web-console/src/views/home-view/home-view.spec.tsx
+++ b/web-console/src/views/home-view/home-view.spec.tsx
@@ -19,7 +19,7 @@
import { shallow } from 'enzyme';
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { HomeView } from './home-view';
diff --git a/web-console/src/views/home-view/home-view.tsx b/web-console/src/views/home-view/home-view.tsx
index 7a3279d5ed9..29295236daa 100644
--- a/web-console/src/views/home-view/home-view.tsx
+++ b/web-console/src/views/home-view/home-view.tsx
@@ -18,7 +18,7 @@
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { DatasourcesCard } from './datasources-card/datasources-card';
import { LookupsCard } from './lookups-card/lookups-card';
diff --git a/web-console/src/views/home-view/lookups-card/lookups-card.spec.tsx b/web-console/src/views/home-view/lookups-card/lookups-card.spec.tsx
index 2873afd511f..2f16cc0f9ed 100644
--- a/web-console/src/views/home-view/lookups-card/lookups-card.spec.tsx
+++ b/web-console/src/views/home-view/lookups-card/lookups-card.spec.tsx
@@ -19,7 +19,7 @@
import { render } from '@testing-library/react';
import React from 'react';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { LookupsCard } from './lookups-card';
diff --git a/web-console/src/views/home-view/lookups-card/lookups-card.tsx b/web-console/src/views/home-view/lookups-card/lookups-card.tsx
index b752d577769..5cb2cfa4d7c 100644
--- a/web-console/src/views/home-view/lookups-card/lookups-card.tsx
+++ b/web-console/src/views/home-view/lookups-card/lookups-card.tsx
@@ -17,13 +17,13 @@
*/
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import { sum } from 'd3-array';
import React from 'react';
import { useQueryManager } from '../../../hooks';
+import { Api } from '../../../singletons';
import { isLookupsUninitialized, pluralIfNeeded } from '../../../utils';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { HomeViewCard } from '../home-view-card/home-view-card';
export interface LookupsCardProps {
@@ -34,7 +34,7 @@ export const LookupsCard = React.memo(function LookupsCard(props: LookupsCardPro
const [lookupsCountState] = useQueryManager({
processQuery: async capabilities => {
if (capabilities.hasCoordinatorAccess()) {
- const resp = await axios.get('/druid/coordinator/v1/lookups/status');
+ const resp = await Api.instance.get('/druid/coordinator/v1/lookups/status');
const data = resp.data;
return sum(Object.keys(data).map(k => Object.keys(data[k]).length));
} else {
diff --git a/web-console/src/views/home-view/segments-card/segments-card.spec.tsx b/web-console/src/views/home-view/segments-card/segments-card.spec.tsx
index e9988fcd4af..e157ee79dd7 100644
--- a/web-console/src/views/home-view/segments-card/segments-card.spec.tsx
+++ b/web-console/src/views/home-view/segments-card/segments-card.spec.tsx
@@ -19,7 +19,7 @@
import { render } from '@testing-library/react';
import React from 'react';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { SegmentsCard } from './segments-card';
diff --git a/web-console/src/views/home-view/segments-card/segments-card.tsx b/web-console/src/views/home-view/segments-card/segments-card.tsx
index 2245aae8d08..3eef75842e5 100644
--- a/web-console/src/views/home-view/segments-card/segments-card.tsx
+++ b/web-console/src/views/home-view/segments-card/segments-card.tsx
@@ -17,11 +17,11 @@
*/
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import { sum } from 'd3-array';
import React from 'react';
import { useQueryManager } from '../../../hooks';
+import { Api } from '../../../singletons';
import { Capabilities, deepGet, pluralIfNeeded, queryDruidSql } from '../../../utils';
import { HomeViewCard } from '../home-view-card/home-view-card';
@@ -46,11 +46,13 @@ FROM sys.segments`,
});
return segments.length === 1 ? segments[0] : null;
} else if (capabilities.hasCoordinatorAccess()) {
- const loadstatusResp = await axios.get('/druid/coordinator/v1/loadstatus?simple');
+ const loadstatusResp = await Api.instance.get('/druid/coordinator/v1/loadstatus?simple');
const loadstatus = loadstatusResp.data;
const unavailableSegmentNum = sum(Object.keys(loadstatus), key => loadstatus[key]);
- const datasourcesMetaResp = await axios.get('/druid/coordinator/v1/datasources?simple');
+ const datasourcesMetaResp = await Api.instance.get(
+ '/druid/coordinator/v1/datasources?simple',
+ );
const datasourcesMeta = datasourcesMetaResp.data;
const availableSegmentNum = sum(datasourcesMeta, (curr: any) =>
deepGet(curr, 'properties.segments.count'),
diff --git a/web-console/src/views/home-view/services-card/services-card.spec.tsx b/web-console/src/views/home-view/services-card/services-card.spec.tsx
index dfec084662d..ec6fc20ff02 100644
--- a/web-console/src/views/home-view/services-card/services-card.spec.tsx
+++ b/web-console/src/views/home-view/services-card/services-card.spec.tsx
@@ -19,7 +19,7 @@
import { render } from '@testing-library/react';
import React from 'react';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { ServicesCard } from './services-card';
diff --git a/web-console/src/views/home-view/services-card/services-card.tsx b/web-console/src/views/home-view/services-card/services-card.tsx
index 3ef5ec92cec..ddc184b2c63 100644
--- a/web-console/src/views/home-view/services-card/services-card.tsx
+++ b/web-console/src/views/home-view/services-card/services-card.tsx
@@ -17,13 +17,13 @@
*/
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React from 'react';
import { PluralPairIfNeeded } from '../../../components/plural-pair-if-needed/plural-pair-if-needed';
import { useQueryManager } from '../../../hooks';
+import { Api } from '../../../singletons';
import { lookupBy, queryDruidSql } from '../../../utils';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { HomeViewCard } from '../home-view-card/home-view-card';
export interface ServiceCounts {
@@ -53,10 +53,10 @@ export const ServicesCard = React.memo(function ServicesCard(props: ServicesCard
});
return lookupBy(serviceCountsFromQuery, x => x.service_type, x => x.count);
} else if (capabilities.hasCoordinatorAccess()) {
- const services = (await axios.get('/druid/coordinator/v1/servers?simple')).data;
+ const services = (await Api.instance.get('/druid/coordinator/v1/servers?simple')).data;
const middleManager = capabilities.hasOverlordAccess()
- ? (await axios.get('/druid/indexer/v1/workers')).data
+ ? (await Api.instance.get('/druid/indexer/v1/workers')).data
: [];
return {
diff --git a/web-console/src/views/home-view/status-card/status-card.tsx b/web-console/src/views/home-view/status-card/status-card.tsx
index d5f3bc81193..09ea1f375d1 100644
--- a/web-console/src/views/home-view/status-card/status-card.tsx
+++ b/web-console/src/views/home-view/status-card/status-card.tsx
@@ -17,11 +17,11 @@
*/
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React, { useState } from 'react';
import { StatusDialog } from '../../../dialogs/status-dialog/status-dialog';
import { useQueryManager } from '../../../hooks';
+import { Api } from '../../../singletons';
import { pluralIfNeeded } from '../../../utils';
import { HomeViewCard } from '../home-view-card/home-view-card';
@@ -36,7 +36,7 @@ export const StatusCard = React.memo(function StatusCard(_props: StatusCardProps
const [showStatusDialog, setShowStatusDialog] = useState(false);
const [statusSummaryState] = useQueryManager({
processQuery: async () => {
- const statusResp = await axios.get('/status');
+ const statusResp = await Api.instance.get('/status');
return {
version: statusResp.data.version,
extensionCount: statusResp.data.modules.length,
diff --git a/web-console/src/views/home-view/supervisors-card/supervisors-card.spec.tsx b/web-console/src/views/home-view/supervisors-card/supervisors-card.spec.tsx
index ec19bef5d2c..9d9625a8df0 100644
--- a/web-console/src/views/home-view/supervisors-card/supervisors-card.spec.tsx
+++ b/web-console/src/views/home-view/supervisors-card/supervisors-card.spec.tsx
@@ -19,7 +19,7 @@
import { render } from '@testing-library/react';
import React from 'react';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { SupervisorsCard } from './supervisors-card';
diff --git a/web-console/src/views/home-view/supervisors-card/supervisors-card.tsx b/web-console/src/views/home-view/supervisors-card/supervisors-card.tsx
index ce81f87bc52..c11c1285ecc 100644
--- a/web-console/src/views/home-view/supervisors-card/supervisors-card.tsx
+++ b/web-console/src/views/home-view/supervisors-card/supervisors-card.tsx
@@ -17,12 +17,12 @@
*/
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React from 'react';
import { useQueryManager } from '../../../hooks';
+import { Api } from '../../../singletons';
import { pluralIfNeeded, queryDruidSql } from '../../../utils';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { HomeViewCard } from '../home-view-card/home-view-card';
export interface SupervisorCounts {
@@ -45,7 +45,7 @@ export const SupervisorsCard = React.memo(function SupervisorsCard(props: Superv
FROM sys.supervisors`,
}))[0];
} else if (capabilities.hasOverlordAccess()) {
- const resp = await axios.get('/druid/indexer/v1/supervisor?full');
+ const resp = await Api.instance.get('/druid/indexer/v1/supervisor?full');
const data = resp.data;
return {
running: data.filter((d: any) => d.spec.suspended === false).length,
diff --git a/web-console/src/views/home-view/tasks-card/tasks-card.spec.tsx b/web-console/src/views/home-view/tasks-card/tasks-card.spec.tsx
index 3398b6a7c23..fd4c8fcc4fa 100644
--- a/web-console/src/views/home-view/tasks-card/tasks-card.spec.tsx
+++ b/web-console/src/views/home-view/tasks-card/tasks-card.spec.tsx
@@ -19,7 +19,7 @@
import { render } from '@testing-library/react';
import React from 'react';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { TasksCard } from './tasks-card';
diff --git a/web-console/src/views/home-view/tasks-card/tasks-card.tsx b/web-console/src/views/home-view/tasks-card/tasks-card.tsx
index 3687607ee5e..88fa6f30d00 100644
--- a/web-console/src/views/home-view/tasks-card/tasks-card.tsx
+++ b/web-console/src/views/home-view/tasks-card/tasks-card.tsx
@@ -17,13 +17,13 @@
*/
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React from 'react';
import { PluralPairIfNeeded } from '../../../components/plural-pair-if-needed/plural-pair-if-needed';
import { useQueryManager } from '../../../hooks';
+import { Api } from '../../../singletons';
import { lookupBy, pluralIfNeeded, queryDruidSql } from '../../../utils';
-import { Capabilities } from '../../../utils/capabilities';
+import { Capabilities } from '../../../utils';
import { HomeViewCard } from '../home-view-card/home-view-card';
function getTaskStatus(d: any) {
@@ -55,7 +55,7 @@ GROUP BY 1`,
});
return lookupBy(taskCountsFromQuery, x => x.status, x => x.count);
} else if (capabilities.hasOverlordAccess()) {
- const tasks: any[] = (await axios.get('/druid/indexer/v1/tasks')).data;
+ const tasks: any[] = (await Api.instance.get('/druid/indexer/v1/tasks')).data;
return {
SUCCESS: tasks.filter(d => getTaskStatus(d) === 'SUCCESS').length,
FAILED: tasks.filter(d => getTaskStatus(d) === 'FAILED').length,
diff --git a/web-console/src/views/ingestion-view/ingestion-view.spec.tsx b/web-console/src/views/ingestion-view/ingestion-view.spec.tsx
index ddbaa9d9103..17404b4f45b 100644
--- a/web-console/src/views/ingestion-view/ingestion-view.spec.tsx
+++ b/web-console/src/views/ingestion-view/ingestion-view.spec.tsx
@@ -19,7 +19,7 @@
import { shallow } from 'enzyme';
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { IngestionView } from './ingestion-view';
diff --git a/web-console/src/views/ingestion-view/ingestion-view.tsx b/web-console/src/views/ingestion-view/ingestion-view.tsx
index d4826d8105d..4dd15dfc401 100644
--- a/web-console/src/views/ingestion-view/ingestion-view.tsx
+++ b/web-console/src/views/ingestion-view/ingestion-view.tsx
@@ -18,7 +18,6 @@
import { Alert, Button, ButtonGroup, Intent, Label, MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import React from 'react';
import SplitterLayout from 'react-splitter-layout';
import ReactTable from 'react-table';
@@ -40,7 +39,7 @@ import {
SupervisorTableActionDialog,
TaskTableActionDialog,
} from '../../dialogs';
-import { AppToaster } from '../../singletons/toaster';
+import { Api, AppToaster } from '../../singletons';
import {
addFilter,
addFilterRaw,
@@ -56,8 +55,8 @@ import {
QueryManager,
QueryState,
} from '../../utils';
+import { Capabilities } from '../../utils';
import { BasicAction } from '../../utils/basic-action';
-import { Capabilities } from '../../utils/capabilities';
import { LocalStorageBackedArray } from '../../utils/local-storage-backed-array';
import './ingestion-view.scss';
@@ -251,7 +250,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
query: IngestionView.SUPERVISOR_SQL,
});
} else if (capabilities.hasOverlordAccess()) {
- const supervisors = (await axios.get('/druid/indexer/v1/supervisor?full')).data;
+ const supervisors = (await Api.instance.get('/druid/indexer/v1/supervisor?full')).data;
if (!Array.isArray(supervisors)) throw new Error(`Unexpected results`);
return supervisors.map((sup: any) => {
return {
@@ -284,7 +283,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
query: IngestionView.TASK_SQL,
});
} else if (capabilities.hasOverlordAccess()) {
- const resp = await axios.get(`/druid/indexer/v1/tasks`);
+ const resp = await Api.instance.get(`/druid/indexer/v1/tasks`);
return IngestionView.parseTasks(resp.data);
} else {
throw new Error(`must have SQL or overlord access`);
@@ -343,7 +342,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
private submitSupervisor = async (spec: JSON) => {
try {
- await axios.post('/druid/indexer/v1/supervisor', spec);
+ await Api.instance.post('/druid/indexer/v1/supervisor', spec);
} catch (e) {
AppToaster.show({
message: `Failed to submit supervisor: ${getDruidErrorMessage(e)}`,
@@ -361,7 +360,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
private submitTask = async (spec: JSON) => {
try {
- await axios.post('/druid/indexer/v1/task', spec);
+ await Api.instance.post('/druid/indexer/v1/task', spec);
} catch (e) {
AppToaster.show({
message: `Failed to submit task: ${getDruidErrorMessage(e)}`,
@@ -431,7 +430,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/indexer/v1/supervisor/${resumeSupervisorId}/resume`,
{},
);
@@ -460,7 +459,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/indexer/v1/supervisor/${suspendSupervisorId}/suspend`,
{},
);
@@ -489,7 +488,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/indexer/v1/supervisor/${resetSupervisorId}/reset`,
{},
);
@@ -527,7 +526,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/indexer/v1/supervisor/${terminateSupervisorId}/terminate`,
{},
);
@@ -684,7 +683,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(`/druid/indexer/v1/task/${killTaskId}/shutdown`, {});
+ const resp = await Api.instance.post(`/druid/indexer/v1/task/${killTaskId}/shutdown`, {});
return resp.data;
}}
confirmButtonText="Kill task"
@@ -945,7 +944,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(`/druid/indexer/v1/supervisor/resumeAll`, {});
+ const resp = await Api.instance.post(`/druid/indexer/v1/supervisor/resumeAll`, {});
return resp.data;
}}
confirmButtonText="Resume all supervisors"
@@ -971,7 +970,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(`/druid/indexer/v1/supervisor/suspendAll`, {});
+ const resp = await Api.instance.post(`/druid/indexer/v1/supervisor/suspendAll`, {});
return resp.data;
}}
confirmButtonText="Suspend all supervisors"
@@ -997,7 +996,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
return (
{
- const resp = await axios.post(`/druid/indexer/v1/supervisor/terminateAll`, {});
+ const resp = await Api.instance.post(`/druid/indexer/v1/supervisor/terminateAll`, {});
return resp.data;
}}
confirmButtonText="Terminate all supervisors"
diff --git a/web-console/src/views/load-data-view/load-data-view.tsx b/web-console/src/views/load-data-view/load-data-view.tsx
index d13e17b95d3..75b427a3e7d 100644
--- a/web-console/src/views/load-data-view/load-data-view.tsx
+++ b/web-console/src/views/load-data-view/load-data-view.tsx
@@ -39,7 +39,6 @@ import {
TextArea,
} from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import classNames from 'classnames';
import memoize from 'memoize-one';
import React from 'react';
@@ -121,8 +120,7 @@ import {
upgradeSpec,
} from '../../druid-models';
import { getLink } from '../../links';
-import { AppToaster } from '../../singletons/toaster';
-import { UrlBaser } from '../../singletons/url-baser';
+import { Api, AppToaster, UrlBaser } from '../../singletons';
import {
deepDelete,
deepGet,
@@ -3220,7 +3218,7 @@ export class LoadDataView extends React.PureComponent {
- const tiersResp = await axios.get('/druid/coordinator/v1/lookups/config?discover=true');
+ const tiersResp = await Api.instance.get(
+ '/druid/coordinator/v1/lookups/config?discover=true',
+ );
const tiers =
tiersResp.data && tiersResp.data.length > 0
? tiersResp.data.sort(tierNameCompare)
: [DEFAULT_LOOKUP_TIER];
const lookupEntries: {}[] = [];
- const lookupResp = await axios.get('/druid/coordinator/v1/lookups/config/all');
+ const lookupResp = await Api.instance.get('/druid/coordinator/v1/lookups/config/all');
const lookupData = lookupResp.data;
Object.keys(lookupData).map((tier: string) => {
const lookupIds = lookupData[tier];
@@ -151,7 +152,7 @@ export class LookupsView extends React.PureComponent {
- await axios.delete(
+ await Api.instance.delete(
`/druid/coordinator/v1/lookups/config/${deleteLookupTier}/${deleteLookupName}`,
);
}}
diff --git a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap b/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap
index dc188d44861..a4823ee6582 100644
--- a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap
+++ b/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap
@@ -32,7 +32,7 @@ exports[`sql view matches snapshot 1`] = `
runeMode={false}
/>
{parsedQuery &&
- oneOf(columnData.DATA_TYPE, 'BIGINT', 'FLOAT') && (
+ oneOf(columnData.DATA_TYPE, 'BIGINT', 'FLOAT', 'DOUBLE') && (
{
- return axios.post(`/druid/v2${isSql ? '/sql' : ''}`, payload, { cancelToken });
+ return Api.instance.post(`/druid/v2${isSql ? '/sql' : ''}`, payload, { cancelToken });
});
this.queryManager = new QueryManager({
@@ -482,7 +481,7 @@ export class QueryView extends React.PureComponent
-
+
this.setState({ editContextDialogOpen: true })}
runeMode={runeMode}
diff --git a/web-console/src/views/segments-view/segments-view.spec.tsx b/web-console/src/views/segments-view/segments-view.spec.tsx
index 5dccedf388a..8d9d68af062 100644
--- a/web-console/src/views/segments-view/segments-view.spec.tsx
+++ b/web-console/src/views/segments-view/segments-view.spec.tsx
@@ -19,7 +19,7 @@
import { shallow } from 'enzyme';
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { SegmentsView } from '../segments-view/segments-view';
describe('segments-view', () => {
diff --git a/web-console/src/views/segments-view/segments-view.tsx b/web-console/src/views/segments-view/segments-view.tsx
index 4d2f64913ec..08568b8a53e 100644
--- a/web-console/src/views/segments-view/segments-view.tsx
+++ b/web-console/src/views/segments-view/segments-view.tsx
@@ -18,7 +18,6 @@
import { Button, ButtonGroup, Intent, Label, MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import { SqlExpression, SqlRef } from 'druid-query-toolkit';
import React from 'react';
import ReactTable, { Filter } from 'react-table';
@@ -36,6 +35,7 @@ import {
} from '../../components';
import { AsyncActionDialog } from '../../dialogs';
import { SegmentTableActionDialog } from '../../dialogs/segments-table-action-dialog/segment-table-action-dialog';
+import { Api } from '../../singletons';
import {
addFilter,
compact,
@@ -50,8 +50,8 @@ import {
QueryState,
sqlQueryCustomTableFilter,
} from '../../utils';
+import { Capabilities, CapabilitiesMode } from '../../utils';
import { BasicAction } from '../../utils/basic-action';
-import { Capabilities, CapabilitiesMode } from '../../utils/capabilities';
import { LocalStorageBackedArray } from '../../utils/local-storage-backed-array';
import './segments-view.scss';
@@ -295,11 +295,13 @@ export class SegmentsView extends React.PureComponent {
- const datasourceList = (await axios.get('/druid/coordinator/v1/metadata/datasources')).data;
+ const datasourceList = (await Api.instance.get(
+ '/druid/coordinator/v1/metadata/datasources',
+ )).data;
const nestedResults: SegmentQueryResultRow[][] = await Promise.all(
datasourceList.map(async (d: string) => {
- const segments = (await axios.get(`/druid/coordinator/v1/datasources/${d}?full`)).data
- .segments;
+ const segments = (await Api.instance.get(`/druid/coordinator/v1/datasources/${d}?full`))
+ .data.segments;
return segments.map(
(segment: any): SegmentQueryResultRow => {
@@ -634,7 +636,7 @@ export class SegmentsView extends React.PureComponent {
- const resp = await axios.delete(
+ const resp = await Api.instance.delete(
`/druid/coordinator/v1/datasources/${terminateDatasourceId}/segments/${terminateSegmentId}`,
{},
);
diff --git a/web-console/src/views/services-view/services-view.spec.tsx b/web-console/src/views/services-view/services-view.spec.tsx
index 6b083ce4f16..32a5a6ef412 100644
--- a/web-console/src/views/services-view/services-view.spec.tsx
+++ b/web-console/src/views/services-view/services-view.spec.tsx
@@ -19,7 +19,7 @@
import { shallow } from 'enzyme';
import React from 'react';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities } from '../../utils';
import { ServicesView } from './services-view';
diff --git a/web-console/src/views/services-view/services-view.tsx b/web-console/src/views/services-view/services-view.tsx
index 1f0280dd443..38d58d6253b 100644
--- a/web-console/src/views/services-view/services-view.tsx
+++ b/web-console/src/views/services-view/services-view.tsx
@@ -18,7 +18,6 @@
import { Button, ButtonGroup, Intent, Label, MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
-import axios from 'axios';
import { sum } from 'd3-array';
import React from 'react';
import ReactTable from 'react-table';
@@ -35,6 +34,7 @@ import {
ViewControlBar,
} from '../../components';
import { AsyncActionDialog } from '../../dialogs';
+import { Api } from '../../singletons';
import {
addFilter,
Capabilities,
@@ -182,7 +182,7 @@ FROM sys.servers
ORDER BY "rank" DESC, "service" DESC`;
static async getServices(): Promise {
- const allServiceResp = await axios.get('/druid/coordinator/v1/servers?simple');
+ const allServiceResp = await Api.instance.get('/druid/coordinator/v1/servers?simple');
const allServices = allServiceResp.data;
return allServices.map((s: any) => {
return {
@@ -221,7 +221,9 @@ ORDER BY "rank" DESC, "service" DESC`;
}
if (capabilities.hasCoordinatorAccess()) {
- const loadQueueResponse = await axios.get('/druid/coordinator/v1/loadqueue?simple');
+ const loadQueueResponse = await Api.instance.get(
+ '/druid/coordinator/v1/loadqueue?simple',
+ );
const loadQueues: Record = loadQueueResponse.data;
services = services.map(s => {
const loadQueueInfo = loadQueues[s.service];
@@ -235,7 +237,7 @@ ORDER BY "rank" DESC, "service" DESC`;
if (capabilities.hasOverlordAccess()) {
let middleManagers: MiddleManagerQueryResultRow[];
try {
- const middleManagerResponse = await axios.get('/druid/indexer/v1/workers');
+ const middleManagerResponse = await Api.instance.get('/druid/indexer/v1/workers');
middleManagers = middleManagerResponse.data;
} catch (e) {
if (
@@ -589,7 +591,7 @@ ORDER BY "rank" DESC, "service" DESC`;
return (
{
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/indexer/v1/worker/${middleManagerDisableWorkerHost}/disable`,
{},
);
@@ -618,7 +620,7 @@ ORDER BY "rank" DESC, "service" DESC`;
return (
{
- const resp = await axios.post(
+ const resp = await Api.instance.post(
`/druid/indexer/v1/worker/${middleManagerEnableWorkerHost}/enable`,
{},
);