- Servers
+ Services
Loading...
diff --git a/web-console/src/views/home-view/servers-card/servers-card.spec.tsx b/web-console/src/views/home-view/services-card/services-card.spec.tsx
similarity index 78%
rename from web-console/src/views/home-view/servers-card/servers-card.spec.tsx
rename to web-console/src/views/home-view/services-card/services-card.spec.tsx
index 48ea6a981a6..dfec084662d 100644
--- a/web-console/src/views/home-view/servers-card/servers-card.spec.tsx
+++ b/web-console/src/views/home-view/services-card/services-card.spec.tsx
@@ -19,13 +19,15 @@
import { render } from '@testing-library/react';
import React from 'react';
-import { ServersCard } from './servers-card';
+import { Capabilities } from '../../../utils/capabilities';
-describe('servers card', () => {
+import { ServicesCard } from './services-card';
+
+describe('services card', () => {
it('matches snapshot', () => {
- const serversCard = ;
+ const servicesCard = ;
- const { container } = render(serversCard);
+ const { container } = render(servicesCard);
expect(container.firstChild).toMatchSnapshot();
});
});
diff --git a/web-console/src/views/home-view/servers-card/servers-card.tsx b/web-console/src/views/home-view/services-card/services-card.tsx
similarity index 61%
rename from web-console/src/views/home-view/servers-card/servers-card.tsx
rename to web-console/src/views/home-view/services-card/services-card.tsx
index 9c28390bd37..2d7915dde64 100644
--- a/web-console/src/views/home-view/servers-card/servers-card.tsx
+++ b/web-console/src/views/home-view/services-card/services-card.tsx
@@ -24,12 +24,12 @@ import { compact, lookupBy, pluralIfNeeded, queryDruidSql, QueryManager } from '
import { Capabilities } from '../../../utils/capabilities';
import { HomeViewCard } from '../home-view-card/home-view-card';
-export interface ServersCardProps {
+export interface ServicesCardProps {
capabilities: Capabilities;
}
-export interface ServersCardState {
- serverCountLoading: boolean;
+export interface ServicesCardState {
+ serviceCountLoading: boolean;
coordinatorCount: number;
overlordCount: number;
routerCount: number;
@@ -38,10 +38,10 @@ export interface ServersCardState {
middleManagerCount: number;
peonCount: number;
indexerCount: number;
- serverCountError?: string;
+ serviceCountError?: string;
}
-export class ServersCard extends React.PureComponent {
+export class ServicesCard extends React.PureComponent {
static renderPluralIfNeededPair(
count1: number,
singular1: string,
@@ -56,12 +56,12 @@ export class ServersCard extends React.PureComponent{text}
;
}
- private serverQueryManager: QueryManager
;
+ private serviceQueryManager: QueryManager;
- constructor(props: ServersCardProps, context: any) {
+ constructor(props: ServicesCardProps, context: any) {
super(props, context);
this.state = {
- serverCountLoading: false,
+ serviceCountLoading: false,
coordinatorCount: 0,
overlordCount: 0,
routerCount: 0,
@@ -72,29 +72,37 @@ export class ServersCard extends React.PureComponent {
- if (capabilities === 'no-sql') {
- const serversResp = await axios.get('/druid/coordinator/v1/servers?simple');
- const middleManagerResp = await axios.get('/druid/indexer/v1/workers');
- return {
- historical: serversResp.data.filter((s: any) => s.type === 'historical').length,
- middle_manager: middleManagerResp.data.length,
- peon: serversResp.data.filter((s: any) => s.type === 'indexer-executor').length,
- };
- } else {
- const serverCountsFromQuery: {
- server_type: string;
+ if (capabilities.hasSql()) {
+ const serviceCountsFromQuery: {
+ service_type: string;
count: number;
}[] = await queryDruidSql({
- query: `SELECT server_type, COUNT(*) as "count" FROM sys.servers GROUP BY 1`,
+ query: `SELECT server_type AS "service_type", COUNT(*) as "count" FROM sys.servers GROUP BY 1`,
});
- return lookupBy(serverCountsFromQuery, x => x.server_type, x => x.count);
+ return lookupBy(serviceCountsFromQuery, x => x.service_type, x => x.count);
+ } else if (capabilities.hasCoordinatorAccess() || capabilities.hasOverlordAccess()) {
+ const services = capabilities.hasCoordinatorAccess()
+ ? (await axios.get('/druid/coordinator/v1/servers?simple')).data
+ : [];
+
+ const middleManager = capabilities.hasOverlordAccess()
+ ? (await axios.get('/druid/indexer/v1/workers')).data
+ : [];
+
+ return {
+ historical: services.filter((s: any) => s.type === 'historical').length,
+ middle_manager: middleManager.length,
+ peon: services.filter((s: any) => s.type === 'indexer-executor').length,
+ };
+ } else {
+ throw new Error(`must have SQL or coordinator/overlord access`);
}
},
onStateChange: ({ result, loading, error }) => {
this.setState({
- serverCountLoading: loading,
+ serviceCountLoading: loading,
coordinatorCount: result ? result.coordinator : 0,
overlordCount: result ? result.overlord : 0,
routerCount: result ? result.router : 0,
@@ -103,7 +111,7 @@ export class ServersCard extends React.PureComponent
- {ServersCard.renderPluralIfNeededPair(
+ {ServicesCard.renderPluralIfNeededPair(
overlordCount,
'overlord',
coordinatorCount,
'coordinator',
)}
- {ServersCard.renderPluralIfNeededPair(routerCount, 'router', brokerCount, 'broker')}
- {ServersCard.renderPluralIfNeededPair(
+ {ServicesCard.renderPluralIfNeededPair(routerCount, 'router', brokerCount, 'broker')}
+ {ServicesCard.renderPluralIfNeededPair(
historicalCount,
'historical',
middleManagerCount,
'middle manager',
)}
- {ServersCard.renderPluralIfNeededPair(peonCount, 'peon', indexerCount, 'indexer')}
+ {ServicesCard.renderPluralIfNeededPair(peonCount, 'peon', indexerCount, 'indexer')}
);
}
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 ac9248da3f9..ec19bef5d2c 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,11 +19,13 @@
import { render } from '@testing-library/react';
import React from 'react';
+import { Capabilities } from '../../../utils/capabilities';
+
import { SupervisorsCard } from './supervisors-card';
describe('supervisors card', () => {
it('matches snapshot', () => {
- const supervisorsCard = ;
+ const supervisorsCard = ;
const { container } = render(supervisorsCard);
expect(container.firstChild).toMatchSnapshot();
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 1b4358aa72c..5b3633bfc11 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
@@ -51,14 +51,14 @@ export class SupervisorsCard extends React.PureComponent<
this.supervisorQueryManager = new QueryManager({
processQuery: async capabilities => {
- if (capabilities !== 'no-sql') {
+ if (capabilities.hasSql()) {
return (await queryDruidSql({
query: `SELECT
COUNT(*) FILTER (WHERE "suspended" = 0) AS "runningSupervisorCount",
COUNT(*) FILTER (WHERE "suspended" = 1) AS "suspendedSupervisorCount"
FROM sys.supervisors`,
}))[0];
- } else {
+ } else if (capabilities.hasOverlordAccess()) {
const resp = await axios.get('/druid/indexer/v1/supervisor?full');
const data = resp.data;
const runningSupervisorCount = data.filter((d: any) => d.spec.suspended === false).length;
@@ -68,6 +68,8 @@ FROM sys.supervisors`,
runningSupervisorCount,
suspendedSupervisorCount,
};
+ } else {
+ throw new Error(`must have SQL or overlord access`);
}
},
onStateChange: ({ result, loading, error }) => {
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 df830266c67..3398b6a7c23 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,11 +19,13 @@
import { render } from '@testing-library/react';
import React from 'react';
+import { Capabilities } from '../../../utils/capabilities';
+
import { TasksCard } from './tasks-card';
describe('tasks card', () => {
it('matches snapshot', () => {
- const tasksCard = ;
+ const tasksCard = ;
const { container } = render(tasksCard);
expect(container.firstChild).toMatchSnapshot();
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 044e79e2c6e..47cbe9e98a7 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
@@ -54,7 +54,16 @@ export class TasksCard extends React.PureComponent {
- if (capabilities === 'no-sql') {
+ if (capabilities.hasSql()) {
+ const taskCountsFromQuery: { status: string; count: number }[] = await queryDruidSql({
+ query: `SELECT
+ CASE WHEN "status" = 'RUNNING' THEN "runner_status" ELSE "status" END AS "status",
+ COUNT (*) AS "count"
+FROM sys.tasks
+GROUP BY 1`,
+ });
+ return lookupBy(taskCountsFromQuery, x => x.status, x => x.count);
+ } else if (capabilities.hasOverlordAccess()) {
const completeTasksResp = await axios.get('/druid/indexer/v1/completeTasks');
const runningTasksResp = await axios.get('/druid/indexer/v1/runningTasks');
const pendingTasksResp = await axios.get('/druid/indexer/v1/pendingTasks');
@@ -67,14 +76,7 @@ export class TasksCard extends React.PureComponent x.status, x => x.count);
+ throw new Error(`must have SQL or overlord access`);
}
},
onStateChange: ({ result, loading, error }) => {
diff --git a/web-console/src/views/index.ts b/web-console/src/views/index.ts
index bea772fc2cb..1dd24f0f804 100644
--- a/web-console/src/views/index.ts
+++ b/web-console/src/views/index.ts
@@ -21,6 +21,6 @@ export * from './home-view/home-view';
export * from './load-data-view/load-data-view';
export * from './lookups-view/lookups-view';
export * from './segments-view/segments-view';
-export * from './servers-view/servers-view';
+export * from './services-view/services-view';
export * from './query-view/query-view';
export * from './task-view/tasks-view';
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 e471c048e5d..094c488a81e 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
@@ -326,7 +326,7 @@ export class LoadDataView extends React.PureComponent
{this.renderStepNav()}
+ {step === 'loading' && }
+
{step === 'welcome' && this.renderWelcomeStep()}
{step === 'connect' && this.renderConnectStep()}
{step === 'parser' && this.renderParserStep()}
@@ -548,7 +550,6 @@ export class LoadDataView extends React.PureComponent
@@ -1071,7 +1072,7 @@ export class LoadDataView extends React.PureComponent
- This path must be available on the local filesystem of all Druid servers.
+ This path must be available on the local filesystem of all Druid services.
)}
@@ -3000,10 +3001,6 @@ export class LoadDataView extends React.PureComponent;
- }
-
renderSpecStep() {
const { spec, submitting } = this.state;
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 8dced7101a3..5dccedf388a 100644
--- a/web-console/src/views/segments-view/segments-view.spec.tsx
+++ b/web-console/src/views/segments-view/segments-view.spec.tsx
@@ -19,6 +19,7 @@
import { shallow } from 'enzyme';
import React from 'react';
+import { Capabilities } from '../../utils/capabilities';
import { SegmentsView } from '../segments-view/segments-view';
describe('segments-view', () => {
@@ -28,7 +29,7 @@ describe('segments-view', () => {
datasource={'test'}
onlyUnavailable={false}
goToQuery={() => {}}
- capabilities="full"
+ capabilities={Capabilities.FULL}
/>,
);
expect(segmentsView).toMatchSnapshot();
diff --git a/web-console/src/views/segments-view/segments-view.tsx b/web-console/src/views/segments-view/segments-view.tsx
index ea39d77a79e..1acf8a88f39 100644
--- a/web-console/src/views/segments-view/segments-view.tsx
+++ b/web-console/src/views/segments-view/segments-view.tsx
@@ -56,12 +56,12 @@ import {
sqlQueryCustomTableFilter,
} from '../../utils';
import { BasicAction } from '../../utils/basic-action';
-import { Capabilities } from '../../utils/capabilities';
+import { Capabilities, CapabilitiesMode } from '../../utils/capabilities';
import { LocalStorageBackedArray } from '../../utils/local-storage-backed-array';
import './segments-view.scss';
-const tableColumns: Record = {
+const tableColumns: Record = {
full: [
'Segment ID',
'Datasource',
@@ -103,7 +103,6 @@ const tableColumns: Record = {
'Is available',
'Is overshadowed',
],
- broken: ['Segment ID'],
};
export interface SegmentsViewProps {
@@ -339,7 +338,7 @@ export class SegmentsView extends React.PureComponent {
this.setState({ segmentFilter: filtered });
}}
- onFetchData={
- capabilities === 'no-sql'
- ? this.fetchClientSideData
- : state => {
- this.setState({
- page: state.page,
- pageSize: state.pageSize,
- filtered: state.filtered,
- sorted: state.sorted,
- });
- if (this.segmentsSqlQueryManager.getLastQuery) {
- this.fetchData(groupByInterval, state);
- }
- }
- }
+ onFetchData={state => {
+ if (capabilities.hasSql()) {
+ this.setState({
+ page: state.page,
+ pageSize: state.pageSize,
+ filtered: state.filtered,
+ sorted: state.sorted,
+ });
+ if (this.segmentsSqlQueryManager.getLastQuery) {
+ this.fetchData(groupByInterval, state);
+ }
+ } else if (capabilities.hasCoordinatorAccess()) {
+ this.fetchClientSideData(state);
+ }
+ }}
showPageJump={false}
ofText=""
pivotBy={groupByInterval ? ['interval'] : []}
@@ -556,7 +555,7 @@ export class SegmentsView extends React.PureComponent (row.original.is_available ? formatNumber(row.value) : (unknown)),
- show: capabilities !== 'no-sql' && hiddenColumns.exists('Num rows'),
+ show: capabilities.hasSql() && hiddenColumns.exists('Num rows'),
},
{
Header: 'Replicas',
@@ -564,35 +563,35 @@ export class SegmentsView extends React.PureComponent String(Boolean(row.is_published)),
Filter: makeBooleanFilter(),
- show: capabilities !== 'no-sql' && hiddenColumns.exists('Is published'),
+ show: capabilities.hasSql() && hiddenColumns.exists('Is published'),
},
{
Header: 'Is realtime',
id: 'is_realtime',
accessor: row => String(Boolean(row.is_realtime)),
Filter: makeBooleanFilter(),
- show: capabilities !== 'no-sql' && hiddenColumns.exists('Is realtime'),
+ show: capabilities.hasSql() && hiddenColumns.exists('Is realtime'),
},
{
Header: 'Is available',
id: 'is_available',
accessor: row => String(Boolean(row.is_available)),
Filter: makeBooleanFilter(),
- show: capabilities !== 'no-sql' && hiddenColumns.exists('Is available'),
+ show: capabilities.hasSql() && hiddenColumns.exists('Is available'),
},
{
Header: 'Is overshadowed',
id: 'is_overshadowed',
accessor: row => String(Boolean(row.is_overshadowed)),
Filter: makeBooleanFilter(),
- show: capabilities !== 'no-sql' && hiddenColumns.exists('Is overshadowed'),
+ show: capabilities.hasSql() && hiddenColumns.exists('Is overshadowed'),
},
{
Header: ACTION_COLUMN_LABEL,
@@ -618,7 +617,7 @@ export class SegmentsView extends React.PureComponent '',
- show: capabilities !== 'no-proxy' && hiddenColumns.exists(ACTION_COLUMN_LABEL),
+ show: capabilities.hasCoordinatorAccess() && hiddenColumns.exists(ACTION_COLUMN_LABEL),
},
]}
defaultPageSize={SegmentsView.PAGE_SIZE}
@@ -663,7 +662,7 @@ export class SegmentsView extends React.PureComponent
- {capabilities !== 'no-sql' && (
+ {capabilities.hasSql() && (