This is an automated email from the ASF dual-hosted git repository.
yuqi4733 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 2e2f79a1df [#9272] fix(lance-rest):Fix class absence for Gravitino
Lance REST Server implementation (#9273)
2e2f79a1df is described below
commit 2e2f79a1dfb803f72aea0c1d36a70393f51dad24
Author: Mini Yu <[email protected]>
AuthorDate: Thu Nov 27 09:10:53 2025 +0800
[#9272] fix(lance-rest):Fix class absence for Gravitino Lance REST Server
implementation (#9273)
### What changes were proposed in this pull request?
This pull request introduces a new bootstrap entry point for the Lance
REST facade by adding the `GravitinoLanceRESTServer` class. This class
is responsible for configuring, initializing, starting, joining, and
stopping the Lance REST service, as well as managing the application
lifecycle and shutdown hooks.
New Lance REST server bootstrap:
* Added the `GravitinoLanceRESTServer` class to serve as the main entry
point for starting and managing the lifecycle of the Lance REST service,
including configuration loading, component initialization, service
startup, and graceful shutdown.
### Why are the changes needed?
### Why are the changes needed?
It's a bug. It is caused by the fact that we need to include
https://github.com/apache/gravitino/commit/eb8ace8ae69e8bdda4bce207f09ab221bf29f48c
before merging https://github.com/apache/gravitino/pull/9174
Fix: #9272
### Does this PR introduce _any_ user-facing change?
N/A.
### How was this patch tested?
Test locally and using docker image.
---
bin/gravitino-lance-rest-server.sh.template | 206 +++++++++++++++++++++
build.gradle.kts | 77 +++++++-
.../lance/server/GravitinoLanceRESTServer.java | 107 +++++++++++
3 files changed, 388 insertions(+), 2 deletions(-)
diff --git a/bin/gravitino-lance-rest-server.sh.template
b/bin/gravitino-lance-rest-server.sh.template
new file mode 100644
index 0000000000..17f098903e
--- /dev/null
+++ b/bin/gravitino-lance-rest-server.sh.template
@@ -0,0 +1,206 @@
+#!/bin/bash
+#
+# 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.
+#
+#set -ex
+USAGE="-e Usage: bin/gravitino-lance-rest-server.sh [--config <conf-dir>]\n\t
+ {start|run|stop|restart|status}"
+
+if [[ "$1" == "--config" ]]; then
+ shift
+ conf_dir="$1"
+ if [[ ! -d "${conf_dir}" ]]; then
+ echo "ERROR : ${conf_dir} is not a directory"
+ echo ${USAGE}
+ exit 1
+ else
+ export GRAVITINO_CONF_DIR="${conf_dir}"
+ fi
+ shift
+fi
+
+bin="$(dirname "${BASH_SOURCE-$0}")"
+bin="$(cd "${bin}">/dev/null; pwd)"
+
+. "${bin}/common.sh"
+
+check_java_version
+
+function check_process_status() {
+ local pid=$(found_lance_rest_server_pid)
+
+ if [[ -z "${pid}" ]]; then
+ echo "GravitinoLanceRESTServer is not running"
+ else
+ printArt
+ echo "GravitinoLanceRESTServer is running[PID:$pid]"
+ fi
+}
+
+function found_lance_rest_server_pid() {
+ process_name='GravitinoLanceRESTServer';
+ RUNNING_PIDS=$(ps x | grep ${process_name} | grep -v grep | awk '{print
$1}');
+
+ if [[ -z "${RUNNING_PIDS}" ]]; then
+ return
+ fi
+
+ if ! kill -0 ${RUNNING_PIDS} > /dev/null 2>&1; then
+ echo "GravitinoLanceRESTServer running but process is dead"
+ fi
+
+ echo "${RUNNING_PIDS}"
+}
+
+function wait_for_lance_rest_server_to_die() {
+ timeout=10
+ timeoutTime=$(date "+%s")
+ let "timeoutTime+=$timeout"
+ currentTime=$(date "+%s")
+ forceKill=1
+
+ while [[ $currentTime -lt $timeoutTime ]]; do
+ local pid=$(found_lance_rest_server_pid)
+ if [[ -z "${pid}" ]]; then
+ forceKill=0
+ break
+ fi
+
+ kill ${pid} > /dev/null 2> /dev/null
+ if kill -0 ${pid} > /dev/null 2>&1; then
+ sleep 3
+ else
+ forceKill=0
+ break
+ fi
+ currentTime=$(date "+%s")
+ done
+
+ if [[ $forceKill -ne 0 ]]; then
+ kill -9 ${pid} > /dev/null 2> /dev/null
+ fi
+}
+
+function start() {
+ local pid=$(found_lance_rest_server_pid)
+
+ if [[ ! -z "${pid}" ]]; then
+ if kill -0 ${pid} >/dev/null 2>&1; then
+ echo "GravitinoLanceRESTServer is already running"
+ return 0;
+ fi
+ fi
+
+ if [[ ! -d "${GRAVITINO_LOG_DIR}" ]]; then
+ echo "Log dir doesn't exist, create ${GRAVITINO_LOG_DIR}"
+ mkdir -p "${GRAVITINO_LOG_DIR}"
+ fi
+
+ nohup ${JAVA_RUNNER} ${JAVA_OPTS} ${GRAVITINO_DEBUG_OPTS} -cp
${GRAVITINO_CLASSPATH} ${GRAVITINO_SERVER_NAME} >> "${GRAVITINO_OUTFILE}" 2>&1 &
+
+ pid=$!
+ if [[ -z "${pid}" ]]; then
+ echo "GravitinoLanceRESTServer start error!"
+ return 1;
+ fi
+
+ sleep 2
+ check_process_status
+}
+
+function run() {
+ ${JAVA_RUNNER} ${JAVA_OPTS} ${GRAVITINO_DEBUG_OPTS} -cp
${GRAVITINO_CLASSPATH} ${GRAVITINO_SERVER_NAME}
+}
+
+function stop() {
+ local pid
+
+ pid=$(found_lance_rest_server_pid)
+
+ if [[ -z "${pid}" ]]; then
+ echo "GravitinoLanceRESTServer is not running"
+ else
+ wait_for_lance_rest_server_to_die
+ echo "GravitinoLanceRESTServer stop"
+ fi
+}
+
+HOSTNAME=$(hostname)
+GRAVITINO_OUTFILE="${GRAVITINO_LOG_DIR}/gravitino-lance-rest-server.out"
+GRAVITINO_SERVER_NAME=org.apache.gravitino.lance.server.GravitinoLanceRESTServer
+GRAVITINO_SIMPLE_SERVER_NAME=gravitino-lance-rest-server
+
+JAVA_OPTS+=" -Dfile.encoding=UTF-8"
+JAVA_OPTS+="
-Dlog4j2.configurationFile=file://${GRAVITINO_CONF_DIR}/log4j2.properties"
+JAVA_OPTS+=" -Dgravitino.log.path=${GRAVITINO_LOG_DIR} ${GRAVITINO_MEM}"
+JAVA_OPTS+=" -Dgravitino.server.name=${GRAVITINO_SIMPLE_SERVER_NAME}"
+if [ "$JVM_VERSION" -eq 17 ]; then
+ JAVA_OPTS+=" -XX:+IgnoreUnrecognizedVMOptions"
+ JAVA_OPTS+=" --add-opens java.base/java.io=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.lang.invoke=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.lang.reflect=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.lang=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.math=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.net=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.nio=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.text=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.time=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.util.concurrent=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.util.regex=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/java.util=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/jdk.internal.ref=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.sql/java.sql=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/sun.util.calendar=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/sun.nio.ch=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/sun.nio.cs=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/sun.security.action=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.base/sun.util.calendar=ALL-UNNAMED"
+ JAVA_OPTS+=" --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED"
+fi
+
+#JAVA_OPTS+=" -Djava.security.krb5.conf=/etc/krb5.conf"
+
+if [ -d "${GRAVITINO_HOME}/lance-rest-server/libs" ]; then
+ addJarInDir "${GRAVITINO_HOME}/lance-rest-server/libs"
+ addDirToClasspath "${GRAVITINO_HOME}/lance-rest-server/conf"
+else
+ addJarInDir "${GRAVITINO_HOME}/libs"
+fi
+
+case "${1}" in
+ start)
+ start
+ ;;
+ run)
+ run
+ ;;
+ stop)
+ stop
+ ;;
+ restart)
+ stop
+ start
+ ;;
+ status)
+ check_process_status
+ ;;
+ *)
+ echo ${USAGE}
+esac
diff --git a/build.gradle.kts b/build.gradle.kts
index d805b00002..be919c3c0d 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -773,6 +773,51 @@ tasks {
}
}
+ val compileLanceRESTServer by registering {
+ dependsOn("lance:lance-rest-server:copyLibAndConfigsToStandalonePackage")
+ group = "gravitino distribution"
+
outputs.dir(projectDir.dir("distribution/${rootProject.name}-lance-rest-server"))
+ doLast {
+ copy {
+ from(projectDir.dir("conf")) {
+ include(
+ "${rootProject.name}-lance-rest-server.conf.template",
+ "${rootProject.name}-env.sh.template",
+ "log4j2.properties.template"
+ )
+ into("${rootProject.name}-lance-rest-server/conf")
+ }
+ from(projectDir.dir("bin")) {
+ include("common.sh.template",
"${rootProject.name}-lance-rest-server.sh.template")
+ into("${rootProject.name}-lance-rest-server/bin")
+ }
+ into(outputDir)
+ rename { fileName ->
+ fileName.replace(".template", "")
+ }
+ eachFile {
+ if (name == "gravitino-env.sh") {
+ filter { line ->
+ line.replace("GRAVITINO_VERSION_PLACEHOLDER", "$version")
+ }
+ }
+ }
+ fileMode = 0b111101101
+ }
+
+ copy {
+ from(projectDir.dir("licenses")) {
into("${rootProject.name}-lance-rest-server/licenses") }
+ from(projectDir.file("LICENSE.rest")) {
into("${rootProject.name}-lance-rest-server") }
+ from(projectDir.file("NOTICE.rest")) {
into("${rootProject.name}-lance-rest-server") }
+ from(projectDir.file("README.md")) {
into("${rootProject.name}-lance-rest-server") }
+ into(outputDir)
+ rename { fileName ->
+ fileName.replace(".rest", "")
+ }
+ }
+ }
+ }
+
val compileTrinoConnector by registering {
dependsOn("trino-connector:trino-connector:copyLibs")
group = "gravitino distribution"
@@ -792,7 +837,7 @@ tasks {
}
val assembleDistribution by registering(Tar::class) {
- dependsOn("assembleTrinoConnector", "assembleIcebergRESTServer")
+ dependsOn("assembleTrinoConnector", "assembleIcebergRESTServer",
"assembleLanceRESTServer")
group = "gravitino distribution"
finalizedBy("checksumDistribution")
into("${rootProject.name}-$version-bin")
@@ -813,6 +858,17 @@ tasks {
destinationDirectory.set(projectDir.dir("distribution"))
}
+ val assembleLanceRESTServer by registering(Tar::class) {
+ dependsOn("compileLanceRESTServer")
+ group = "gravitino distribution"
+ finalizedBy("checksumLanceRESTServerDistribution")
+ into("${rootProject.name}-lance-rest-server-$version-bin")
+ from(compileLanceRESTServer.map { it.outputs.files.single() })
+ compression = Compression.GZIP
+
archiveFileName.set("${rootProject.name}-lance-rest-server-$version-bin.tar.gz")
+ destinationDirectory.set(projectDir.dir("distribution"))
+ }
+
val assembleIcebergRESTServer by registering(Tar::class) {
dependsOn("compileIcebergRESTServer")
group = "gravitino distribution"
@@ -840,9 +896,25 @@ tasks {
}
}
+ register("checksumLanceRESTServerDistribution") {
+ group = "gravitino distribution"
+ dependsOn(assembleLanceRESTServer)
+ val archiveFile = assembleLanceRESTServer.flatMap { it.archiveFile }
+ val checksumFile = archiveFile.map { archive ->
+ archive.asFile.let { it.resolveSibling("${it.name}.sha256") }
+ }
+ inputs.file(archiveFile)
+ outputs.file(checksumFile)
+ doLast {
+ checksumFile.get().writeText(
+
serviceOf<ChecksumService>().sha256(archiveFile.get().asFile).toString()
+ )
+ }
+ }
+
register("checksumDistribution") {
group = "gravitino distribution"
- dependsOn(assembleDistribution, "checksumTrinoConnector",
"checksumIcebergRESTServerDistribution")
+ dependsOn(assembleDistribution, "checksumTrinoConnector",
"checksumIcebergRESTServerDistribution", "checksumLanceRESTServerDistribution")
val archiveFile = assembleDistribution.flatMap { it.archiveFile }
val checksumFile = archiveFile.map { archive ->
archive.asFile.let { it.resolveSibling("${it.name}.sha256") }
@@ -886,6 +958,7 @@ tasks {
!it.name.startsWith("filesystem") &&
!it.name.startsWith("flink") &&
!it.name.startsWith("iceberg") &&
+ !it.name.startsWith("lance") &&
!it.name.startsWith("spark") &&
it.name != "hadoop-common" &&
it.name != "hive-metastore-common" &&
diff --git
a/lance/lance-rest-server/src/main/java/org/apache/gravitino/lance/server/GravitinoLanceRESTServer.java
b/lance/lance-rest-server/src/main/java/org/apache/gravitino/lance/server/GravitinoLanceRESTServer.java
new file mode 100644
index 0000000000..e28bdd5c17
--- /dev/null
+++
b/lance/lance-rest-server/src/main/java/org/apache/gravitino/lance/server/GravitinoLanceRESTServer.java
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+package org.apache.gravitino.lance.server;
+
+import org.apache.gravitino.Config;
+import org.apache.gravitino.GravitinoEnv;
+import org.apache.gravitino.lance.LanceRESTService;
+import org.apache.gravitino.lance.common.config.LanceConfig;
+import org.apache.gravitino.server.ServerConfig;
+import org.apache.gravitino.server.authentication.ServerAuthenticator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Bootstrap entry point for the Lance REST facade. */
+public class GravitinoLanceRESTServer {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(GravitinoLanceRESTServer.class);
+
+ public static final String CONF_FILE = "gravitino-lance-rest-server.conf";
+
+ private final Config serverConfig;
+
+ private LanceRESTService lanceRESTService;
+ private GravitinoEnv gravitinoEnv;
+
+ public GravitinoLanceRESTServer(Config config) {
+ this.serverConfig = config;
+ this.gravitinoEnv = GravitinoEnv.getInstance();
+ this.lanceRESTService = new LanceRESTService();
+ }
+
+ private void initialize() {
+ gravitinoEnv.initializeBaseComponents(serverConfig);
+ lanceRESTService.serviceInit(
+ serverConfig.getConfigsWithPrefix(LanceConfig.LANCE_CONFIG_PREFIX));
+ ServerAuthenticator.getInstance().initialize(serverConfig);
+ }
+
+ private void start() {
+ gravitinoEnv.start();
+ lanceRESTService.serviceStart();
+ }
+
+ private void join() {
+ lanceRESTService.join();
+ }
+
+ private void stop() throws Exception {
+ lanceRESTService.serviceStop();
+ LOG.info("Gravitino Lance REST service stopped");
+ }
+
+ public static void main(String[] args) {
+ LOG.info("Starting Gravitino Lance REST Server");
+ String confPath = System.getenv("GRAVITINO_TEST") == null ? "" : args[0];
+ ServerConfig serverConfig = ServerConfig.loadConfig(confPath, CONF_FILE);
+ GravitinoLanceRESTServer lanceRESTServer = new
GravitinoLanceRESTServer(serverConfig);
+ lanceRESTServer.initialize();
+
+ try {
+ lanceRESTServer.start();
+ } catch (Exception e) {
+ LOG.error("Error while running lance REST server", e);
+ System.exit(-1);
+ }
+ LOG.info("Done, Gravitino Lance REST server started.");
+
+ Runtime.getRuntime()
+ .addShutdownHook(
+ new Thread(
+ () -> {
+ try {
+
Thread.sleep(serverConfig.get(ServerConfig.SERVER_SHUTDOWN_TIMEOUT));
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ LOG.error("Interrupted exception:", e);
+ } catch (Exception e) {
+ LOG.error("Error while running clean-up tasks in shutdown
hook", e);
+ }
+ }));
+ lanceRESTServer.join();
+
+ LOG.info("Shutting down Gravitino Lance REST Server ... ");
+ try {
+ lanceRESTServer.stop();
+ LOG.info("Gravitino Lance REST Server has shut down.");
+ } catch (Exception e) {
+ LOG.error("Error while stopping Gravitino Lance REST Server", e);
+ }
+ }
+}