diff --git a/web-console/src/dialogs/kill-datasource-dialog/kill-datasource-dialog.tsx b/web-console/src/dialogs/kill-datasource-dialog/kill-datasource-dialog.tsx index fdf160b2316c..16fe862581f7 100644 --- a/web-console/src/dialogs/kill-datasource-dialog/kill-datasource-dialog.tsx +++ b/web-console/src/dialogs/kill-datasource-dialog/kill-datasource-dialog.tsx @@ -58,9 +58,9 @@ export const KillDatasourceDialog = function KillDatasourceDialog( className="kill-datasource-dialog" action={async () => { const resp = await Api.instance.delete( - `/druid/coordinator/v1/datasources/${Api.encodePath( - datasource, - )}?kill=true&interval=${Api.encodePath(interval)}`, + `/druid/indexer/v1/datasources/${Api.encodePath(datasource)}/intervals/${Api.encodePath( + interval.replace(/\//g, '_'), + )}`, {}, ); return resp.data; diff --git a/web-console/src/views/datasources-view/datasources-view.tsx b/web-console/src/views/datasources-view/datasources-view.tsx index bf6ca1950d30..51aec83ea680 100644 --- a/web-console/src/views/datasources-view/datasources-view.tsx +++ b/web-console/src/views/datasources-view/datasources-view.tsx @@ -708,7 +708,7 @@ GROUP BY 1, 2`; { const resp = await Api.instance.delete( - `/druid/coordinator/v1/datasources/${Api.encodePath( + `/druid/indexer/v1/datasources/${Api.encodePath( datasourceToMarkAsUnusedAllSegmentsIn, )}`, {}, @@ -749,7 +749,7 @@ GROUP BY 1, 2`; { const resp = await Api.instance.post( - `/druid/coordinator/v1/datasources/${Api.encodePath( + `/druid/indexer/v1/datasources/${Api.encodePath( datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn, )}`, {}, @@ -792,7 +792,7 @@ GROUP BY 1, 2`; if (!useUnuseInterval) return; const param = isUse ? 'markUsed' : 'markUnused'; const resp = await Api.instance.post( - `/druid/coordinator/v1/datasources/${Api.encodePath( + `/druid/indexer/v1/datasources/${Api.encodePath( datasourceToMarkSegmentsByIntervalIn, )}/${Api.encodePath(param)}`, { @@ -1006,29 +1006,8 @@ GROUP BY 1, 2`; ): BasicAction[] { const { goToQuery, goToSegments, capabilities } = this.props; - const goToActions: BasicAction[] = []; - - if (capabilities.hasSql()) { - goToActions.push({ - icon: IconNames.APPLICATION, - title: 'Query with SQL', - onAction: () => goToQuery({ queryString: SqlQuery.create(T(datasource)).toString() }), - }); - } - - goToActions.push({ - icon: IconNames.STACKED_CHART, - title: 'Go to segments', - onAction: () => { - goToSegments({ datasource }); - }, - }); - - if (!capabilities.hasCoordinatorAccess()) { - return goToActions; - } - if (unused) { + if (!capabilities.hasOverlordAccess()) return []; return [ { icon: IconNames.EXPORT, @@ -1055,77 +1034,101 @@ GROUP BY 1, 2`; }, ]; } else { - return goToActions.concat( - compact([ - { - icon: IconNames.AUTOMATIC_UPDATES, - title: 'Edit retention rules', - onAction: () => { - const defaultRules = this.state.datasourcesAndDefaultRulesState.data?.defaultRules; - if (!defaultRules) return; - this.setState({ - retentionDialogOpenOn: { - datasource, - rules: rules || [], - defaultRules, - }, - }); - }, - }, - { - icon: IconNames.REFRESH, - title: 'Mark as used all segments (will lead to reapplying retention rules)', - onAction: () => - this.setState({ - datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn: datasource, - }), - }, - compactionInfo - ? { - icon: IconNames.COMPRESSED, - title: 'Edit compaction configuration', - onAction: () => { - this.setState({ - compactionDialogOpenOn: { - datasource, - compactionConfig: compactionInfo.config, - }, - }); - }, - } - : undefined, - { - icon: IconNames.EXPORT, - title: 'Mark as used segments by interval', - onAction: () => - this.setState({ - datasourceToMarkSegmentsByIntervalIn: datasource, - useUnuseAction: 'use', - }), - }, - { - icon: IconNames.IMPORT, - title: 'Mark as unused segments by interval', - onAction: () => - this.setState({ - datasourceToMarkSegmentsByIntervalIn: datasource, - useUnuseAction: 'unuse', - }), - }, - { - icon: IconNames.IMPORT, - title: 'Mark as unused all segments', - intent: Intent.DANGER, - onAction: () => this.setState({ datasourceToMarkAsUnusedAllSegmentsIn: datasource }), - }, - { - icon: IconNames.TRASH, - title: 'Delete unused segments (issue kill task)', - intent: Intent.DANGER, - onAction: () => this.setState({ killDatasource: datasource }), + return compact([ + capabilities.hasSql() + ? { + icon: IconNames.APPLICATION, + title: 'Query with SQL', + onAction: () => goToQuery({ queryString: SqlQuery.create(T(datasource)).toString() }), + } + : undefined, + { + icon: IconNames.STACKED_CHART, + title: 'Go to segments', + onAction: () => { + goToSegments({ datasource }); }, - ]), - ); + }, + capabilities.hasCoordinatorAccess() + ? { + icon: IconNames.AUTOMATIC_UPDATES, + title: 'Edit retention rules', + onAction: () => { + const defaultRules = this.state.datasourcesAndDefaultRulesState.data?.defaultRules; + if (!defaultRules) return; + this.setState({ + retentionDialogOpenOn: { + datasource, + rules: rules || [], + defaultRules, + }, + }); + }, + } + : undefined, + capabilities.hasOverlordAccess() + ? { + icon: IconNames.REFRESH, + title: 'Mark as used all segments (will lead to reapplying retention rules)', + onAction: () => + this.setState({ + datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn: datasource, + }), + } + : undefined, + capabilities.hasCoordinatorAccess() && compactionInfo + ? { + icon: IconNames.COMPRESSED, + title: 'Edit compaction configuration', + onAction: () => { + this.setState({ + compactionDialogOpenOn: { + datasource, + compactionConfig: compactionInfo.config, + }, + }); + }, + } + : undefined, + capabilities.hasOverlordAccess() + ? { + icon: IconNames.EXPORT, + title: 'Mark as used segments by interval', + onAction: () => + this.setState({ + datasourceToMarkSegmentsByIntervalIn: datasource, + useUnuseAction: 'use', + }), + } + : undefined, + capabilities.hasOverlordAccess() + ? { + icon: IconNames.IMPORT, + title: 'Mark as unused segments by interval', + onAction: () => + this.setState({ + datasourceToMarkSegmentsByIntervalIn: datasource, + useUnuseAction: 'unuse', + }), + } + : undefined, + capabilities.hasOverlordAccess() + ? { + icon: IconNames.IMPORT, + title: 'Mark as unused all segments', + intent: Intent.DANGER, + onAction: () => this.setState({ datasourceToMarkAsUnusedAllSegmentsIn: datasource }), + } + : undefined, + capabilities.hasOverlordAccess() + ? { + icon: IconNames.TRASH, + title: 'Delete unused segments (issue kill task)', + intent: Intent.DANGER, + onAction: () => this.setState({ killDatasource: datasource }), + } + : undefined, + ]); } } diff --git a/web-console/src/views/segments-view/segments-view.tsx b/web-console/src/views/segments-view/segments-view.tsx index 4baebd6ffc2c..f9a6834bdd29 100644 --- a/web-console/src/views/segments-view/segments-view.tsx +++ b/web-console/src/views/segments-view/segments-view.tsx @@ -546,13 +546,19 @@ export class SegmentsView extends React.PureComponent this.setState({ terminateSegmentId: id, terminateDatasourceId: datasource }), - }); + + if (capabilities.hasOverlordAccess()) { + actions.push({ + icon: IconNames.IMPORT, + title: 'Drop segment (disable)', + intent: Intent.DANGER, + onAction: () => + this.setState({ terminateSegmentId: id, terminateDatasourceId: datasource }), + }); + } + return actions; } @@ -1017,7 +1023,7 @@ export class SegmentsView extends React.PureComponent { const resp = await Api.instance.delete( - `/druid/coordinator/v1/datasources/${Api.encodePath( + `/druid/indexer/v1/datasources/${Api.encodePath( terminateDatasourceId, )}/segments/${Api.encodePath(terminateSegmentId)}`, {}, @@ -1025,7 +1031,7 @@ export class SegmentsView extends React.PureComponent {