You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by fj...@apache.org on 2019/08/01 15:37:16 UTC

[incubator-druid] branch master updated: add timeout to capabilities check (#8213)

This is an automated email from the ASF dual-hosted git repository.

fjy 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 a0f8886  add timeout to capabilities check (#8213)
a0f8886 is described below

commit a0f88868e3e60e88516cbd1617ed65d60b675ddd
Author: Vadim Ogievetsky <va...@gmail.com>
AuthorDate: Thu Aug 1 08:37:02 2019 -0700

    add timeout to capabilities check (#8213)
---
 web-console/src/console-application.tsx            | 17 +++++++++-----
 web-console/src/utils/general.tsx                  |  4 ++++
 web-console/src/utils/local-storage-keys.tsx       |  1 +
 .../src/views/datasource-view/datasource-view.tsx  |  3 ++-
 .../views/query-view/column-tree/column-tree.tsx   | 26 ++++++++++++++--------
 5 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/web-console/src/console-application.tsx b/web-console/src/console-application.tsx
index 1898f39..9f1eeee 100644
--- a/web-console/src/console-application.tsx
+++ b/web-console/src/console-application.tsx
@@ -25,7 +25,7 @@ import { HashRouter, Route, Switch } from 'react-router-dom';
 
 import { ExternalLink, HeaderActiveTab, HeaderBar, Loader } from './components';
 import { AppToaster } from './singletons/toaster';
-import { QueryManager } from './utils';
+import { localStorageGet, LocalStorageKeys, QueryManager } from './utils';
 import { DRUID_DOCS_API, DRUID_DOCS_SQL } from './variables';
 import {
   DatasourcesView,
@@ -56,20 +56,27 @@ export class ConsoleApplication extends React.PureComponent<
   ConsoleApplicationProps,
   ConsoleApplicationState
 > {
-  static MESSAGE_KEY = 'druid-console-message';
-  static MESSAGE_DISMISSED = 'dismissed';
+  static STATUS_TIMEOUT = 2000;
+
   private capabilitiesQueryManager: QueryManager<null, Capabilities>;
 
   static async discoverCapabilities(): Promise<Capabilities> {
+    const capabilitiesOverride = localStorageGet(LocalStorageKeys.CAPABILITIES_OVERRIDE);
+    if (capabilitiesOverride) return capabilitiesOverride as Capabilities;
+
     try {
-      await axios.post('/druid/v2/sql', { query: 'SELECT 1337' });
+      await axios.post(
+        '/druid/v2/sql',
+        { query: 'SELECT 1337', context: { timeout: ConsoleApplication.STATUS_TIMEOUT } },
+        { timeout: ConsoleApplication.STATUS_TIMEOUT },
+      );
     } catch (e) {
       const { response } = e;
       if (response.status !== 405 || response.statusText !== 'Method Not Allowed') {
         return 'working-with-sql'; // other failure
       }
       try {
-        await axios.get('/status');
+        await axios.get('/status', { timeout: ConsoleApplication.STATUS_TIMEOUT });
       } catch (e) {
         return 'broken'; // total failure
       }
diff --git a/web-console/src/utils/general.tsx b/web-console/src/utils/general.tsx
index 33e1437..63e6a4c 100644
--- a/web-console/src/utils/general.tsx
+++ b/web-console/src/utils/general.tsx
@@ -321,3 +321,7 @@ export function downloadFile(text: string, type: string, filename: string): void
   });
   FileSaver.saveAs(blob, filename);
 }
+
+export function escapeSqlIdentifier(identifier: string): string {
+  return `"${identifier.replace(/"/g, '""')}"`;
+}
diff --git a/web-console/src/utils/local-storage-keys.tsx b/web-console/src/utils/local-storage-keys.tsx
index 620dc0e..0dec7d5 100644
--- a/web-console/src/utils/local-storage-keys.tsx
+++ b/web-console/src/utils/local-storage-keys.tsx
@@ -17,6 +17,7 @@
  */
 
 export const LocalStorageKeys = {
+  CAPABILITIES_OVERRIDE: 'capabilities-override' as 'capabilities-override',
   INGESTION_SPEC: 'ingestion-spec' as 'ingestion-spec',
   DATASOURCE_TABLE_COLUMN_SELECTION: 'datasource-table-column-selection' as 'datasource-table-column-selection',
   SEGMENT_TABLE_COLUMN_SELECTION: 'segment-table-column-selection' as 'segment-table-column-selection',
diff --git a/web-console/src/views/datasource-view/datasource-view.tsx b/web-console/src/views/datasource-view/datasource-view.tsx
index d9dfae1..aca475b 100644
--- a/web-console/src/views/datasource-view/datasource-view.tsx
+++ b/web-console/src/views/datasource-view/datasource-view.tsx
@@ -37,6 +37,7 @@ import { AppToaster } from '../../singletons/toaster';
 import {
   addFilter,
   countBy,
+  escapeSqlIdentifier,
   formatBytes,
   formatNumber,
   getDruidErrorMessage,
@@ -558,7 +559,7 @@ GROUP BY 1`;
         {
           icon: IconNames.APPLICATION,
           title: 'Query with SQL',
-          onAction: () => goToQuery(`SELECT * FROM "${datasource}"`),
+          onAction: () => goToQuery(`SELECT * FROM ${escapeSqlIdentifier(datasource)}`),
         },
         {
           icon: IconNames.AUTOMATIC_UPDATES,
diff --git a/web-console/src/views/query-view/column-tree/column-tree.tsx b/web-console/src/views/query-view/column-tree/column-tree.tsx
index 4e0d24f..e833718 100644
--- a/web-console/src/views/query-view/column-tree/column-tree.tsx
+++ b/web-console/src/views/query-view/column-tree/column-tree.tsx
@@ -21,7 +21,7 @@ import { IconNames } from '@blueprintjs/icons';
 import React, { ChangeEvent } from 'react';
 
 import { Loader } from '../../../components';
-import { groupBy } from '../../../utils';
+import { escapeSqlIdentifier, groupBy } from '../../../utils';
 import { ColumnMetadata } from '../../../utils/column-metadata';
 
 import './column-tree.scss';
@@ -159,13 +159,13 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
         const tableSchema = selectedNode.label;
         let columns: string[];
         if (nodeData.childNodes) {
-          columns = nodeData.childNodes.map(child => String(child.label));
+          columns = nodeData.childNodes.map(child => escapeSqlIdentifier(String(child.label)));
         } else {
           columns = ['*'];
         }
         if (tableSchema === 'druid') {
           onQueryStringChange(`SELECT ${columns.join(', ')}
-FROM "${nodeData.label}"
+FROM ${escapeSqlIdentifier(String(nodeData.label))}
 WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY`);
         } else {
           onQueryStringChange(`SELECT ${columns.join(', ')}
@@ -176,23 +176,31 @@ FROM ${tableSchema}.${nodeData.label}`);
       case 2: // Column
         const schemaNode = selectedNode;
         const columnSchema = schemaNode.label;
-        const columnTable = schemaNode.childNodes ? schemaNode.childNodes[nodePath[0]].label : '?';
+        const columnTable = schemaNode.childNodes
+          ? String(schemaNode.childNodes[nodePath[0]].label)
+          : '?';
         if (columnSchema === 'druid') {
           if (nodeData.icon === IconNames.TIME) {
-            onQueryStringChange(`SELECT TIME_FLOOR("${nodeData.label}", 'PT1H') AS "Time", COUNT(*) AS "Count"
-FROM "${columnTable}"
+            onQueryStringChange(`SELECT
+  TIME_FLOOR(${escapeSqlIdentifier(String(nodeData.label))}, 'PT1H') AS "Time",
+  COUNT(*) AS "Count"
+FROM ${escapeSqlIdentifier(columnTable)}
 WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY
 GROUP BY 1
 ORDER BY "Time" ASC`);
           } else {
-            onQueryStringChange(`SELECT "${nodeData.label}", COUNT(*) AS "Count"
-FROM "${columnTable}"
+            onQueryStringChange(`SELECT
+  "${nodeData.label}",
+  COUNT(*) AS "Count"
+FROM ${escapeSqlIdentifier(columnTable)}
 WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY
 GROUP BY 1
 ORDER BY "Count" DESC`);
           }
         } else {
-          onQueryStringChange(`SELECT "${nodeData.label}", COUNT(*) AS "Count"
+          onQueryStringChange(`SELECT
+  ${escapeSqlIdentifier(String(nodeData.label))},
+  COUNT(*) AS "Count"
 FROM ${columnSchema}.${columnTable}
 GROUP BY 1
 ORDER BY "Count" DESC`);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org