305 lines
10 KiB
Groovy
305 lines
10 KiB
Groovy
plugins {
|
||
id 'java'
|
||
id 'application'
|
||
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||
}
|
||
|
||
allprojects {
|
||
tasks.withType(JavaCompile).configureEach {
|
||
options.encoding = 'UTF-8'
|
||
}
|
||
}
|
||
|
||
group = 'shine'
|
||
version = '1.1_codex'
|
||
|
||
tasks.jar {
|
||
enabled = false // это что бы не создавала обычный джар, а будет только толстый джар
|
||
}
|
||
|
||
tasks.processResources {
|
||
filteringCharset = 'UTF-8'
|
||
filesMatching('application.properties') {
|
||
expand(projectVersion: project.version.toString())
|
||
}
|
||
}
|
||
|
||
repositories {
|
||
mavenCentral()
|
||
}
|
||
|
||
dependencies {
|
||
implementation 'org.eclipse.jetty:jetty-server:11.0.20' // WS сервер
|
||
implementation 'org.eclipse.jetty:jetty-servlet:11.0.20'
|
||
implementation 'org.eclipse.jetty.websocket:websocket-jetty-server:11.0.20'
|
||
|
||
implementation 'org.bouncycastle:bcprov-jdk18on:1.78.1' // шифрование
|
||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1' // json
|
||
|
||
// implementation 'org.slf4j:slf4j-api:2.0.9'
|
||
implementation 'ch.qos.logback:logback-classic:1.5.6'
|
||
// Logback (реализация SLF4J + классический модуль)
|
||
runtimeOnly "ch.qos.logback:logback-classic:1.5.6"
|
||
|
||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||
|
||
implementation "org.slf4j:slf4j-api:2.0.16" // вызов логгера
|
||
|
||
|
||
// runtimeOnly "org.apache.logging.log4j:log4j-core:2.24.3" // Реализация: Log4j2 пишет в файл/консоль
|
||
// runtimeOnly "org.apache.logging.log4j:log4j-slf4j2-impl:2.24.3" // Реализация: Log4j2 пишет в файл/консоль
|
||
|
||
|
||
implementation project(':shine-server-config') // модуль настроек из application.properties
|
||
implementation project(":shine-server-log") // модуль логирования и уведомления админов
|
||
|
||
implementation project(':shine-server-crypto') // модуль сервера для работы с криптографией
|
||
implementation project(':shine-server-db') // модуль для работы с БД содержит и сущности из БД и саму работу с БД
|
||
implementation project(':shine-server-blockchain') // модуль для работы с блокчейном
|
||
|
||
implementation project(':shine-server-geo') // модуль для определения геолокации по IP
|
||
|
||
implementation project(':shine-server-net-protocol') // Модуль отвечающий за протокол (классы Net..Request/Response
|
||
implementation project(':shine-server-net-server') // Хэндлеры для обработки сетевых запросов
|
||
|
||
|
||
|
||
|
||
// -------------------- ТЕСТЫ (JUnit 5) --------------------
|
||
// Один BOM на всё семейство JUnit (Jupiter + Platform модули)
|
||
testImplementation platform("org.junit:junit-bom:5.10.2")
|
||
|
||
// JUnit Jupiter (Test, BeforeAll, Assertions)
|
||
testImplementation "org.junit.jupiter:junit-jupiter"
|
||
|
||
// JUnit Platform Suite (@Suite, @SelectClasses)
|
||
testImplementation "org.junit.platform:junit-platform-suite-api"
|
||
testRuntimeOnly "org.junit.platform:junit-platform-suite-engine"
|
||
|
||
// Нужно для компиляции RussianSummaryListener (org.junit.platform.launcher.*)
|
||
// и чтобы JUnit мог подхватить listener при запуске
|
||
testImplementation "org.junit.platform:junit-platform-launcher"
|
||
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
|
||
}
|
||
|
||
test {
|
||
useJUnitPlatform()
|
||
}
|
||
|
||
application {
|
||
// 👇 класс с методом main
|
||
mainClass = 'server.ws.WsServer'
|
||
}
|
||
|
||
|
||
java {
|
||
toolchain {
|
||
languageVersion = JavaLanguageVersion.of(17)
|
||
}
|
||
}
|
||
|
||
|
||
shadowJar {
|
||
// создаём 1 файл без постфиксов
|
||
archiveBaseName.set('shine-server')
|
||
archiveClassifier.set('')
|
||
archiveVersion.set('')
|
||
mergeServiceFiles()
|
||
|
||
manifest {
|
||
attributes(
|
||
'Main-Class': 'server.ws.WsServer'
|
||
)
|
||
}
|
||
}
|
||
|
||
|
||
tasks.named('test') {
|
||
enabled = false
|
||
}
|
||
|
||
tasks.register('cleanServerLogs') {
|
||
group = "!!test"
|
||
description = "Clear server logs/app.log and remove rolled log files"
|
||
|
||
doLast {
|
||
File logsDir = file('logs')
|
||
if (!logsDir.exists()) {
|
||
logsDir.mkdirs()
|
||
}
|
||
|
||
File appLog = new File(logsDir, 'app.log')
|
||
if (!appLog.exists()) {
|
||
appLog.createNewFile()
|
||
}
|
||
appLog.text = ''
|
||
|
||
fileTree(logsDir) {
|
||
include 'app.*.log'
|
||
}.files.each { File f ->
|
||
if (!f.delete()) {
|
||
throw new GradleException("Failed to delete log file: ${f.absolutePath}")
|
||
}
|
||
}
|
||
|
||
println "Server logs cleared: ${logsDir.absolutePath}"
|
||
}
|
||
}
|
||
|
||
tasks.register('integrationTest', JavaExec) {
|
||
group = "!!test"
|
||
description = "Clean data → kill 7070 → start WS → run all IT tests"
|
||
|
||
classpath = sourceSets.test.runtimeClasspath
|
||
mainClass = "test.it.IT_RunAllCleanStartWsMain"
|
||
|
||
// пробрасываем системные флаги (по желанию)
|
||
systemProperty "it.debug", System.getProperty("it.debug", "true")
|
||
systemProperty "it.login", System.getProperty("it.login", "anya24")
|
||
|
||
dependsOn testClasses
|
||
}
|
||
|
||
tasks.named('build') {
|
||
finalizedBy tasks.named('integrationTest')
|
||
}
|
||
|
||
tasks.register('deployServer', JavaExec) {
|
||
group = "!!deployment"
|
||
description = "Build → upload to server → clean remote data → restart service → run IT against server"
|
||
|
||
classpath = sourceSets.test.runtimeClasspath
|
||
mainClass = "test.it.IT_DeployRestartAndRunRemoteMain"
|
||
|
||
// можно переопределить при запуске:
|
||
// ./gradlew deployServer -Dit.remoteHost=... -Dit.wsUri=...
|
||
dependsOn shadowJar
|
||
systemProperty "it.remoteHost", System.getProperty("it.remoteHost", "194.87.0.247")
|
||
systemProperty "it.remoteUser", System.getProperty("it.remoteUser", "user")
|
||
systemProperty "it.remoteDir", System.getProperty("it.remoteDir", "/home/user/docker/shine-server")
|
||
systemProperty "it.remoteDataDir", System.getProperty("it.remoteDataDir", "/home/user/docker/shine-server/data")
|
||
systemProperty "it.service", System.getProperty("it.service", "shine-server")
|
||
systemProperty "it.localJar", System.getProperty("it.localJar", "build/libs/shine-server.jar")
|
||
|
||
systemProperty "it.wsUri", System.getProperty("it.wsUri", "wss://shineup.me/ws")
|
||
systemProperty "it.login", System.getProperty("it.login", "anya24")
|
||
|
||
dependsOn testClasses
|
||
}
|
||
|
||
tasks.register('deployServerNoCleanNoTests', JavaExec) {
|
||
group = "!!deployment"
|
||
description = "Build → upload to server → restart service (no data clean, no IT tests)"
|
||
|
||
classpath = sourceSets.test.runtimeClasspath
|
||
mainClass = "test.it.IT_DeployRestartNoCleanNoTestsMain"
|
||
|
||
// можно переопределить при запуске:
|
||
// ./gradlew deployServerNoCleanNoTests -Dit.remoteHost=...
|
||
dependsOn shadowJar
|
||
systemProperty "it.remoteHost", System.getProperty("it.remoteHost", "194.87.0.247")
|
||
systemProperty "it.remoteUser", System.getProperty("it.remoteUser", "user")
|
||
systemProperty "it.remoteDir", System.getProperty("it.remoteDir", "/home/user/docker/shine-server")
|
||
systemProperty "it.service", System.getProperty("it.service", "shine-server")
|
||
systemProperty "it.localJar", System.getProperty("it.localJar", "build/libs/shine-server.jar")
|
||
|
||
dependsOn testClasses
|
||
}
|
||
|
||
tasks.register('deployWEB', Exec) {
|
||
group = "!!deployment"
|
||
description = "Deploy WEB via deploy_shine-PWA.sh"
|
||
|
||
workingDir = rootDir
|
||
commandLine 'bash', file('deploy_shine-PWA.sh').absolutePath
|
||
}
|
||
|
||
tasks.register('deployAll') {
|
||
group = "!!deployment"
|
||
description = "Deploy server and WEB"
|
||
|
||
dependsOn tasks.named('deployServer')
|
||
dependsOn tasks.named('deployWEB')
|
||
}
|
||
|
||
tasks.register('startLocal', Exec) {
|
||
group = "!!run"
|
||
description = "Builds server, starts local WS server and local HTTP UI for end-to-end local testing"
|
||
|
||
dependsOn shadowJar
|
||
dependsOn cleanServerLogs
|
||
|
||
workingDir = rootDir
|
||
def wsPort = System.getProperty("localWsPort", "7070")
|
||
def webPort = System.getProperty("localWebPort", "8088")
|
||
|
||
commandLine 'bash', '-lc', """
|
||
set -euo pipefail
|
||
JAR_PATH="${file('build/libs/shine-server.jar').absolutePath}"
|
||
UI_DIR="${file('shine-UI').absolutePath}"
|
||
WS_PORT="${wsPort}"
|
||
WEB_PORT="${webPort}"
|
||
|
||
is_port_busy() {
|
||
local port="\$1"
|
||
if command -v ss >/dev/null 2>&1; then
|
||
ss -ltnH "sport = :\$port" | grep -q .
|
||
elif command -v lsof >/dev/null 2>&1; then
|
||
lsof -iTCP:"\$port" -sTCP:LISTEN >/dev/null 2>&1
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
pick_free_port() {
|
||
local p="\$1"
|
||
while is_port_busy "\$p"; do
|
||
p=\$((p + 1))
|
||
done
|
||
echo "\$p"
|
||
}
|
||
|
||
WS_PORT="\$(pick_free_port "\$WS_PORT")"
|
||
WEB_PORT="\$(pick_free_port "\$WEB_PORT")"
|
||
|
||
echo "Starting SHiNE local stack..."
|
||
echo "WS server port: \$WS_PORT"
|
||
echo "UI HTTP port: \$WEB_PORT"
|
||
echo "Client URL: http://localhost:\$WEB_PORT/?localWsPort=\$WS_PORT"
|
||
|
||
java -Dserver.port="\$WS_PORT" -jar "\$JAR_PATH" &
|
||
SERVER_PID=\$!
|
||
trap 'kill \$SERVER_PID 2>/dev/null || true' EXIT INT TERM
|
||
|
||
CLIENT_URL="http://localhost:\$WEB_PORT/?localWsPort=\$WS_PORT"
|
||
if command -v xdg-open >/dev/null 2>&1; then
|
||
(xdg-open "\$CLIENT_URL" >/dev/null 2>&1 || true) &
|
||
elif command -v open >/dev/null 2>&1; then
|
||
(open "\$CLIENT_URL" >/dev/null 2>&1 || true) &
|
||
elif command -v cmd.exe >/dev/null 2>&1; then
|
||
(cmd.exe /c start "" "\$CLIENT_URL" >/dev/null 2>&1 || true) &
|
||
else
|
||
echo "Browser auto-open is not available on this host. Open manually: \$CLIENT_URL"
|
||
fi
|
||
|
||
if command -v python3 >/dev/null 2>&1; then
|
||
(cd "\$UI_DIR" && python3 -m http.server "\$WEB_PORT")
|
||
else
|
||
(cd "\$UI_DIR" && python -m http.server "\$WEB_PORT")
|
||
fi
|
||
"""
|
||
}
|
||
|
||
tasks.register('startLocalWithBuild') {
|
||
group = "!!run"
|
||
description = "Build server (build) and then start local stack (startLocal)"
|
||
|
||
dependsOn tasks.named('build')
|
||
dependsOn tasks.named('startLocal')
|
||
}
|
||
|
||
tasks.named('startLocal').configure {
|
||
mustRunAfter tasks.named('build')
|
||
}
|