Skip to content

Commit c800f2a

Browse files
Ragnaroosclaudemorningman
authored
[feature](ui) Add the new Web UI foundation (#66690)
### What problem does this PR solve? Issue Number: N/A (draft for early design review) Related PR: N/A Problem Summary: The earlier revisions of this draft added the React application under `ui-next/` next to the legacy AngularJS `ui/`, so the new UI was never produced by a normal build. Reviewers and users had to pass `CUSTOM_UI_DIST` by hand, and the packaged default was still the legacy application. This revision finishes that transition instead of maintaining two applications: the React application takes over the `ui/` directory, the AngularJS application is removed, and `./build.sh --fe` produces the new UI with no flag and no change to `build.sh`. ### What changed in the latest revision - `ui/` now holds the React application; the AngularJS sources are deleted and the `ui-next/` directory name is gone. `build_ui()` already builds `${DORIS_HOME}/ui` and packs `${DORIS_HOME}/ui/dist` into the FE resources, so no build script change is required. `CUSTOM_UI_DIST` still works for callers that package a prebuilt directory. - `@testing-library/dom` is now an explicit dev dependency. React Testing Library only lists it as a peer dependency and re-exports `screen`, `fireEvent`, `waitFor` and `within` from it, while `build_ui()` installs with `--legacy-peer-deps`, which does not install peer dependencies. Without the explicit entry the production build fails to type-check every test file. - `enable_web_ui` now defaults to `true`. It gated the UI routes and the SPA forward while the new UI was optional; leaving it `false` would ship a build whose packaged UI answers 404 on every page. - Also in this revision: the Playground toolbar and object-tree refinements, and restoring the resolved identity in the cookie authentication path so `checkAdminAuth` no longer sees a null user. The branch is rebased on master. ### Implemented scope - English-only login and logout. A Doris user must have global `ADMIN` privilege to use UI Next. - Home version information and complete frontend/backend node status tables. - SQL Playground with formatting, a database/table/column object tree, and FE-managed JDBC sessions that preserve SQL session state across statements. Restored browser session IDs are verified with the owning FE before the UI reports the connection as ready. - System proc navigation backed by the existing `/rest/v1/system` API. - Active Sessions backed by the existing `/rest/v1/session` API. - Log configuration, content, and verbose logger management backed by the existing `/rest/v1/log` API. - Query Profile list and raw Text details backed by the existing current-FE `/rest/v1/query_profile*` APIs. Only `Task Type: QUERY` entries are shown. - Visual Profile for structurally compatible `MergedProfile` text. Parsing is performed in a bounded browser Worker, ELK produces the compound Fragment layout, and React Flow renders the read-only DAG. Missing `MergedProfile` data is reported as unavailable; incompatible data reports the parse reason instead of relying on a hard Doris-version gate. - FE and BE Configuration tables backed by the existing manager configuration APIs. Mutable rows expose an ADMIN-only editor; immutable rows remain read-only, including against direct mutation requests. ### FE backend scope The FE addition remains limited to behavior that cannot live safely in the browser: - Login and logout reuse `/rest/v1/login` and `/rest/v1/logout`. A thin `/rest/v1/ui/me` endpoint bootstraps the authenticated ADMIN user and CSRF token. - Home, System, Sessions, Log, Query Profiles, and Configuration reuse existing Doris HTTP controllers rather than adding parallel read controllers. - Web SQL retains FE-local session ownership, one persistent JDBC connection per active session, execution/cancellation, bounded results, idle cleanup, and logout cleanup. It is exposed as the UI-independent `/rest/v1/sql-sessions` API under `org.apache.doris.httpv2.websql`. - Web SQL accepts HTTP Basic authentication or the existing Doris login cookie; both require global `ADMIN`. Cookie mutations additionally require CSRF. - The existing Configuration manager endpoints now accept the authenticated UI cookie, preserve ADMIN authorization, use cluster-internal authentication for FE/BE fan-out, encode configuration values safely, and reject immutable FE changes server-side. - `enable_web_ui=true` is an immutable FE-local master switch for UI routes, assets, login/bootstrap, and stateful SQL endpoints. Setting it to `false` returns 404 for those resources without stopping port 8030 or shared FE HTTP APIs. - `enable_web_sql_session`, `web_sql_session_idle_timeout_seconds`, `web_sql_max_sessions`, and `web_sql_max_result_bytes` are mutable. Running Web SQL operations read their current values without an FE restart. Numeric session limits reject non-positive values; the result-byte limit accepts 1 through 100 MiB. - `StatementSubmitter` and the legacy Login controller remain unchanged from this PR's master baseline. The legacy Log mutation adds only a cookie CSRF check; its existing log behavior and response remain unchanged. The Visual Profile parser and graph are adapted from `apache/doris-website` PR #4043 at commit `133f948c235995a917b2e1f6d4e9d764b6d62726` under the Apache License 2.0. The website uploader, AI analysis, hCaptcha, polling, storage, recovery, and Docusaurus wrapper are not included. ### FE endpoints used by the UI Enumerated from `ui/src/api/**`, split by whether the endpoint is added here or reused from existing Doris controllers. Added by this PR: | Endpoint | Method | Purpose | | --- | --- | --- | | `/rest/v1/ui/me` | GET | Bootstrap after login: current ADMIN user and CSRF token (`UiSessionController`) | | `/rest/v1/sql-sessions` | POST | Create a Web SQL session (`WebSqlSessionController`) | | `/rest/v1/sql-sessions/{id}` | GET, DELETE | Inspect and close a session | | `/rest/v1/sql-sessions/{id}/statements` | POST | Execute exactly one statement | | `/rest/v1/sql-sessions/{id}/cancel` | POST | Cancel the running statement | | `/rest/v1/sql-sessions/{id}/reset` | POST | Reset the connection state | | `/rest/v1/hardware_info/fe/version` | GET | Version-only route on the existing `HardwareInfoController`, so Home does not trigger OSHI hardware collection | Reused, no new controller: | Endpoint | Method | Page | Controller | | --- | --- | --- | --- | | `/rest/v1/login` | POST | Login | `WebConfigurer` | | `/rest/v1/logout` | POST | Sign out | `WebConfigurer` | | `/rest/v1/system?path=/frontends` | GET | Cluster Overview, Frontends | `SystemController` | | `/rest/v1/system?path=/backends` | GET | Cluster Overview, Backends | `SystemController` | | `/rest/v1/system?path=...` | GET | Proc System navigation | `SystemController` | | `/rest/v1/session` | GET | Sessions | `SessionController` | | `/rest/v1/log` | GET | Log configuration and contents | `LogController` | | `/rest/v1/log` | POST | Add or delete a verbose logger, sent as the legacy `add_verbose` / `del_verbose` form parameters | `LogController` | | `/rest/v1/query_profile` | GET | Query Profile list | `QueryProfileAction` | | `/rest/v1/query_profile/text/{queryId}` | GET | Raw profile text, shared by the Text and Visual tabs | `QueryProfileAction` | | `/rest/v2/manager/node/configuration_info?type={fe\|be}` | POST | Configuration read | `NodeAction` | | `/rest/v2/manager/node/set_config/{fe\|be}` | POST | Configuration update, ADMIN only | `NodeAction` | `/rest/v1/ui/**` and `/rest/v1/sql-sessions**` go through `uiRequest`, which requires the login cookie and sends the CSRF header on mutations. Everything else goes through `legacyRequest` and retains each legacy controller's existing authorization behavior. The PR-added `/rest/v1/ui/**` and Web SQL endpoints require global `ADMIN`; reused legacy endpoints are not all globally ADMIN-only. Web SQL additionally accepts HTTP Basic. ### Behavior and impact - The FE web port now serves the React application. The AngularJS application is no longer part of the repository, so a legacy build is no longer a rollback option; reverting this change is. - Node.js 22.12 or newer and npm are required to build FE. The repository's x86, gcc10 and ARM compilation images are updated to provide Node.js 22.12.0. Neither Node.js nor npm is required at runtime. - Web SQL sessions remain behind `enable_web_sql_session`. ### Validation - `./build.sh --fe` with no flags builds the React application and packs it: the resulting `doris-fe.jar` `static/` payload matches `ui/dist` file for file. - `npm run lint`, `npm run typecheck`, `npm run test` and `npm run build` in `ui/`. - The branch is rebased on master and merges cleanly. ### Release note The Doris FE Web UI is replaced with a new React application. Repository compilation images now provide Node.js 22.12.0; the ARM image uses AlmaLinux 8 because the official Node.js 22 ARM64 binary requires a newer glibc than CentOS 7 provides. ### Check List (For Author) - Test - [ ] Regression test - [x] Unit Test - [x] Manual test (development and packaging steps are documented in `ui/README.md`) - [ ] No need to test or manual test. Explain why: - Behavior changed: - [ ] No. - [x] Yes. The FE web port serves the new UI, and the AngularJS UI is removed. - Does this need documentation? - [x] No. Development and packaging instructions are included in `ui/README.md`. - [ ] Yes. ### Follow-up - Add CI coverage for the UI directory. No workflow currently runs its lint, typecheck, test or build, so frontend regressions cannot fail a build. - Split the production bundle further; Vite currently reports large ELK and application chunks. --------- Co-authored-by: Ragnaroos <Ragnaroos@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: morningman <yunyou@selectdb.com>
1 parent 2689e0d commit c800f2a

230 files changed

Lines changed: 20927 additions & 6004 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-ui.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
#
18+
---
19+
name: FE Web UI
20+
21+
on:
22+
pull_request:
23+
workflow_dispatch:
24+
concurrency:
25+
group: ${{ github.ref }} (FE Web UI)
26+
cancel-in-progress: true
27+
28+
jobs:
29+
changes:
30+
name: Detect Changes
31+
runs-on: ubuntu-latest
32+
outputs:
33+
ui_changes: ${{ steps.filter.outputs.ui_changes }}
34+
steps:
35+
- name: Checkout ${{ github.ref }}
36+
uses: actions/checkout@v3
37+
with:
38+
persist-credentials: false
39+
submodules: recursive
40+
41+
- name: Paths filter
42+
uses: ./.github/actions/paths-filter
43+
id: filter
44+
with:
45+
filters: |
46+
ui_changes:
47+
- 'ui/**'
48+
- '.github/workflows/build-ui.yml'
49+
50+
build-ui:
51+
name: Lint, Typecheck, Test and Build
52+
needs: changes
53+
if: ${{ needs.changes.outputs.ui_changes == 'true' }}
54+
runs-on: ubuntu-latest
55+
steps:
56+
- name: Checkout ${{ github.ref }}
57+
uses: actions/checkout@v3
58+
with:
59+
persist-credentials: false
60+
61+
# Keep this in step with the "engines" floor in ui/package.json and with the Node version
62+
# the compilation images install, so a green build here means ./build.sh --fe also builds.
63+
- name: Setup Node.js
64+
uses: actions/setup-node@v4
65+
with:
66+
node-version: '22.12.0'
67+
68+
# Same resolution as build.sh: the committed lockfile, with --legacy-peer-deps.
69+
- name: Install dependencies
70+
run: npm ci --legacy-peer-deps
71+
working-directory: ui
72+
73+
- name: Lint
74+
run: npm run lint
75+
working-directory: ui
76+
77+
- name: Typecheck
78+
run: npm run typecheck
79+
working-directory: ui
80+
81+
- name: Unit tests
82+
run: npm run test
83+
working-directory: ui
84+
85+
- name: Production build
86+
run: npm run build
87+
working-directory: ui

.github/workflows/third_party_review.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,13 @@ jobs:
6060
# You can only include one of these two options: `allow-licenses` and `deny-licenses`
6161
# ([String]). Only allow these licenses (optional)
6262
# Possible values: Any SPDX-compliant license identifiers or expressions from https://spdx.org/licenses/
63-
allow-licenses: BSD-2-Clause, BSD-3-Clause, MIT, Apache-2.0, EPL-2.0, MPL-2.0, CC0-1.0
63+
# Project-approved licenses, including permissive Category A licenses from the ASF policy.
64+
allow-licenses: >-
65+
BSD-2-Clause, BSD-3-Clause, BSD-2-Clause-Views, MIT, MIT-0, ISC,
66+
Apache-2.0, EPL-2.0, MPL-2.0, CC0-1.0, Python-2.0, BlueOak-1.0.0
67+
# caniuse-lite is browser-compatibility data used only by the UI build toolchain.
68+
# Keep this exception package-specific because CC-BY-4.0 is not generally allow-listed.
69+
allow-dependencies-licenses: pkg:npm/caniuse-lite@1.0.30001809
6470
# ([String]). Acknowledged advisories that must not fail the review (optional)
6571
# org.codehaus.jackson:jackson-mapper-asl (GHSA-c27h-mcmw-48hv, GHSA-r6j9-8759-g62w):
6672
# legacy Jackson 1.x is EOL and neither advisory has a fixed version. Hive's metastore
@@ -70,4 +76,4 @@ jobs:
7076
allow-ghsas: GHSA-c27h-mcmw-48hv, GHSA-r6j9-8759-g62w
7177
# ([String]). Block pull requests that introduce vulnerabilities in the scopes that match this list (optional)
7278
# Possible values: "development", "runtime", "unknown"
73-
fail-on-scopes: development, runtime
79+
fail-on-scopes: development, runtime

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ dependency-reduced-pom.xml
2525
yarn.lock
2626
ut_dir
2727
package-lock.json
28+
# The Web UI lockfile is an exception to the rule above: ui/dist is built into
29+
# doris-fe.jar and shipped, so the exact dependency set has to be recorded in the
30+
# source tree for the binary release to be reproducible from it.
31+
!ui/package-lock.json
2832
__pycache__
2933

3034
# ignore all sub `/bin` and `/build` directory

LICENSE.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,4 +737,12 @@ The Mission Control source code is made available under the Universal Permissive
737737
Version 1.0 or a BSD-style license, alternatively. The full open source license text is available
738738
at license/LICENSE.txt in the JMC project.
739739

740-
----------------------------------------------------------------------------------
740+
----------------------------------------------------------------------------------
741+
742+
ui bundled dependency elkjs 0.12.0: Eclipse Public License v2.0
743+
744+
elkjs is offered under EPL-2.0 OR GPL-3.0-or-later. This distribution elects
745+
EPL-2.0. The full Eclipse Public License v2.0 text is available at
746+
dist/licenses/LICENSE-EPL-2.0.txt.
747+
748+
----------------------------------------------------------------------------------

build.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,8 +1045,9 @@ function build_ui() {
10451045
ui_dist="${CUSTOM_UI_DIST}"
10461046
else
10471047
cd "${DORIS_HOME}/ui"
1048-
"${NPM}" cache clean --force
1049-
"${NPM}" install --legacy-peer-deps
1048+
# ci, not install: the shipped bundle must come from the committed lockfile so that
1049+
# the same source tree always produces the same static/ payload.
1050+
"${NPM}" ci --legacy-peer-deps
10501051
"${NPM}" run build
10511052
fi
10521053
echo "ui dist: ${ui_dist}"

dist/LICENSE-dist.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,8 @@ Eclipse Public License - v2.0 -- licenses/LICENSE-EPL-2.0.txt
13461346
* Jakarta WebSocket - Server API:
13471347
- jakarta.websocket:jakarta.websocket-api:1.1.2 (https://projects.eclipse.org/projects/ee4j.websocket)
13481348
### The following components use multiple licenses and we choose EPLv2
1349+
* elkjs:
1350+
- npm:elkjs:0.12.0 (https://github.com/kieler/elkjs)
13491351
* javax.inject:1 as OSGi bundle:
13501352
- org.glassfish.hk2.external:jakarta.inject:2.6.1 (https://github.com/eclipse-ee4j/glassfish-hk2/external/jakarta.inject)
13511353
* Jakarta Servlet:

docker/compilation/Dockerfile

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
4747
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
4848

4949
# install nodejs
50-
RUN wget https://nodejs.org/download/release/latest-v14.x/node-v14.21.3-linux-x64.tar.gz \
51-
-q -O /tmp/node-v14.21.3-linux-x64.tar.gz \
52-
&& cd /tmp/ && tar -xf node-v14.21.3-linux-x64.tar.gz \
53-
&& cp -r node-v14.21.3-linux-x64/* /usr/local/ \
54-
&& rm /tmp/node-v14.21.3-linux-x64.tar.gz && rm -rf node-v14.21.3-linux-x64
50+
ARG NODEJS_VERSION=22.12.0
51+
RUN wget https://nodejs.org/dist/v${NODEJS_VERSION}/node-v${NODEJS_VERSION}-linux-x64.tar.xz \
52+
-q -O /tmp/node-v${NODEJS_VERSION}-linux-x64.tar.xz \
53+
&& cd /tmp/ && tar -xf node-v${NODEJS_VERSION}-linux-x64.tar.xz \
54+
&& cp -r node-v${NODEJS_VERSION}-linux-x64/* /usr/local/ \
55+
&& rm /tmp/node-v${NODEJS_VERSION}-linux-x64.tar.xz \
56+
&& rm -rf node-v${NODEJS_VERSION}-linux-x64
5557

5658
# install Rust for lance-c
5759
ARG RUST_TOOLCHAIN="1.91.0"

docker/compilation/Dockerfile.gcc10

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,13 @@ RUN wget https://github.com/westes/flex/releases/download/v$FLEX_VERSION/flex-$F
6363
&& rm -rf /tmp/flex-$FLEX_VERSION
6464

6565
# install nodejs
66-
ARG NODEJS_VERSION=14.16.0
67-
RUN wget https://nodejs.org/dist/v$NODEJS_VERSION/node-v$NODEJS_VERSION-linux-x64.tar.gz \
68-
-q -O /tmp/node-v$NODEJS_VERSION-linux-x64.tar.gz \
69-
&& cd /tmp/ && tar -xf node-v$NODEJS_VERSION-linux-x64.tar.gz \
70-
&& cp -r node-v$NODEJS_VERSION-linux-x64/* /usr/local/ \
71-
&& rm /tmp/node-v$NODEJS_VERSION-linux-x64.tar.gz && rm -rf node-v$NODEJS_VERSION-linux-x64
66+
ARG NODEJS_VERSION=22.12.0
67+
RUN wget https://unofficial-builds.nodejs.org/download/release/v${NODEJS_VERSION}/node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
68+
-q -O /tmp/node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
69+
&& cd /tmp/ && tar -xf node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
70+
&& cp -r node-v${NODEJS_VERSION}-linux-x64-glibc-217/* /usr/local/ \
71+
&& rm /tmp/node-v${NODEJS_VERSION}-linux-x64-glibc-217.tar.xz \
72+
&& rm -rf node-v${NODEJS_VERSION}-linux-x64-glibc-217
7273

7374

7475
ENV BASH_ENV=/opt/rh/devtoolset-10/enable \

docker/compilation/arm/Dockerfile

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,20 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
FROM centos:7 AS builder
18+
FROM almalinux:8 AS builder
1919

2020
# install epel repo for ccache
21-
RUN yum install epel-release -y && yum clean all && yum makecache
21+
RUN dnf install -y dnf-plugins-core epel-release \
22+
&& dnf config-manager --set-enabled powertools \
23+
&& dnf clean all \
24+
&& dnf makecache
2225

2326
# install dependencies
24-
RUN yum install -y byacc patch automake libtool perf vim make which file ncurses-devel gettext-devel unzip bzip2 zip util-linux \
27+
RUN dnf install -y byacc patch automake libtool perf vim make which file ncurses-devel gettext-devel unzip bzip2 zip util-linux \
2528
ccache wget git python2 bison java-11-openjdk-devel java-1.8.0-openjdk-devel
2629

2730
# clean cache
28-
RUN yum clean all
31+
RUN dnf clean all
2932

3033
# install maven 3.9.9
3134
RUN mkdir -p /usr/share/maven /usr/share/maven/ref && \
@@ -35,11 +38,13 @@ RUN mkdir -p /usr/share/maven /usr/share/maven/ref && \
3538
ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
3639

3740
# install nodejs
38-
RUN wget https://nodejs.org/dist/v16.3.0/node-v16.3.0-linux-arm64.tar.xz \
39-
-q -O /tmp/node-v16.3.0-linux-arm64.tar.xz \
40-
&& cd /tmp/ && tar -xf node-v16.3.0-linux-arm64.tar.xz \
41-
&& cp -r node-v16.3.0-linux-arm64/* /usr/local/ \
42-
&& rm /tmp/node-v16.3.0-linux-arm64.tar.xz && rm -rf node-v16.3.0-linux-arm64
41+
ARG NODEJS_VERSION=22.12.0
42+
RUN wget https://nodejs.org/dist/v${NODEJS_VERSION}/node-v${NODEJS_VERSION}-linux-arm64.tar.xz \
43+
-q -O /tmp/node-v${NODEJS_VERSION}-linux-arm64.tar.xz \
44+
&& cd /tmp/ && tar -xf node-v${NODEJS_VERSION}-linux-arm64.tar.xz \
45+
&& cp -r node-v${NODEJS_VERSION}-linux-arm64/* /usr/local/ \
46+
&& rm /tmp/node-v${NODEJS_VERSION}-linux-arm64.tar.xz \
47+
&& rm -rf node-v${NODEJS_VERSION}-linux-arm64
4348

4449
# install ldb-toolchain
4550
RUN wget https://github.com/amosbird/ldb_toolchain_gen/releases/download/v0.9.1/ldb_toolchain_gen.aarch64.sh \

fe/fe-common/src/main/java/org/apache/doris/common/Config.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.doris.common;
1919

2020
import java.io.File;
21+
import java.lang.reflect.Field;
2122

2223
public class Config extends ConfigBase {
2324
@ConfField(description = "The path of the user-defined configuration file, used to store fe_custom.conf. "
@@ -1519,6 +1520,10 @@ public class Config extends ConfigBase {
15191520
@ConfField
15201521
public static boolean enable_http_server_v2 = true;
15211522

1523+
@ConfField(mutable = false, masterOnly = false,
1524+
description = "Whether to enable the FE Web UI and its dedicated APIs.")
1525+
public static boolean enable_web_ui = true;
1526+
15221527
/*
15231528
* Base path is the URL prefix for all API paths.
15241529
* Some deployment environments need to configure additional base path to match resources.
@@ -2788,6 +2793,64 @@ public class Config extends ConfigBase {
27882793
+ "SQL submitter.")
27892794
public static int http_sql_submitter_max_worker_threads = 2;
27902795

2796+
@ConfField(mutable = true, masterOnly = false,
2797+
description = "Whether to enable stateful Web SQL HTTP sessions.")
2798+
public static boolean enable_web_sql_session = true;
2799+
2800+
@ConfField(mutable = true, masterOnly = false, callback = PositiveWebSqlIntegerConfHandler.class,
2801+
description = "Idle timeout for Web SQL sessions, in seconds.")
2802+
public static int web_sql_session_idle_timeout_seconds = 1800;
2803+
2804+
@ConfField(mutable = true, masterOnly = false, callback = PositiveWebSqlIntegerConfHandler.class,
2805+
description = "Maximum number of Web SQL sessions on one FE.")
2806+
public static int web_sql_max_sessions = 100;
2807+
2808+
/** Rejects non-positive dynamic Web SQL session limits. */
2809+
public static class PositiveWebSqlIntegerConfHandler implements ConfHandler {
2810+
@Override
2811+
public void handle(Field field, String value) throws Exception {
2812+
int parsed = Integer.parseInt(value);
2813+
if (parsed <= 0) {
2814+
throw new ConfigException(field.getName() + " must be greater than 0");
2815+
}
2816+
field.setInt(null, parsed);
2817+
}
2818+
}
2819+
2820+
public static final long WEB_SQL_MAX_RESULT_BYTES_UPPER_BOUND = 100L * 1024 * 1024;
2821+
2822+
/** Validates Web SQL limits loaded from fe.conf and fe_custom.conf at FE startup. */
2823+
public static void validateWebSqlConfig() throws ConfigException {
2824+
if (web_sql_session_idle_timeout_seconds <= 0) {
2825+
throw new ConfigException("web_sql_session_idle_timeout_seconds must be greater than 0");
2826+
}
2827+
if (web_sql_max_sessions <= 0) {
2828+
throw new ConfigException("web_sql_max_sessions must be greater than 0");
2829+
}
2830+
if (web_sql_max_result_bytes <= 0
2831+
|| web_sql_max_result_bytes > WEB_SQL_MAX_RESULT_BYTES_UPPER_BOUND) {
2832+
throw new ConfigException("web_sql_max_result_bytes must be between 1 and "
2833+
+ WEB_SQL_MAX_RESULT_BYTES_UPPER_BOUND);
2834+
}
2835+
}
2836+
2837+
@ConfField(mutable = true, masterOnly = false, callback = WebSqlMaxResultBytesConfHandler.class,
2838+
description = "Approximate maximum result bytes for one Web SQL statement.")
2839+
public static long web_sql_max_result_bytes = 10 * 1024 * 1024;
2840+
2841+
/** Validates dynamic Web SQL result limits before publishing them to running statements. */
2842+
public static class WebSqlMaxResultBytesConfHandler implements ConfHandler {
2843+
@Override
2844+
public void handle(Field field, String value) throws Exception {
2845+
long parsed = Long.parseLong(value);
2846+
if (parsed <= 0 || parsed > WEB_SQL_MAX_RESULT_BYTES_UPPER_BOUND) {
2847+
throw new ConfigException("web_sql_max_result_bytes must be between 1 and "
2848+
+ WEB_SQL_MAX_RESULT_BYTES_UPPER_BOUND);
2849+
}
2850+
field.setLong(null, parsed);
2851+
}
2852+
}
2853+
27912854
@ConfField(mutable = true, masterOnly = true, description = "The threshold of load labels' number. After this "
27922855
+ "number is exceeded, the labels of the completed " + "import jobs or tasks will be deleted, and the "
27932856
+ "deleted labels can be reused. When the value is -1, " + "it indicates no threshold.")

0 commit comments

Comments
 (0)