You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by cw...@apache.org on 2019/03/21 10:38:42 UTC
[incubator-druid] branch master updated: Add overlord edit dialog
to allow user to change overlord dynamic config on the fly (#7308)
This is an automated email from the ASF dual-hosted git repository.
cwylie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
The following commit(s) were added to refs/heads/master by this push:
new 494c1a2 Add overlord edit dialog to allow user to change overlord dynamic config on the fly (#7308)
494c1a2 is described below
commit 494c1a2ef84c7538780a6ebdbdc74e18fe668af3
Author: Qi Shu <sh...@gmail.com>
AuthorDate: Thu Mar 21 03:38:35 2019 -0700
Add overlord edit dialog to allow user to change overlord dynamic config on the fly (#7308)
* Add overlord edit dialog to allow user to edit overlord dynmamic config on the fly
* Set config to {} if druid return nothing for overlord config
---
web-console/src/components/filler.tsx | 3 +-
web-console/src/components/header-bar.tsx | 11 +-
.../src/dialogs/overlord-dynamic-config.scss | 53 +++++++++
.../src/dialogs/overlord-dynamic-config.tsx | 130 +++++++++++++++++++++
4 files changed, 194 insertions(+), 3 deletions(-)
diff --git a/web-console/src/components/filler.tsx b/web-console/src/components/filler.tsx
index 11dcf93..decea1f 100644
--- a/web-console/src/components/filler.tsx
+++ b/web-console/src/components/filler.tsx
@@ -53,7 +53,8 @@ export const IconNames = {
ARROW_UP: "arrow-up" as "arrow-up",
ARROW_DOWN: "arrow-down" as "arrow-down",
PROPERTIES: "properties" as "properties",
- BUILD: "build" as "build"
+ BUILD: "build" as "build",
+ WRENCH: "wrench" as "wrench"
};
export type IconNames = typeof IconNames[keyof typeof IconNames];
diff --git a/web-console/src/components/header-bar.tsx b/web-console/src/components/header-bar.tsx
index 9eea252..ec3e283 100644
--- a/web-console/src/components/header-bar.tsx
+++ b/web-console/src/components/header-bar.tsx
@@ -23,6 +23,7 @@ import * as React from 'react';
import { Alignment, IconNames, Navbar, NavbarDivider, NavbarGroup } from "../components/filler";
import { AboutDialog } from "../dialogs/about-dialog";
import { CoordinatorDynamicConfigDialog } from '../dialogs/coordinator-dynamic-config';
+import { OverlordDynamicConfigDialog } from "../dialogs/overlord-dynamic-config";
import {
DRUID_DOCS,
DRUID_GITHUB,
@@ -42,6 +43,7 @@ export interface HeaderBarProps extends React.Props<any> {
export interface HeaderBarState {
aboutDialogOpen: boolean;
coordinatorDynamicConfigDialogOpen: boolean;
+ overlordDynamicConfigDialogOpen: boolean;
}
export class HeaderBar extends React.Component<HeaderBarProps, HeaderBarState> {
@@ -49,7 +51,8 @@ export class HeaderBar extends React.Component<HeaderBarProps, HeaderBarState> {
super(props);
this.state = {
aboutDialogOpen: false,
- coordinatorDynamicConfigDialogOpen: false
+ coordinatorDynamicConfigDialogOpen: false,
+ overlordDynamicConfigDialogOpen: false
};
}
@@ -104,7 +107,7 @@ export class HeaderBar extends React.Component<HeaderBarProps, HeaderBarState> {
render() {
const { active } = this.props;
- const { aboutDialogOpen, coordinatorDynamicConfigDialogOpen } = this.state;
+ const { aboutDialogOpen, coordinatorDynamicConfigDialogOpen, overlordDynamicConfigDialogOpen } = this.state;
const legacyMenu = <Menu>
<MenuItem iconName={IconNames.GRAPH} text="Legacy coordinator console" href={LEGACY_COORDINATOR_CONSOLE} target="_blank" />
@@ -120,6 +123,7 @@ export class HeaderBar extends React.Component<HeaderBarProps, HeaderBarState> {
const configMenu = <Menu>
<MenuItem iconName={IconNames.COG} text="Coordinator dynamic config" onClick={() => this.setState({ coordinatorDynamicConfigDialogOpen: true })}/>
+ <MenuItem iconName={IconNames.WRENCH} text="Overlord dynamic config" onClick={() => this.setState({ overlordDynamicConfigDialogOpen: true })}/>
<MenuItem iconName={IconNames.PROPERTIES} className={classNames(Classes.MINIMAL, { 'pt-active': active === 'lookups' })} text="Lookups" href="#lookups"/>
</Menu>;
@@ -153,6 +157,9 @@ export class HeaderBar extends React.Component<HeaderBarProps, HeaderBarState> {
{ coordinatorDynamicConfigDialogOpen ? <CoordinatorDynamicConfigDialog
onClose={() => this.setState({ coordinatorDynamicConfigDialogOpen: false })}
/> : null }
+ { overlordDynamicConfigDialogOpen ? <OverlordDynamicConfigDialog
+ onClose={() => this.setState({ overlordDynamicConfigDialogOpen: false })}
+ /> : null }
</Navbar>;
}
}
diff --git a/web-console/src/dialogs/overlord-dynamic-config.scss b/web-console/src/dialogs/overlord-dynamic-config.scss
new file mode 100644
index 0000000..0a8dcfc
--- /dev/null
+++ b/web-console/src/dialogs/overlord-dynamic-config.scss
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+.overlord-dynamic-config {
+
+ &.pt-dialog {
+ width: 600px;
+ }
+
+ margin-top: 5vh;
+
+ .pt-dialog-body {
+ max-height: 70vh;
+
+ .auto-form {
+ max-height: 60vh;
+ overflow: auto;
+
+ .ace_editor {
+ height: 25vh !important;
+ }
+ }
+
+ .html-select {
+ width: 195px;
+ }
+
+ .config-comment {
+ margin-top: 10px;
+ padding: 0 15px;
+
+ textarea {
+ max-width: 200px;
+ padding: 0 15px;
+ }
+ }
+ }
+}
diff --git a/web-console/src/dialogs/overlord-dynamic-config.tsx b/web-console/src/dialogs/overlord-dynamic-config.tsx
new file mode 100644
index 0000000..f3be789
--- /dev/null
+++ b/web-console/src/dialogs/overlord-dynamic-config.tsx
@@ -0,0 +1,130 @@
+/*
+ * 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 { Intent } from "@blueprintjs/core";
+import axios from "axios";
+import * as React from "react";
+
+import { AutoForm } from "../components/auto-form";
+import { IconNames } from "../components/filler";
+import { AppToaster } from "../singletons/toaster";
+import { getDruidErrorMessage } from "../utils";
+
+import { SnitchDialog } from "./snitch-dialog";
+
+import "./overlord-dynamic-config.scss";
+
+export interface OverlordDynamicConfigDialogProps extends React.Props<any> {
+ onClose: () => void;
+}
+
+export interface OverlordDynamicConfigDialogState {
+ dynamicConfig: Record<string, any> | null;
+ allJSONValid: boolean;
+}
+
+export class OverlordDynamicConfigDialog extends React.Component<OverlordDynamicConfigDialogProps, OverlordDynamicConfigDialogState> {
+ constructor(props: OverlordDynamicConfigDialogProps) {
+ super(props);
+ this.state = {
+ dynamicConfig: null,
+ allJSONValid: true
+ };
+ }
+
+ componentDidMount(): void {
+ this.getConfig();
+ }
+
+ async getConfig() {
+ let config: Record<string, any> | null = null;
+ try {
+ const configResp = await axios.get("/druid/indexer/v1/worker");
+ config = configResp.data || {};
+ } catch (e) {
+ AppToaster.show({
+ iconName: IconNames.ERROR,
+ intent: Intent.DANGER,
+ message: `Could not load overlord dynamic config: ${getDruidErrorMessage(e)}`
+ });
+ return;
+ }
+ this.setState({
+ dynamicConfig: config
+ });
+ }
+
+ private saveConfig = async (author: string, comment: string) => {
+ const { onClose } = this.props;
+ const newState: any = this.state.dynamicConfig;
+ try {
+ await axios.post("/druid/indexer/v1/worker", newState, {
+ headers: {
+ "X-Druid-Author": author,
+ "X-Druid-Comment": comment
+ }
+ });
+ } catch (e) {
+ AppToaster.show({
+ iconName: IconNames.ERROR,
+ intent: Intent.DANGER,
+ message: `Could not save overlord dynamic config: ${getDruidErrorMessage(e)}`
+ });
+ }
+
+ AppToaster.show({
+ message: 'Saved overlord dynamic config',
+ intent: Intent.SUCCESS
+ });
+ onClose();
+ }
+
+ render() {
+ const { onClose } = this.props;
+ const { dynamicConfig, allJSONValid } = this.state;
+
+ return <SnitchDialog
+ className="overlord-dynamic-config"
+ isOpen
+ onSave={this.saveConfig}
+ onClose={onClose}
+ title="Overlord dynamic config"
+ saveDisabled={!allJSONValid}
+ >
+ <p>
+ Edit the overlord dynamic configuration on the fly.
+ For more information please refer to the <a href="http://druid.io/docs/latest/configuration/index.html#overlord-dynamic-configuration" target="_blank">documentation</a>.
+ </p>
+ <AutoForm
+ fields={[
+ {
+ name: "selectStrategy",
+ type: "json"
+ },
+ {
+ name: "autoScaler",
+ type: "json"
+ }
+ ]}
+ model={dynamicConfig}
+ onChange={m => this.setState({ dynamicConfig: m })}
+ updateJSONValidity={e => this.setState({allJSONValid: e})}
+ />
+ </SnitchDialog>;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org