This is an automated email from the ASF dual-hosted git repository.
vogievetsky pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 4ba3e25a545 Change web console to use overlord APIs vs coordinator
APIs (#18172)
4ba3e25a545 is described below
commit 4ba3e25a5454f73a7dd37fdd6f88b292a484bd78
Author: Vadim Ogievetsky <[email protected]>
AuthorDate: Wed Jun 25 17:12:40 2025 +0100
Change web console to use overlord APIs vs coordinator APIs (#18172)
---
.../kill-datasource-dialog.tsx | 6 +-
.../views/datasources-view/datasources-view.tsx | 193 +++++++++++----------
.../src/views/segments-view/segments-view.tsx | 22 ++-
3 files changed, 115 insertions(+), 106 deletions(-)
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 fdf160b2316..16fe862581f 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 bf6ca1950d3..51aec83ea68 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`;
<AsyncActionDialog
action={async () => {
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`;
<AsyncActionDialog
action={async () => {
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 4baebd6ffc2..f9a6834bdd2 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<SegmentsViewProps, Segment
}
private getSegmentActions(id: string, datasource: string): BasicAction[] {
+ const { capabilities } = this.props;
const actions: BasicAction[] = [];
- actions.push({
- icon: IconNames.IMPORT,
- title: 'Drop segment (disable)',
- intent: Intent.DANGER,
- onAction: () => 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<SegmentsViewProps, Segment
<AsyncActionDialog
action={async () => {
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<SegmentsViewProps, Segment
return resp.data;
}}
confirmButtonText="Drop segment"
- successText="Segment drop request acknowledged, next time the
coordinator runs segment will be dropped"
+ successText="Segment drop request acknowledged, next time the overlord
runs segment will be dropped"
failText="Could not drop segment"
intent={Intent.DANGER}
onClose={() => {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]