[] = [
>
),
},
+ {
+ name: 'featureSpec',
+ label: 'JSON parser features',
+ type: 'json',
+ defined: typeIs('json'),
+ info: (
+ <>
+
+
+ JSON parser features
+ {' '}
+ supported by Jackson library. Those features will be applied when parsing the input JSON
+ data.
+
+
+ Example:{' '}
+ {`{ "ALLOW_SINGLE_QUOTES": true, "ALLOW_UNQUOTED_FIELD_NAMES": true }`}
+
+ >
+ ),
+ },
+ {
+ name: 'delimiter',
+ type: 'string',
+ defaultValue: '\t',
+ suggestions: ['\t', ';', '|', '#'],
+ defined: typeIs('tsv'),
+ info: <>A custom delimiter for data values.>,
+ },
{
name: 'pattern',
type: 'string',
@@ -110,14 +140,6 @@ export const INPUT_FORMAT_FIELDS: Field[] = [
>
),
},
- {
- name: 'delimiter',
- type: 'string',
- defaultValue: '\t',
- suggestions: ['\t', ';', '|', '#'],
- defined: typeIs('tsv'),
- info: <>A custom delimiter for data values.>,
- },
{
name: 'listDelimiter',
type: 'string',
diff --git a/web-console/src/druid-models/input-source.tsx b/web-console/src/druid-models/input-source.tsx
index 8c4302e28b2..116ef48a839 100644
--- a/web-console/src/druid-models/input-source.tsx
+++ b/web-console/src/druid-models/input-source.tsx
@@ -41,6 +41,10 @@ export interface InputSource {
// hdfs
paths?: string;
+
+ // http
+ httpAuthenticationUsername?: any;
+ httpAuthenticationPassword?: any;
}
export function issueWithInputSource(inputSource: InputSource | undefined): string | undefined {
diff --git a/web-console/src/utils/capabilities.ts b/web-console/src/utils/capabilities.ts
index 4ad0dd2fb6b..406115dfc99 100644
--- a/web-console/src/utils/capabilities.ts
+++ b/web-console/src/utils/capabilities.ts
@@ -45,6 +45,7 @@ export class Capabilities {
static COORDINATOR_OVERLORD: Capabilities;
static COORDINATOR: Capabilities;
static OVERLORD: Capabilities;
+ static NO_PROXY: Capabilities;
private readonly queryType: QueryType;
private readonly coordinator: boolean;
@@ -96,7 +97,7 @@ export class Capabilities {
static async detectNode(node: 'coordinator' | 'overlord'): Promise {
try {
- await Api.instance.get(`/druid/${node === 'overlord' ? 'indexer' : node}/v1/isLeader`, {
+ await Api.instance.get(`/proxy/${node}/status`, {
timeout: Capabilities.STATUS_TIMEOUT,
});
} catch (e) {
@@ -218,3 +219,8 @@ Capabilities.OVERLORD = new Capabilities({
coordinator: false,
overlord: true,
});
+Capabilities.NO_PROXY = new Capabilities({
+ queryType: 'nativeAndSql',
+ coordinator: false,
+ overlord: false,
+});
diff --git a/web-console/src/utils/general.tsx b/web-console/src/utils/general.tsx
index fb651e18296..e1c064a0059 100644
--- a/web-console/src/utils/general.tsx
+++ b/web-console/src/utils/general.tsx
@@ -310,6 +310,21 @@ export function formatDurationWithMs(ms: NumberLike): string {
);
}
+export function formatDurationHybrid(ms: NumberLike): string {
+ const n = Number(ms);
+ if (n < 600000) {
+ // anything that looks like 1:23.45 (max 9:59.99)
+ const timeInMin = Math.floor(n / 60000);
+ const timeInSec = Math.floor(n / 1000) % 60;
+ const timeInMs = Math.floor(n) % 1000;
+ return `${timeInMin ? `${timeInMin}:` : ''}${timeInMin ? pad2(timeInSec) : timeInSec}.${pad3(
+ timeInMs,
+ ).substring(0, 2)}s`;
+ } else {
+ return formatDuration(n);
+ }
+}
+
export function pluralIfNeeded(n: NumberLike, singular: string, plural?: string): string {
if (!plural) plural = singular + 's';
return `${formatInteger(n)} ${n === 1 ? singular : plural}`;
@@ -512,3 +527,7 @@ export function hashJoaat(str: string): number {
export function objectHash(obj: any): string {
return hashJoaat(JSONBig.stringify(obj)).toString(16).padStart(8);
}
+
+export function hasPopoverOpen(): boolean {
+ return Boolean(document.querySelector('.bp4-portal .bp4-overlay .bp4-popover2'));
+}
diff --git a/web-console/src/utils/sampler.ts b/web-console/src/utils/sampler.ts
index a8619a5bafd..5ebd49d67b1 100644
--- a/web-console/src/utils/sampler.ts
+++ b/web-console/src/utils/sampler.ts
@@ -139,13 +139,15 @@ export interface HeaderFromSampleResponseOptions {
ignoreTimeColumn?: boolean;
columnOrder?: string[];
suffixColumnOrder?: string[];
+ useInput?: boolean;
}
export function headerFromSampleResponse(options: HeaderFromSampleResponseOptions): string[] {
- const { sampleResponse, ignoreTimeColumn, columnOrder, suffixColumnOrder } = options;
+ const { sampleResponse, ignoreTimeColumn, columnOrder, suffixColumnOrder, useInput } = options;
+ const key = useInput ? 'input' : 'parsed';
let columns = arrangeWithPrefixSuffix(
- dedupe(sampleResponse.data.flatMap(s => (s.parsed ? Object.keys(s.parsed) : []))),
+ dedupe(sampleResponse.data.flatMap(s => (s[key] ? Object.keys(s[key]!) : []))),
columnOrder || [TIME_COLUMN],
suffixColumnOrder || [],
);
diff --git a/web-console/src/variables.scss b/web-console/src/variables.scss
index d14c0b79a3d..86528e15661 100644
--- a/web-console/src/variables.scss
+++ b/web-console/src/variables.scss
@@ -35,7 +35,7 @@ $druid-brand-background: #1c1c26;
background: $white;
border-radius: $pt-border-radius;
- .bp3-dark & {
+ .#{$bp-ns}-dark & {
background: $dark-gray3;
}
}
diff --git a/web-console/src/views/datasource-view/datasource-view.tsx b/web-console/src/views/datasource-view/datasource-view.tsx
index d04c630b536..b894f7d91c1 100644
--- a/web-console/src/views/datasource-view/datasource-view.tsx
+++ b/web-console/src/views/datasource-view/datasource-view.tsx
@@ -57,6 +57,7 @@ import {
formatMillions,
formatPercent,
getDruidErrorMessage,
+ hasPopoverOpen,
isNumberLikeNaN,
LocalStorageBackedVisibility,
LocalStorageKeys,
@@ -493,7 +494,8 @@ ORDER BY 1`;
});
}
- private readonly refresh = (auto: any): void => {
+ private readonly refresh = (auto: boolean): void => {
+ if (auto && hasPopoverOpen()) return;
this.datasourceQueryManager.rerunLastQuery(auto);
this.tiersQueryManager.rerunLastQuery(auto);
};
diff --git a/web-console/src/views/ingestion-view/ingestion-view.tsx b/web-console/src/views/ingestion-view/ingestion-view.tsx
index 3071ebd4b65..ac4a8afe929 100644
--- a/web-console/src/views/ingestion-view/ingestion-view.tsx
+++ b/web-console/src/views/ingestion-view/ingestion-view.tsx
@@ -47,6 +47,7 @@ import {
deepGet,
formatDuration,
getDruidErrorMessage,
+ hasPopoverOpen,
LocalStorageBackedVisibility,
localStorageGet,
LocalStorageKeys,
@@ -1089,7 +1090,10 @@ ORDER BY "rank" DESC, "created_time" DESC`;
this.supervisorQueryManager.rerunLastQuery(auto)}
+ onRefresh={auto => {
+ if (auto && hasPopoverOpen()) return;
+ this.supervisorQueryManager.rerunLastQuery(auto);
+ }}
/>
{this.renderBulkSupervisorActions()}
this.taskQueryManager.rerunLastQuery(auto)}
+ onRefresh={auto => {
+ if (auto && hasPopoverOpen()) return;
+ this.taskQueryManager.rerunLastQuery(auto);
+ }}
/>
{this.renderBulkTasksActions()}
)}
- {this.renderFlattenControls()}
+ {canFlatten && this.renderFlattenControls()}
{suggestedFlattenFields && suggestedFlattenFields.length ? (
this.serviceQueryManager.rerunLastQuery(auto)}
+ onRefresh={auto => {
+ if (auto && hasPopoverOpen()) return;
+ this.serviceQueryManager.rerunLastQuery(auto);
+ }}
localStorageKey={LocalStorageKeys.SERVICES_REFRESH_RATE}
/>
{this.renderBulkServicesActions()}