diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000000..f72e0789cb --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,43 @@ +name: integration + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "main" branch + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +concurrency: + group: ${{ github.worklfow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_requests' }} + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + integration_test: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + with: + gradle-version: '8.1.1' + + - name: Show gradle version + run: gradle --version + + - name: Package Graviton + run: | + gradle build + gradle compileDistribution \ No newline at end of file diff --git a/.gitignore b/.gitignore index d747398dd9..4bc81cd2e7 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ gen *.iml out/** *.iws + +distribution +server/src/main/resources/project.properties \ No newline at end of file diff --git a/bin/common.sh b/bin/common.sh new file mode 100644 index 0000000000..f097c9c5fb --- /dev/null +++ b/bin/common.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# +# Copyright 2023 Datastrato. +# This software is licensed under the Apache License version 2. +# + +if [ -L "${BASH_SOURCE-$0}" ]; then + FWDIR=$(dirname "$(readlink "${BASH_SOURCE-$0}")") +else + FWDIR=$(dirname "${BASH_SOURCE-$0}") +fi + +echo ${GRAVITON_HOME} + +if [[ -z "${GRAVITON_HOME}" ]]; then + export GRAVITON_HOME="$(cd "${FWDIR}/.." || exit; pwd)" +fi + +if [[ -z "${GRAVITON_CONF_DIR}" ]]; then + export GRAVITON_CONF_DIR="${GRAVITON_HOME}/conf" +fi + +if [[ -z "${GRAVITON_LOG_DIR}" ]]; then + export GRAVITON_LOG_DIR="${GRAVITON_HOME}/logs" +fi + +if [[ -f "${GRAVITON_CONF_DIR}/graviton-env.sh" ]]; then + . "${GRAVITON_CONF_DIR}/graviton-env.sh" +fi + +GRAVITON_CLASSPATH+=":${GRAVITON_CONF_DIR}" + +function check_java_version() { + if [[ -n "${JAVA_HOME+x}" ]]; then + JAVA="$JAVA_HOME/bin/java" + fi + java_ver_output=$("${JAVA:-java}" -version 2>&1) + jvmver=$(echo "$java_ver_output" | grep '[openjdk|java] version' | awk -F'"' 'NR==1 {print $2}' | cut -d\- -f1) + JVM_VERSION=$(echo "$jvmver"|sed -e 's|^\([0-9][0-9]*\)\..*$|\1|') + if [ "$JVM_VERSION" = "1" ]; then + JVM_VERSION=$(echo "$jvmver"|sed -e 's|^1\.\([0-9][0-9]*\)\..*$|\1|') + fi + + # JDK 8u151 version fixed a number of security vulnerabilities and issues to improve system stability and security. + # https://www.oracle.com/java/technologies/javase/8u151-relnotes.html + if [ "$JVM_VERSION" -lt 8 ] || { [ "$JVM_VERSION" -eq 8 ] && [ "${jvmver#*_}" -lt 151 ]; } ; then + echo "Graviton requires either Java 8 update 151 or newer" + exit 1; + fi +} + +function addEachJarInDir(){ + if [[ -d "${1}" ]]; then + for jar in "${1}"/*.jar ; do + GRAVITON_CLASSPATH="${jar}:${GRAVITON_CLASSPATH}" + done + fi +} + +function addEachJarInDirRecursive(){ + if [[ -d "${1}" ]]; then + for jar in "${1}"/**/*.jar ; do + GRAVITON_CLASSPATH="${jar}:${GRAVITON_CLASSPATH}" + done + fi +} + +function addJarInDir(){ + if [[ -d "${1}" ]]; then + GRAVITON_CLASSPATH="${1}/*:${GRAVITON_CLASSPATH}" + fi +} + +if [[ -z "${GRAVITON_MEM}" ]]; then + export GRAVITON_MEM="-Xmx1024m" +fi + +if [[ -n "${JAVA_HOME}" ]]; then + export JAVA_RUNNER="${JAVA_HOME}/bin/java" +else + export JAVA_RUNNER=java +fi diff --git a/bin/graviton.sh b/bin/graviton.sh new file mode 100755 index 0000000000..22e7a23b11 --- /dev/null +++ b/bin/graviton.sh @@ -0,0 +1,152 @@ +#!/bin/bash +# +# Copyright 2023 Datastrato. +# This software is licensed under the Apache License version 2. +# +#set -ex +USAGE="-e Usage: bin/graviton.sh [--config ]\n\t + {start|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 GRAVITON_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_graviton_server_pid) + + if [[ -z "${pid}" ]]; then + echo "Graviton Server is not running" + else + echo "Graviton Server is running[PID:$pid]" + fi +} + +function found_graviton_server_pid() { + process_name='GravitonServer'; + 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 "Graviton Server running but process is dead" + fi + + echo "${RUNNING_PIDS}" +} + +function wait_for_graviton_server_to_die() { + timeout=10 + timeoutTime=$(date "+%s") + let "timeoutTime+=$timeout" + currentTime=$(date "+%s") + forceKill=1 + + while [[ $currentTime -lt $timeoutTime ]]; do + local pid=$(found_graviton_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_graviton_server_pid) + + if [[ ! -z "${pid}" ]]; then + if kill -0 ${pid} >/dev/null 2>&1; then + echo "Graviton Server is already running" + return 0; + fi + fi + + if [[ ! -d "${GRAVITON_LOG_DIR}" ]]; then + echo "Log dir doesn't exist, create ${GRAVITON_LOG_DIR}" + mkdir -p "${GRAVITON_LOG_DIR}" + fi + + nohup ${JAVA_RUNNER} ${JAVA_OPTS} ${GRAVITON_DEBUG_OPTS} -cp ${GRAVITON_CLASSPATH} ${GRAVITON_SERVER_NAME} >> "${GRAVITON_OUTFILE}" 2>&1 & + + pid=$! + if [[ -z "${pid}" ]]; then + echo "Graviton Server start error!" + return 1; + else + echo "Graviton Server start success!" + fi + + sleep 2 + check_process_status +} + +function stop() { + local pid + + pid=$(found_graviton_server_pid) + + if [[ -z "${pid}" ]]; then + echo "Graviton Server is not running" + else + wait_for_graviton_server_to_die + echo "Graviton Server stop" + fi +} + +HOSTNAME=$(hostname) +GRAVITON_OUTFILE="${GRAVITON_LOG_DIR}/graviton-${HOSTNAME}.out" +GRAVITON_SERVER_NAME=com.datastrato.graviton.server.GravitonServer + +JAVA_OPTS+=" -Dfile.encoding=UTF-8" +JAVA_OPTS+=" -Dlog4j2.configurationFile=file://${GRAVITON_CONF_DIR}/log4j2.properties" +JAVA_OPTS+=" -Dgraviton.log.path=${GRAVITON_LOG_DIR} ${GRAVITON_MEM}" + +addJarInDir "${GRAVITON_HOME}/lib" + +case "${1}" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + check_process_status + ;; + *) + echo ${USAGE} +esac \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 091d35f9a4..e4ad0d23da 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,6 +6,8 @@ import com.diffplug.gradle.spotless.SpotlessExtension import com.diffplug.gradle.spotless.SpotlessPlugin import com.github.vlsi.gradle.dsl.configureEach import java.util.Locale +import org.gradle.internal.hash.ChecksumService +import org.gradle.kotlin.dsl.support.serviceOf plugins { `maven-publish` @@ -29,7 +31,7 @@ java { } } -allprojects { +subprojects { apply(plugin = "jacoco") repositories { @@ -42,7 +44,7 @@ allprojects { finalizedBy(tasks.getByName("jacocoTestReport")) } - tasks.withType { + tasks.withType { reports { csv.required.set(true) xml.required.set(true) @@ -50,6 +52,8 @@ allprojects { } } + val allDeps by tasks.registering(DependencyReportTask::class) + group = "com.datastrato.graviton" version = "${version}" @@ -133,3 +137,118 @@ jacoco { toolVersion = "0.8.10" reportsDirectory.set(layout.buildDirectory.dir("JacocoReport")) } + +tasks { + val projectDir = layout.projectDirectory + val outputDir = projectDir.dir("distribution") + + val compileDistribution by registering { + dependsOn("copyRuntimeClass", "copyCatalogRuntimeClass", "copySubmoduleClass") + + group = "graviton distribution" + outputs.dir(projectDir.dir("distribution/package")) + doLast { + copy { + from(projectDir.dir("conf")) { into("package/conf") } + from(projectDir.dir("bin")) { into("package/bin") } + into(outputDir) + rename { fileName -> + // a simple way is to remove the "-$version" from the jar filename + // but you can customize the filename replacement rule as you wish. + fileName.replace(".template", "") + } + fileMode = 0b111101101 + } + } + } + + val assembleDistribution by registering(Tar::class) { + group = "graviton distribution" + finalizedBy("checksumDistribution") + from(compileDistribution.map { it.outputs.files.single() }) + archiveBaseName.set("datastrato") + archiveAppendix.set(rootProject.name.lowercase()) + archiveVersion.set("${version}") + archiveClassifier.set("bin") + destinationDirectory.set(outputDir) + } + + register("checksumDistribution") { + group = "graviton distribution" + dependsOn(assembleDistribution) + val archiveFile = assembleDistribution.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().sha256(archiveFile.get().asFile).toString() + ) + } + } + + val cleanDistribution by registering(Delete::class) { + group = "graviton distribution" + delete(outputDir) + delete("/tmp/graviton") + delete("server/src/main/resources/project.properties") + } + + val copyRuntimeClass by registering(Copy::class) { + subprojects.forEach() { + if (it.name != "catalog-hive" && it.name != "client-java") { + // println("copyRuntimeClass: ${it.name}") + from(it.configurations.runtimeClasspath) + into("distribution/package/lib") + } + } + } + + val copyCatalogRuntimeClass by registering(Copy::class) { + subprojects.forEach() { + if (it.name == "catalog-hive") { + // println("copyCatalogRuntimeClass: ${it.name}") + from(it.configurations.runtimeClasspath) + into("distribution/package/catalogs/catalog-hive/lib") + } + } + } + + val copySubmoduleClass by registering(Copy::class) { + dependsOn("copyRuntimeClass", "copyCatalogRuntimeClass") + subprojects.forEach() { + // println("copySubmoduleClass: ${it.name}") + if (it.name != "client-java") { + from("${it.name}/build/libs") + into("distribution/package/lib") + include("*.jar") + setDuplicatesStrategy(DuplicatesStrategy.INCLUDE) + } + } + } + + // Print all dependencies of all subprojects, `./gradlew allDeps` + task("allDeps") { + doLast { + subprojects.forEach { project -> + println("Dependencies for project: ${project.name}") + project.configurations.forEach { configuration -> + configuration.allDependencies.forEach { dependency -> + println("- ${dependency.group}:${dependency.name}:${dependency.version}") + } + } + println() + } + } + } + +// assemble { +// finalizedBy(assembleDistribution) +// } + + clean { + dependsOn(cleanDistribution) + } +} \ No newline at end of file diff --git a/catalog-hive/build.gradle.kts b/catalog-hive/build.gradle.kts index aa4181d13a..ad6a716356 100644 --- a/catalog-hive/build.gradle.kts +++ b/catalog-hive/build.gradle.kts @@ -77,16 +77,3 @@ dependencies { testImplementation(libs.junit.jupiter.api) testRuntimeOnly(libs.junit.jupiter.engine) } - -tasks.test { - useJUnitPlatform() -} - -task("copyDependencies", type = Copy::class) { - from(configurations.runtimeClasspath) - into("build/libs") -} - -tasks.named("build") { - finalizedBy("copyDependencies") -} diff --git a/conf/graviton-env.sh.template b/conf/graviton-env.sh.template new file mode 100644 index 0000000000..e6866969b4 --- /dev/null +++ b/conf/graviton-env.sh.template @@ -0,0 +1,13 @@ +# +# Copyright 2023 Datastrato. +# This software is licensed under the Apache License version 2. +# + +# Debug Graviton server +# export GRAVITON_DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 -Dlog4j2.debug=true" + +# export JAVA_HOME +# export GRAVITON_HOME +# export GRAVITON_CONF_DIR +# export GRAVITON_LOG_DIR # Where log files are stored. PWD by default. +# export GRAVITON_MEM # Graviton jvm mem options Default -Xms1024m -Xmx1024m -XX:MaxMetaspaceSize=512m diff --git a/conf/graviton.conf.template b/conf/graviton.conf.template new file mode 100644 index 0000000000..9d99693a3d --- /dev/null +++ b/conf/graviton.conf.template @@ -0,0 +1,37 @@ +# +# Copyright 2023 Datastrato. +# This software is licensed under the Apache License version 2. +# + +# THE CONFIGURATION FOR GRAVITON SERVER +graviton.server.shutdown.timeout = 3000 + +# THE CONFIGURATION FOR GRAVITON WEB SERVER +# The host name of the built-in web server +graviton.server.webserver.host = 127.0.0.1 +# The http port number of the built-in web server +graviton.server.webserver.httpPort = 8090 +# The core thread size of the built-in web server +graviton.server.webserver.coreThreads = 24 +# The max thread size of the built-in web server +graviton.server.webserver.maxThreads = 200 +# The stop idle timeout of the built-in web server +graviton.server.webserver.stopIdleTimeout = 30000 +# The executor thread pool work queue size of the built-in web server +graviton.server.webserver.threadPoolWorkQueueSize = 100 +# The request header size of the built-in web server +graviton.server.webserver.requestHeaderSize = 131072 +# The response header size of the built-in web server +graviton.server.webserver.responseHeaderSize = 131072 + +# THE CONFIGURATION FOR GRAVITON ENTITY STORE +# The entity store to use +graviton.entity.store = kv +# The RocksDB entity store +graviton.entity.store.kv = RocksDBKvBackend +# The RocksDB backend path for entity store +graviton.entity.store.kv.rocskdb.path = /tmp/graviton + +# THE CONFIGURATION FOR GRAVITON CATALOG +# The interval in milliseconds to evict the catalog cache +graviton.catalog.cache.evictionIntervalMs = 3600000 diff --git a/conf/log4j2.properties.template b/conf/log4j2.properties.template new file mode 100644 index 0000000000..3321548184 --- /dev/null +++ b/conf/log4j2.properties.template @@ -0,0 +1,37 @@ +# +# Copyright 2023 Datastrato. +# This software is licensed under the Apache License version 2. +# + +status = warn + +# Log files location +property.basePath = ${sys:graviton.log.path} + +# RollingFileAppender name, pattern, path and rollover policy +appender.rolling.type = RollingFile +appender.rolling.name = fileLogger +appender.rolling.fileName = ${basePath}/graviton-server.log +appender.rolling.filePattern = ${basePath}/graviton-server_%d{yyyyMMdd}.log.gz +appender.rolling.layout.type = PatternLayout +appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %level [%t] [%l] - %msg%n +appender.rolling.policies.type = Policies + +# RollingFileAppender rotation policy +appender.rolling.policies.size.type = SizeBasedTriggeringPolicy +appender.rolling.policies.size.size = 10MB +appender.rolling.policies.time.type = TimeBasedTriggeringPolicy +appender.rolling.policies.time.interval = 1 +appender.rolling.policies.time.modulate = true +appender.rolling.strategy.type = DefaultRolloverStrategy +appender.rolling.strategy.delete.type = Delete +appender.rolling.strategy.delete.basePath = ${basePath} +appender.rolling.strategy.delete.maxDepth = 10 +appender.rolling.strategy.delete.ifLastModified.type = IfLastModified + +# Delete all files older than 30 days +appender.rolling.strategy.delete.ifLastModified.age = 30d + +# Configure root logger +rootLogger.level = debug +rootLogger.appenderRef.rolling.ref = fileLogger diff --git a/server/build.gradle.kts b/server/build.gradle.kts index 5ee1dcec11..f4e8a0e0af 100644 --- a/server/build.gradle.kts +++ b/server/build.gradle.kts @@ -2,6 +2,10 @@ * Copyright 2023 Datastrato. * This software is licensed under the Apache License version 2. */ + +import java.text.SimpleDateFormat +import java.util.Date + plugins { `maven-publish` id("java") @@ -43,3 +47,28 @@ dependencies { } testImplementation(libs.mockito.core) } + +tasks.register("writeProjectPropertiesFile") { + val propertiesFile = file("src/main/resources/project.properties") + val dateFormat = SimpleDateFormat("dd/MM/yyyy HH:mm:ss") + + doLast { + val compileDate = dateFormat.format(Date()) + val projectVersion = project.version.toString() + + propertiesFile.parentFile.mkdirs() + propertiesFile.createNewFile() + propertiesFile.writer().use { writer -> + writer.write("#\n" + + "# Copyright 2023 Datastrato.\n" + + "# This software is licensed under the Apache License version 2.\n" + + "#\n") + writer.write("compileDate=$compileDate\n") + writer.write("version=$projectVersion") + } + } +} + +tasks.named("build") { + dependsOn("writeProjectPropertiesFile") +} diff --git a/server/src/main/java/com/datastrato/graviton/server/GravitonServer.java b/server/src/main/java/com/datastrato/graviton/server/GravitonServer.java index dc32ae70c1..6f838824ca 100644 --- a/server/src/main/java/com/datastrato/graviton/server/GravitonServer.java +++ b/server/src/main/java/com/datastrato/graviton/server/GravitonServer.java @@ -88,15 +88,34 @@ public void stop() { public static void main(String[] args) throws Exception { LOG.info("Starting Graviton Server"); - GravitonServer server = new GravitonServer(); server.initialize(); try { + // Instantiates GravitonServer server.start(); - server.join(); - } finally { - server.stop(); + } catch (Exception e) { + LOG.error("Error while running jettyServer", e); + System.exit(-1); } + LOG.info("Done, Graviton server started."); + + Runtime.getRuntime() + .addShutdownHook( + new Thread( + () -> { + LOG.info("Shutting down Graviton Server ... "); + try { + server.stop(); + Thread.sleep(server.serverConfig.get(ServerConfig.SERVER_SHUTDOWN_TIMEOUT)); + } catch (InterruptedException e) { + LOG.error("Interrupted exception:", e); + } catch (Exception e) { + LOG.error("Error while stopping servlet container", e); + } + LOG.info("Graviton Server has shut down."); + })); + + server.join(); } } diff --git a/server/src/main/java/com/datastrato/graviton/server/ServerConfig.java b/server/src/main/java/com/datastrato/graviton/server/ServerConfig.java index 991fef6abd..5bfb606c35 100644 --- a/server/src/main/java/com/datastrato/graviton/server/ServerConfig.java +++ b/server/src/main/java/com/datastrato/graviton/server/ServerConfig.java @@ -59,6 +59,20 @@ public class ServerConfig extends Config { .intConf() .createWithDefault(128 * 1024); + public static final ConfigEntry WEBSERVER_THREAD_POOL_WORK_QUEUE_SIZE = + new ConfigBuilder("graviton.server.webserver.threadPoolWorkQueueSize") + .doc("The executor thread pool work queue size of the built-in web server") + .version("0.1.0") + .intConf() + .createWithDefault(100); + + public static final ConfigEntry SERVER_SHUTDOWN_TIMEOUT = + new ConfigBuilder("graviton.server.shutdown.timeout") + .doc("The stop idle timeout(millis) of the Graviton Server") + .version("0.1.0") + .intConf() + .createWithDefault(3 * 1000); + public ServerConfig(boolean loadDefaults) { super(loadDefaults); } diff --git a/server/src/main/java/com/datastrato/graviton/server/web/JettyServer.java b/server/src/main/java/com/datastrato/graviton/server/web/JettyServer.java index cf6b065595..a40d3b0e50 100644 --- a/server/src/main/java/com/datastrato/graviton/server/web/JettyServer.java +++ b/server/src/main/java/com/datastrato/graviton/server/web/JettyServer.java @@ -7,6 +7,7 @@ import com.datastrato.graviton.Config; import com.datastrato.graviton.server.GravitonServerException; import com.datastrato.graviton.server.ServerConfig; +import com.datastrato.graviton.server.web.rest.ProjectVersion; import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.net.BindException; import java.util.EnumSet; @@ -53,12 +54,15 @@ public JettyServer() {} public synchronized void initialize(Config config) { int coreThreads = config.get(ServerConfig.WEBSERVER_CORE_THREADS); int maxThreads = config.get(ServerConfig.WEBSERVER_MAX_THREADS); - ExecutorThreadPool threadPool = createThreadPool(coreThreads, maxThreads); + long idleTimeout = config.get(ServerConfig.WEBSERVER_STOP_IDLE_TIMEOUT); + int threadPoolWorkQueueSize = config.get(ServerConfig.WEBSERVER_THREAD_POOL_WORK_QUEUE_SIZE); + ExecutorThreadPool threadPool = + createThreadPool(coreThreads, maxThreads, threadPoolWorkQueueSize); // Create and config Jetty Server server = new Server(threadPool); server.setStopAtShutdown(true); - server.setStopTimeout(config.get(ServerConfig.WEBSERVER_STOP_IDLE_TIMEOUT)); + server.setStopTimeout(idleTimeout); // Set error handler for Jetty Server ErrorHandler errorHandler = new ErrorHandler(); @@ -146,6 +150,7 @@ private void initializeServletContextHandler(Server server) { this.servletContextHandler = new ServletContextHandler(); servletContextHandler.setContextPath("/"); servletContextHandler.addServlet(DefaultServlet.class, "/"); + servletContextHandler.addServlet(ProjectVersion.class, "/version"); HandlerCollection handlers = new HandlerCollection(); handlers.addHandler(servletContextHandler); @@ -178,14 +183,15 @@ private ServerConnector creatorServerConnector( return new ServerConnector(server, null, serverExecutor, null, -1, -1, connectionFactories); } - private ExecutorThreadPool createThreadPool(int coreThreads, int maxThreads) { + private ExecutorThreadPool createThreadPool( + int coreThreads, int maxThreads, int threadPoolWorkQueueSize) { return new ExecutorThreadPool( new ThreadPoolExecutor( coreThreads, maxThreads, 60, TimeUnit.SECONDS, - new LinkedBlockingQueue<>(), + new LinkedBlockingQueue<>(threadPoolWorkQueueSize), new ThreadFactoryBuilder() .setDaemon(true) .setNameFormat("jetty-webserver-%d") diff --git a/server/src/main/java/com/datastrato/graviton/server/web/rest/ProjectVersion.java b/server/src/main/java/com/datastrato/graviton/server/web/rest/ProjectVersion.java new file mode 100644 index 0000000000..8e32ec01bc --- /dev/null +++ b/server/src/main/java/com/datastrato/graviton/server/web/rest/ProjectVersion.java @@ -0,0 +1,25 @@ +/* + * Copyright 2023 Datastrato. + * This software is licensed under the Apache License version 2. + */ +package com.datastrato.graviton.server.web.rest; + +import java.io.IOException; +import java.util.Properties; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ProjectVersion extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + Properties projectProperties = new Properties(); + projectProperties.load(ProjectVersion.class.getResourceAsStream("/project.properties")); + String version = projectProperties.getProperty("version"); + + resp.getWriter().write(version); + resp.setStatus(200); + } +}