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