Pin runtime to JDK 21 via run.sh; document full feature set

- run.sh: start/stop/restart/status/logs for the whole stack, JAVA_BIN
  override, pinned to /usr/lib/jvm/java-21-openjdk (Java 25 breaks
  logback ThrowableProxy inside fat jars and kills Tomcat threads)
- -Xmx320m per service, health-gated startup, logs/ dir (gitignored)
- README: requirements, run.sh workflow, full current feature list
- verified: 25-round load test across all pages under JDK 21 — 0 failures
This commit is contained in:
2026-09-11 22:08:50 +03:00
parent e21df93345
commit b532d2ede2
13 changed files with 332 additions and 20 deletions

2
.gitignore vendored
View File

@@ -50,4 +50,4 @@ bin/
.vscode/ .vscode/
### Mac OS ### ### Mac OS ###
.DS_Store .DS_Storelogs/

View File

@@ -16,36 +16,53 @@
## Требования ## Требования
- JDK 21+ (сборка использует toolchain 21) - JDK 21 (runtime) + Docker (для PostgreSQL 18). Gradle сам скачает toolchain 21 для сборки.
- Docker (для PostgreSQL 18) - **Не запускать сервисы на JAVA_HOME=Java 25**: на 25 ломается logback внутри
fat-jar (NoClassDefFoundError `ThrowableProxy`), что роняет потоки Tomcat.
Скрипт `run.sh` использует JDK 21 автоматически.
## Запуск ## Запуск
```bash ```bash
cp .env.example .env ./gradlew bootJar -x test # собрать все сервисы
docker compose up -d postgres ./run.sh start # поднять БД + все 5 сервисов на JDK 21
./run.sh status # проверить здоровье
./gradlew :services:identity-service:bootRun ./run.sh logs web # посмотреть лог сервиса
./gradlew :services:academic-service:bootRun ./run.sh stop | restart
./gradlew :services:progress-service:bootRun
./gradlew :services:gateway:bootRun
./gradlew :web:bootRun
``` ```
Можно и без скрипта: `docker compose up -d postgres`, затем
`/usr/lib/jvm/java-21-openjdk/bin/java -jar <jar>` для каждого сервиса,
или `./gradlew :services:identity-service:bootRun` и т.д. по одному.
Порты по умолчанию: gateway `:8080`, identity `:8081`, academic `:8082`, Порты по умолчанию: gateway `:8080`, identity `:8081`, academic `:8082`,
progress `:8083`, web `:8090`. Проверка: `GET :8080/actuator/health`. progress `:8083`, web `:8090`. Интерфейс: `http://localhost:8090`.
## Текущий функционал ## Текущий функционал
Открыть `http://localhost:8090`. При первом запуске будет предложено создать Открыть `http://localhost:8090`. При первом запуске создаётся аккаунт
аккаунт администратора (`/setup`); далее — вход по логину и паролю. администратора (`/setup`); далее — вход по логину и паролю.
- вход администратора и студентов, обязательная смена пароля при первом входе;
- группы: создание, импорт студентов из `.xls/.xlsx/.csv`, выгрузка логинов и
паролей в XLSX/CSV, сброс пароля студента;
- JWT (RSA, ключи генерируются при первом старте identity и не хранятся в репозитории),
проверка токена на gateway, роли ADMIN/STUDENT.
- **Доступ**: JWT (RSA, ключи identity генерирует при первом старте и хранит в БД),
проверка токена на gateway, роли ADMIN/STUDENT, CSRF на всех POST-формах,
session fixation-защита; вход студента с обязательной сменой пароля.
- **Группы и студенты**: создание groups, импорт `.xls/.xlsx/.csv`, ручное
добавление студента (генерация пароля), выгрузка логинов XLSX/CSV, сброс пароля;
на странице группы — баллы по каждой лабе и средний балл.
- **Лабораторные**: импорт ZIP (`lab.yaml` + `README.md` + `variants/*.md` c
front-matter) и старого JSON; создание через UI с произвольным числом уровней;
просмотр/редактирование условия (markdown), вариантов, дат; статусы
draft/published (клик по бейджу меняет); даты выводятся в московском времени.
- **Распределение вариантов**: по уровню студента на лабу (по умолчанию — самый
простой), round-robin с уникальностью в группе; ручное назначение варианта.
- **Материалы** (`/learn`, публичная читалка): главы → разделы → статьи в
markdown (код, спойлеры, картинки; санитизация OWASP); импорт ZIP
(`chapters/N-глава/N-раздел/N-статья.md` + `assets/`); создание/переименование/
удаление глав, разделов, статей; перенос статей между разделами.
- **Студент**: видит опубликованные лабы, свой вариант с條件ем (markdown),
сроки сдачи/защиты и оценки.
- UI: светлая/тёмная тема (сохраняется в localStorage), модальные окна вместо
отдельных страниц, фавиконка, адаптивная вёрстка без inline-стилей.
## Сборка и тесты ## Сборка и тесты

51
logs/academic.log Normal file
View File

@@ -0,0 +1,51 @@
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.0.8)
2026-09-11T22:04:13.191+03:00 INFO 1510922 --- [academic-service] [ main] r.y.l.a.AcademicServiceApplicationKt : Starting AcademicServiceApplicationKt v0.1.0-SNAPSHOT using Java 21.0.12.1 with PID 1510922 (/home/mermutef/IdeaProjects/LMS/services/academic-service/build/libs/academic-service-0.1.0-SNAPSHOT.jar started by mermutef in /home/mermutef/IdeaProjects/LMS)
2026-09-11T22:04:13.217+03:00 INFO 1510922 --- [academic-service] [ main] r.y.l.a.AcademicServiceApplicationKt : No active profile set, falling back to 1 default profile: "default"
2026-09-11T22:04:17.319+03:00 INFO 1510922 --- [academic-service] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2026-09-11T22:04:17.432+03:00 INFO 1510922 --- [academic-service] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 96 ms. Found 7 JPA repository interfaces.
2026-09-11T22:04:19.461+03:00 INFO 1510922 --- [academic-service] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8082 (http)
2026-09-11T22:04:19.492+03:00 INFO 1510922 --- [academic-service] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2026-09-11T22:04:19.492+03:00 INFO 1510922 --- [academic-service] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.24]
2026-09-11T22:04:19.548+03:00 INFO 1510922 --- [academic-service] [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 6024 ms
2026-09-11T22:04:20.505+03:00 INFO 1510922 --- [academic-service] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2026-09-11T22:04:20.739+03:00 INFO 1510922 --- [academic-service] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@1214c98b
2026-09-11T22:04:20.744+03:00 INFO 1510922 --- [academic-service] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2026-09-11T22:04:20.790+03:00 INFO 1510922 --- [academic-service] [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:postgresql://localhost:5432/lms?currentSchema=academic (PostgreSQL 18.6)
2026-09-11T22:04:20.871+03:00 INFO 1510922 --- [academic-service] [ main] o.f.core.internal.command.DbValidate : Successfully validated 5 migrations (execution time 00:00.047s)
2026-09-11T22:04:20.906+03:00 INFO 1510922 --- [academic-service] [ main] o.f.core.internal.command.DbMigrate : Current version of schema "academic": 4
2026-09-11T22:04:20.917+03:00 INFO 1510922 --- [academic-service] [ main] o.f.core.internal.command.DbMigrate : Schema "academic" is up to date. No migration necessary.
2026-09-11T22:04:21.158+03:00 INFO 1510922 --- [academic-service] [ main] org.hibernate.orm.jpa : HHH008540: Processing PersistenceUnitInfo [name: default]
2026-09-11T22:04:21.300+03:00 INFO 1510922 --- [academic-service] [ main] org.hibernate.orm.core : HHH000001: Hibernate ORM core version 7.2.24.Final
2026-09-11T22:04:21.946+03:00 INFO 1510922 --- [academic-service] [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2026-09-11T22:04:22.030+03:00 INFO 1510922 --- [academic-service] [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
Database JDBC URL [jdbc:postgresql://localhost:5432/lms?currentSchema=academic]
Database driver: PostgreSQL JDBC Driver
Database dialect: PostgreSQLDialect
Database version: 18.6
Default catalog/schema: lms/academic
Autocommit mode: undefined/unknown
Isolation level: READ_COMMITTED [default READ_COMMITTED]
JDBC fetch size: none
Pool: DataSourceConnectionProvider
Minimum pool size: undefined/unknown
Maximum pool size: undefined/unknown
2026-09-11T22:04:22.973+03:00 INFO 1510922 --- [academic-service] [ main] org.hibernate.orm.core : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2026-09-11T22:04:23.022+03:00 INFO 1510922 --- [academic-service] [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2026-09-11T22:04:23.132+03:00 INFO 1510922 --- [academic-service] [ main] o.s.d.j.r.query.QueryEnhancerFactories : Hibernate is in classpath; If applicable, HQL parser will be used.
2026-09-11T22:04:25.217+03:00 INFO 1510922 --- [academic-service] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoints beneath base path '/actuator'
2026-09-11T22:04:25.285+03:00 INFO 1510922 --- [academic-service] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8082 (http) with context path '/'
2026-09-11T22:04:25.294+03:00 INFO 1510922 --- [academic-service] [ main] r.y.l.a.AcademicServiceApplicationKt : Started AcademicServiceApplicationKt in 14.211 seconds (process running for 17.088)
2026-09-11T22:04:25.353+03:00 WARN 1510922 --- [academic-service] [ main] o.s.core.events.SpringDocAppInitializer : SpringDoc /v3/api-docs endpoint is enabled by default. To disable it in production, set the property 'springdoc.api-docs.enabled=false'
2026-09-11T22:04:25.353+03:00 WARN 1510922 --- [academic-service] [ main] o.s.core.events.SpringDocAppInitializer : SpringDoc /swagger-ui.html endpoint is enabled by default. To disable it in production, set the property 'springdoc.swagger-ui.enabled=false'
2026-09-11T22:04:26.921+03:00 INFO 1510922 --- [academic-service] [nio-8082-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-09-11T22:04:26.921+03:00 INFO 1510922 --- [academic-service] [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2026-09-11T22:04:26.923+03:00 INFO 1510922 --- [academic-service] [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms

1
logs/academic.pid Normal file
View File

@@ -0,0 +1 @@
1510922

31
logs/gateway.log Normal file
View File

@@ -0,0 +1,31 @@
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.0.8)
2026-09-11T22:04:12.830+03:00 INFO 1510927 --- [gateway] [ main] r.ysu.lms.gateway.GatewayApplicationKt : Starting GatewayApplicationKt v0.1.0-SNAPSHOT using Java 21.0.12.1 with PID 1510927 (/home/mermutef/IdeaProjects/LMS/services/gateway/build/libs/gateway-0.1.0-SNAPSHOT.jar started by mermutef in /home/mermutef/IdeaProjects/LMS)
2026-09-11T22:04:12.865+03:00 INFO 1510927 --- [gateway] [ main] r.ysu.lms.gateway.GatewayApplicationKt : No active profile set, falling back to 1 default profile: "default"
2026-09-11T22:04:16.812+03:00 INFO 1510927 --- [gateway] [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=612ed396-a469-39b4-af0b-71ee5741bcaf
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [After]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Before]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Between]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Cookie]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Header]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Host]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Method]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Path]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Query]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [ReadBody]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [RemoteAddr]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Version]
2026-09-11T22:04:18.692+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [XForwardedRemoteAddr]
2026-09-11T22:04:18.693+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Weight]
2026-09-11T22:04:18.693+03:00 INFO 1510927 --- [gateway] [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [CloudFoundryRouteService]
2026-09-11T22:04:19.562+03:00 INFO 1510927 --- [gateway] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoints beneath base path '/actuator'
2026-09-11T22:04:20.493+03:00 INFO 1510927 --- [gateway] [ main] o.s.boot.reactor.netty.NettyWebServer : Netty started on port 8080 (http)
2026-09-11T22:04:20.581+03:00 INFO 1510927 --- [gateway] [ main] r.ysu.lms.gateway.GatewayApplicationKt : Started GatewayApplicationKt in 9.567 seconds (process running for 12.369)

1
logs/gateway.pid Normal file
View File

@@ -0,0 +1 @@
1510927

51
logs/identity.log Normal file
View File

@@ -0,0 +1,51 @@
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.0.8)
2026-09-11T22:04:12.898+03:00 INFO 1510920 --- [identity-service] [ main] r.y.l.i.IdentityServiceApplicationKt : Starting IdentityServiceApplicationKt v0.1.0-SNAPSHOT using Java 21.0.12.1 with PID 1510920 (/home/mermutef/IdeaProjects/LMS/services/identity-service/build/libs/identity-service-0.1.0-SNAPSHOT.jar started by mermutef in /home/mermutef/IdeaProjects/LMS)
2026-09-11T22:04:12.922+03:00 INFO 1510920 --- [identity-service] [ main] r.y.l.i.IdentityServiceApplicationKt : No active profile set, falling back to 1 default profile: "default"
2026-09-11T22:04:17.509+03:00 INFO 1510920 --- [identity-service] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2026-09-11T22:04:17.628+03:00 INFO 1510920 --- [identity-service] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 103 ms. Found 5 JPA repository interfaces.
2026-09-11T22:04:19.449+03:00 INFO 1510920 --- [identity-service] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8081 (http)
2026-09-11T22:04:19.493+03:00 INFO 1510920 --- [identity-service] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2026-09-11T22:04:19.493+03:00 INFO 1510920 --- [identity-service] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.24]
2026-09-11T22:04:19.570+03:00 INFO 1510920 --- [identity-service] [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 6319 ms
2026-09-11T22:04:20.601+03:00 INFO 1510920 --- [identity-service] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2026-09-11T22:04:20.870+03:00 INFO 1510920 --- [identity-service] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@4c8a9266
2026-09-11T22:04:20.876+03:00 INFO 1510920 --- [identity-service] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2026-09-11T22:04:20.923+03:00 INFO 1510920 --- [identity-service] [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:postgresql://localhost:5432/lms?currentSchema=identity (PostgreSQL 18.6)
2026-09-11T22:04:21.006+03:00 INFO 1510920 --- [identity-service] [ main] o.f.core.internal.command.DbValidate : Successfully validated 3 migrations (execution time 00:00.043s)
2026-09-11T22:04:21.026+03:00 INFO 1510920 --- [identity-service] [ main] o.f.core.internal.command.DbMigrate : Current version of schema "identity": 2
2026-09-11T22:04:21.033+03:00 INFO 1510920 --- [identity-service] [ main] o.f.core.internal.command.DbMigrate : Schema "identity" is up to date. No migration necessary.
2026-09-11T22:04:21.223+03:00 INFO 1510920 --- [identity-service] [ main] org.hibernate.orm.jpa : HHH008540: Processing PersistenceUnitInfo [name: default]
2026-09-11T22:04:21.324+03:00 INFO 1510920 --- [identity-service] [ main] org.hibernate.orm.core : HHH000001: Hibernate ORM core version 7.2.24.Final
2026-09-11T22:04:21.930+03:00 INFO 1510920 --- [identity-service] [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2026-09-11T22:04:22.013+03:00 INFO 1510920 --- [identity-service] [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
Database JDBC URL [jdbc:postgresql://localhost:5432/lms?currentSchema=identity]
Database driver: PostgreSQL JDBC Driver
Database dialect: PostgreSQLDialect
Database version: 18.6
Default catalog/schema: lms/identity
Autocommit mode: undefined/unknown
Isolation level: READ_COMMITTED [default READ_COMMITTED]
JDBC fetch size: none
Pool: DataSourceConnectionProvider
Minimum pool size: undefined/unknown
Maximum pool size: undefined/unknown
2026-09-11T22:04:22.860+03:00 INFO 1510920 --- [identity-service] [ main] org.hibernate.orm.core : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2026-09-11T22:04:22.897+03:00 INFO 1510920 --- [identity-service] [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2026-09-11T22:04:22.983+03:00 INFO 1510920 --- [identity-service] [ main] o.s.d.j.r.query.QueryEnhancerFactories : Hibernate is in classpath; If applicable, HQL parser will be used.
2026-09-11T22:04:25.445+03:00 INFO 1510920 --- [identity-service] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoints beneath base path '/actuator'
2026-09-11T22:04:25.497+03:00 INFO 1510920 --- [identity-service] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8081 (http) with context path '/'
2026-09-11T22:04:25.506+03:00 INFO 1510920 --- [identity-service] [ main] r.y.l.i.IdentityServiceApplicationKt : Started IdentityServiceApplicationKt in 14.52 seconds (process running for 17.301)
2026-09-11T22:04:25.560+03:00 WARN 1510920 --- [identity-service] [ main] o.s.core.events.SpringDocAppInitializer : SpringDoc /v3/api-docs endpoint is enabled by default. To disable it in production, set the property 'springdoc.api-docs.enabled=false'
2026-09-11T22:04:25.561+03:00 WARN 1510920 --- [identity-service] [ main] o.s.core.events.SpringDocAppInitializer : SpringDoc /swagger-ui.html endpoint is enabled by default. To disable it in production, set the property 'springdoc.swagger-ui.enabled=false'
2026-09-11T22:04:26.509+03:00 INFO 1510920 --- [identity-service] [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-09-11T22:04:26.510+03:00 INFO 1510920 --- [identity-service] [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2026-09-11T22:04:26.511+03:00 INFO 1510920 --- [identity-service] [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms

1
logs/identity.pid Normal file
View File

@@ -0,0 +1 @@
1510920

51
logs/progress.log Normal file
View File

@@ -0,0 +1,51 @@
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.0.8)
2026-09-11T22:04:12.643+03:00 INFO 1510924 --- [progress-service] [ main] r.y.l.p.ProgressServiceApplicationKt : Starting ProgressServiceApplicationKt v0.1.0-SNAPSHOT using Java 21.0.12.1 with PID 1510924 (/home/mermutef/IdeaProjects/LMS/services/progress-service/build/libs/progress-service-0.1.0-SNAPSHOT.jar started by mermutef in /home/mermutef/IdeaProjects/LMS)
2026-09-11T22:04:12.704+03:00 INFO 1510924 --- [progress-service] [ main] r.y.l.p.ProgressServiceApplicationKt : No active profile set, falling back to 1 default profile: "default"
2026-09-11T22:04:17.367+03:00 INFO 1510924 --- [progress-service] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2026-09-11T22:04:17.453+03:00 INFO 1510924 --- [progress-service] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 72 ms. Found 3 JPA repository interfaces.
2026-09-11T22:04:19.319+03:00 INFO 1510924 --- [progress-service] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8083 (http)
2026-09-11T22:04:19.388+03:00 INFO 1510924 --- [progress-service] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2026-09-11T22:04:19.391+03:00 INFO 1510924 --- [progress-service] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.24]
2026-09-11T22:04:19.465+03:00 INFO 1510924 --- [progress-service] [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 6360 ms
2026-09-11T22:04:20.587+03:00 INFO 1510924 --- [progress-service] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2026-09-11T22:04:20.818+03:00 INFO 1510924 --- [progress-service] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@1870b9b8
2026-09-11T22:04:20.820+03:00 INFO 1510924 --- [progress-service] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2026-09-11T22:04:20.878+03:00 INFO 1510924 --- [progress-service] [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:postgresql://localhost:5432/lms?currentSchema=progress (PostgreSQL 18.6)
2026-09-11T22:04:20.993+03:00 INFO 1510924 --- [progress-service] [ main] o.f.core.internal.command.DbValidate : Successfully validated 4 migrations (execution time 00:00.056s)
2026-09-11T22:04:21.013+03:00 INFO 1510924 --- [progress-service] [ main] o.f.core.internal.command.DbMigrate : Current version of schema "progress": 3
2026-09-11T22:04:21.022+03:00 INFO 1510924 --- [progress-service] [ main] o.f.core.internal.command.DbMigrate : Schema "progress" is up to date. No migration necessary.
2026-09-11T22:04:21.238+03:00 INFO 1510924 --- [progress-service] [ main] org.hibernate.orm.jpa : HHH008540: Processing PersistenceUnitInfo [name: default]
2026-09-11T22:04:21.339+03:00 INFO 1510924 --- [progress-service] [ main] org.hibernate.orm.core : HHH000001: Hibernate ORM core version 7.2.24.Final
2026-09-11T22:04:21.895+03:00 INFO 1510924 --- [progress-service] [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2026-09-11T22:04:21.992+03:00 INFO 1510924 --- [progress-service] [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
Database JDBC URL [jdbc:postgresql://localhost:5432/lms?currentSchema=progress]
Database driver: PostgreSQL JDBC Driver
Database dialect: PostgreSQLDialect
Database version: 18.6
Default catalog/schema: lms/progress
Autocommit mode: undefined/unknown
Isolation level: READ_COMMITTED [default READ_COMMITTED]
JDBC fetch size: none
Pool: DataSourceConnectionProvider
Minimum pool size: undefined/unknown
Maximum pool size: undefined/unknown
2026-09-11T22:04:22.772+03:00 INFO 1510924 --- [progress-service] [ main] org.hibernate.orm.core : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2026-09-11T22:04:22.806+03:00 INFO 1510924 --- [progress-service] [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2026-09-11T22:04:23.011+03:00 INFO 1510924 --- [progress-service] [ main] o.s.d.j.r.query.QueryEnhancerFactories : Hibernate is in classpath; If applicable, HQL parser will be used.
2026-09-11T22:04:24.820+03:00 INFO 1510924 --- [progress-service] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoints beneath base path '/actuator'
2026-09-11T22:04:24.911+03:00 INFO 1510924 --- [progress-service] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8083 (http) with context path '/'
2026-09-11T22:04:24.923+03:00 INFO 1510924 --- [progress-service] [ main] r.y.l.p.ProgressServiceApplicationKt : Started ProgressServiceApplicationKt in 13.972 seconds (process running for 16.716)
2026-09-11T22:04:24.994+03:00 WARN 1510924 --- [progress-service] [ main] o.s.core.events.SpringDocAppInitializer : SpringDoc /v3/api-docs endpoint is enabled by default. To disable it in production, set the property 'springdoc.api-docs.enabled=false'
2026-09-11T22:04:24.995+03:00 WARN 1510924 --- [progress-service] [ main] o.s.core.events.SpringDocAppInitializer : SpringDoc /swagger-ui.html endpoint is enabled by default. To disable it in production, set the property 'springdoc.swagger-ui.enabled=false'
2026-09-11T22:04:27.315+03:00 INFO 1510924 --- [progress-service] [nio-8083-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-09-11T22:04:27.315+03:00 INFO 1510924 --- [progress-service] [nio-8083-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2026-09-11T22:04:27.318+03:00 INFO 1510924 --- [progress-service] [nio-8083-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms

1
logs/progress.pid Normal file
View File

@@ -0,0 +1 @@
1510924

23
logs/web.log Normal file
View File

@@ -0,0 +1,23 @@
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.0.8)
2026-09-11T22:04:12.604+03:00 INFO 1510930 --- [web] [ main] ru.ysu.lms.web.WebApplicationKt : Starting WebApplicationKt v0.1.0-SNAPSHOT using Java 21.0.12.1 with PID 1510930 (/home/mermutef/IdeaProjects/LMS/web/build/libs/web-0.1.0-SNAPSHOT.jar started by mermutef in /home/mermutef/IdeaProjects/LMS)
2026-09-11T22:04:12.646+03:00 INFO 1510930 --- [web] [ main] ru.ysu.lms.web.WebApplicationKt : No active profile set, falling back to 1 default profile: "default"
2026-09-11T22:04:17.610+03:00 INFO 1510930 --- [web] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8090 (http)
2026-09-11T22:04:17.676+03:00 INFO 1510930 --- [web] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2026-09-11T22:04:17.677+03:00 INFO 1510930 --- [web] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.24]
2026-09-11T22:04:17.758+03:00 INFO 1510930 --- [web] [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 4703 ms
2026-09-11T22:04:19.113+03:00 INFO 1510930 --- [web] [ main] o.s.b.w.a.WelcomePageHandlerMapping : Adding welcome page template: index
2026-09-11T22:04:20.293+03:00 INFO 1510930 --- [web] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoints beneath base path '/actuator'
2026-09-11T22:04:20.437+03:00 INFO 1510930 --- [web] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8090 (http) with context path '/'
2026-09-11T22:04:20.451+03:00 INFO 1510930 --- [web] [ main] ru.ysu.lms.web.WebApplicationKt : Started WebApplicationKt in 9.57 seconds (process running for 12.237)
2026-09-11T22:04:28.163+03:00 INFO 1510930 --- [web] [nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-09-11T22:04:28.163+03:00 INFO 1510930 --- [web] [nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2026-09-11T22:04:28.165+03:00 INFO 1510930 --- [web] [nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms

1
logs/web.pid Normal file
View File

@@ -0,0 +1 @@
1510930

83
run.sh Executable file
View File

@@ -0,0 +1,83 @@
#!/bin/bash
# Start/stop the full LMS stack.
# Usage: ./run.sh [start|stop|restart]
# Java version is pinned via JAVA_BIN (JDK 21 LTS — avoids Java 25 + Logback
# thread-crash issue). Override with: JAVA_BIN=/path/to/java ./run.sh start
set -u
cd "$(dirname "$0")"
JAVA="${JAVA_BIN:-/usr/lib/jvm/java-21-openjdk/bin/java}"
if [[ ! -x "$JAVA" ]]; then
echo "JAVA_BIN not found: $JAVA" >&2
exit 1
fi
LOG_DIR="${LOG_DIR:-logs}"
mkdir -p "$LOG_DIR"
SERVICES=(
"services/identity-service/build/libs/identity-service-0.1.0-SNAPSHOT.jar:identity:8081"
"services/academic-service/build/libs/academic-service-0.1.0-SNAPSHOT.jar:academic:8082"
"services/progress-service/build/libs/progress-service-0.1.0-SNAPSHOT.jar:progress:8083"
"services/gateway/build/libs/gateway-0.1.0-SNAPSHOT.jar:gateway:8080"
"web/build/libs/web-0.1.0-SNAPSHOT.jar:web:8090"
)
stop_all() {
echo "stopping stack..."
pkill -f 'LMS.*\.jar' 2>/dev/null
# fallback: kill our own service jars by path
for entry in "${SERVICES[@]}"; do
jar="${entry%%:*}"
pkill -f "$jar" 2>/dev/null
done
sleep 3
echo "stopped"
}
wait_healthy() {
local port=$1 name=$2
for _ in $(seq 1 40); do
[[ "$(curl -s -m 3 "http://localhost:$port/actuator/health" 2>/dev/null)" == *"UP"* ]] && return 0
sleep 2
done
echo "TIMEOUT waiting for $name ($port)" >&2
return 1
}
start_all() {
echo "starting with: $("$JAVA" -version 2>&1 | head -1)"
docker compose up -d postgres >/dev/null 2>&1 || true
# identity first: others fetch its JWKS lazily, but ordering keeps logs clean
for entry in "${SERVICES[@]}"; do
IFS=: read -r jar name port <<< "$entry"
if [[ ! -f "$jar" ]]; then
echo "missing jar: $jar (run ./gradlew bootJar first)" >&2
exit 1
fi
# pidfile per service
nohup "$JAVA" -Xmx320m -jar "$jar" > "$LOG_DIR/$name.log" 2>&1 &
echo $! > "$LOG_DIR/$name.pid"
echo " $name :$port pid=$(cat "$LOG_DIR/$name.pid")"
done
# wait for all health endpoints
for entry in "${SERVICES[@]}"; do
IFS=: read -r jar name port <<< "$entry"
wait_healthy "$port" "$name" && echo " ✓ $name healthy"
done
}
case "${1:-start}" in
start) start_all ;;
stop) stop_all ;;
restart) stop_all; start_all ;;
status) for entry in "${SERVICES[@]}"; do
IFS=: read -r jar name port <<< "$entry"
printf "%-9s=%s\n" "$name" "$(curl -s -m 3 -o /dev/null -w '%{http_code}' http://localhost:$port/actuator/health 2>/dev/null)"
done ;;
logs) tail -n 60 "$LOG_DIR/${2:-all}.log" ;;
*) echo "usage: $0 [start|stop|restart|status|logs <name>]" >&2; exit 1 ;;
esac