From 053663e7d5692e6694184a88bdcd3702024a9c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horv=C3=A1th=20Istv=C3=A1n?= Date: Sun, 12 Oct 2025 11:45:20 +0200 Subject: [PATCH] Migrate to Sprint Boot 4 --- backend/build.gradle.kts | 84 ++++--- backend/gradle/wrapper/gradle-wrapper.jar | Bin 43764 -> 45633 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- backend/gradlew | 5 +- backend/gradlew.bat | 3 +- .../hu/bme/sch/cmsch/CMSchApplication.kt | 2 +- .../indulasch/IndulaschIntegrationService.kt | 2 +- .../addon/nova/NovaIntegrationController.kt | 9 +- .../addon/nova/NovaIntegrationService.kt | 30 +-- .../addon/payment/AddonPaymentController.kt | 38 ++-- .../hu/bme/sch/cmsch/admin/CsvParserUtil.kt | 29 +-- .../cmsch/admin/dashboard/DashboardPage.kt | 4 +- .../admin/dashboard/SubmissionHistory.kt | 4 +- .../admission/AdmissionByFormController.kt | 2 +- .../component/admission/AdmissionComponent.kt | 9 +- .../AdmissionComponentEntityConfiguration.kt | 2 +- .../admission/AdmissionController.kt | 2 +- .../component/admission/AdmissionService.kt | 4 +- .../component/admission/TicketController.kt | 2 +- .../component/app/ApplicationApiController.kt | 8 +- .../component/app/ApplicationConfigDto.kt | 13 +- .../component/app/ExtraMenuController.kt | 2 +- .../component/app/MenuAdminController.kt | 6 +- .../sch/cmsch/component/app/MenuService.kt | 7 +- .../component/bmejegy/BmejegyComponent.kt | 9 +- .../BmejegyComponentEntityConfiguration.kt | 2 +- .../component/bmejegy/BmejegyController.kt | 2 +- .../bmejegy/BmejegyRecordRepository.kt | 2 +- .../component/bmejegy/CheersBmejegyService.kt | 14 +- .../component/bmejegy/LegacyBmejegyService.kt | 17 +- .../component/bmejegy/LegacyBmejegyTimer.kt | 4 +- .../component/challenge/ChallengeComponent.kt | 9 +- .../ChallengeComponentEntityConfiguration.kt | 2 +- .../challenge/ChallengeController.kt | 2 +- .../communities/CommunitiesComponent.kt | 9 +- ...CommunitiesComponentEntityConfiguration.kt | 2 +- .../communities/CommunitiesController.kt | 2 +- .../component/communities/CommunityEntity.kt | 2 +- .../communities/CommunityRepository.kt | 2 +- .../communities/OrganizationController.kt | 2 +- .../communities/OrganizationEntity.kt | 2 +- .../communities/OrganizationRepository.kt | 2 +- .../conference/ConferenceCompanyController.kt | 2 +- .../conference/ConferenceComponent.kt | 9 +- .../ConferenceComponentEntityConfiguration.kt | 2 +- .../conference/ConferenceController.kt | 2 +- .../ConferenceOrganizerController.kt | 2 +- .../ConferencePresentationController.kt | 2 +- .../ConferencePresenterController.kt | 2 +- .../conference/ConferenceRepositories.kt | 4 +- .../conference/ConferenceSeedConfig.kt | 11 +- .../component/countdown/CountdownComponent.kt | 9 +- .../debt/DebtAdminDebtsByGroupController.kt | 6 +- .../debt/DebtAdminDebtsByUsersController.kt | 6 +- .../sch/cmsch/component/debt/DebtComponent.kt | 9 +- .../debt/DebtComponentEntityConfiguration.kt | 2 +- .../debt/DebtsOfMyGroupAdminController.kt | 2 +- .../component/debt/DebtsOfUserController.kt | 2 +- .../cmsch/component/debt/ProductController.kt | 2 +- .../cmsch/component/debt/ProductRepository.kt | 2 +- .../component/debt/SellProductsController.kt | 2 +- .../component/debt/SoldProductController.kt | 2 +- .../debt/SoldProductStatsController.kt | 2 +- .../cmsch/component/email/EmailComponent.kt | 9 +- .../EmailComponentEntityConfiguration.kt | 2 +- .../cmsch/component/email/EmailController.kt | 2 +- .../component/email/KirMailEmailProvider.kt | 2 +- .../component/errorlog/ErrorLogComponent.kt | 9 +- .../ErrorLogComponentEntityConfiguration.kt | 2 +- .../component/errorlog/ErrorLogController.kt | 2 +- .../component/errorlog/ErrorLogRepository.kt | 2 +- .../cmsch/component/event/EventComponent.kt | 9 +- .../EventComponentEntityConfiguration.kt | 2 +- .../cmsch/component/event/EventController.kt | 2 +- .../cmsch/component/event/EventRepository.kt | 2 +- .../cmsch/component/form/FormApiController.kt | 2 +- .../sch/cmsch/component/form/FormComponent.kt | 9 +- .../form/FormComponentEntityConfiguration.kt | 2 +- .../cmsch/component/form/FormController.kt | 2 +- .../sch/cmsch/component/form/FormEntityDto.kt | 4 +- .../component/form/FormMasterFillDashboard.kt | 8 +- .../sch/cmsch/component/form/FormService.kt | 11 +- .../cmsch/component/form/ResponseEntity.kt | 4 +- .../component/form/ResponseRepository.kt | 2 +- .../component/form/ResponsesController.kt | 10 +- .../component/form/VoteByFormDashboard.kt | 4 +- .../cmsch/component/form/VoteListDashboard.kt | 2 +- .../component/gallery/GalleryComponent.kt | 9 +- .../GalleryComponentEntityConfiguration.kt | 2 +- .../component/gallery/GalleryController.kt | 2 +- .../component/gallery/GalleryRepository.kt | 2 +- .../cmsch/component/gallery/GalleryView.kt | 2 +- .../groupselection/GroupSelectionComponent.kt | 9 +- .../groupselection/GroupSelectionService.kt | 5 +- .../sch/cmsch/component/home/HomeComponent.kt | 9 +- .../component/impressum/ImpressumComponent.kt | 9 +- .../cmsch/component/key/AccessKeyComponent.kt | 9 +- .../AccessKeyComponentEntityConfiguration.kt | 2 +- .../component/key/AccessKeyController.kt | 2 +- .../component/key/AccessKeyRepository.kt | 4 +- .../cmsch/component/key/AccessKeyService.kt | 5 +- .../leaderboard/LeaderBoardComponent.kt | 9 +- .../leaderboard/LeaderBoardGroupController.kt | 2 +- .../leaderboard/LeaderBoardService.kt | 25 +-- .../leaderboard/LeaderBoardUserController.kt | 2 +- .../component/location/LocationComponent.kt | 9 +- .../LocationComponentEntityConfiguration.kt | 2 +- .../component/location/LocationRepository.kt | 2 +- .../component/location/LocationService.kt | 8 +- .../location/RawLocationController.kt | 2 +- .../location/TrackOneGroupController.kt | 2 +- .../component/location/WaypointController.kt | 2 +- .../component/location/WaypointRepository.kt | 2 +- .../cmsch/component/login/LoginComponent.kt | 9 +- .../keycloak/KeycloakUserInfoResponse.kt | 2 +- .../component/messaging/MessagingComponent.kt | 9 +- .../component/messaging/MessagingService.kt | 2 +- .../sch/cmsch/component/news/NewsComponent.kt | 9 +- .../news/NewsComponentEntityConfiguration.kt | 2 +- .../cmsch/component/news/NewsController.kt | 2 +- .../component/profile/ProfileComponent.kt | 9 +- .../cmsch/component/profile/ProfileService.kt | 7 +- .../cmsch/component/proto/ProtoComponent.kt | 9 +- .../ProtoComponentEntityConfiguration.kt | 2 +- .../cmsch/component/proto/ProtoController.kt | 2 +- .../FirebaseMessagingConfiguration.kt | 13 +- .../PushNotificationComponent.kt | 9 +- ...otificationComponentEntityConfiguration.kt | 2 +- .../PushNotificationService.kt | 4 +- .../component/qrfight/QrFightComponent.kt | 9 +- .../QrFightComponentEntityConfiguration.kt | 2 +- .../cmsch/component/qrfight/QrFightService.kt | 13 +- .../component/qrfight/QrLevelController.kt | 2 +- .../component/qrfight/QrLevelRepository.kt | 2 +- .../component/qrfight/QrTowerController.kt | 2 +- .../component/qrfight/QrTowerRepository.kt | 2 +- .../race/FreestyleRaceRecordController.kt | 2 +- .../race/FreestyleRaceRecordRepository.kt | 2 +- .../component/race/RaceCategoryController.kt | 2 +- .../component/race/RaceCategoryRepository.kt | 2 +- .../race/RaceCategoryStatController.kt | 2 +- .../sch/cmsch/component/race/RaceComponent.kt | 9 +- .../race/RaceComponentEntityConfiguration.kt | 2 +- .../race/RaceLeaderBoardController.kt | 6 +- .../component/race/RaceRecordController.kt | 2 +- .../component/race/RaceRecordRepository.kt | 2 +- .../riddle/RiddleBusinessLogicService.kt | 11 +- .../component/riddle/RiddleCacheManager.kt | 5 +- .../riddle/RiddleCategoryController.kt | 2 +- .../cmsch/component/riddle/RiddleComponent.kt | 9 +- .../RiddleComponentEntityConfiguration.kt | 2 +- .../component/riddle/RiddleController.kt | 2 +- .../riddle/RiddleEntityRepository.kt | 2 +- .../riddle/RiddlePersistenceService.kt | 5 +- .../riddle/RiddlesByGroupsController.kt | 6 +- .../riddle/RiddlesByUsersController.kt | 6 +- .../cmsch/component/script/ScriptComponent.kt | 9 +- .../ScriptComponentEntityConfiguration.kt | 2 +- .../component/script/ScriptController.kt | 2 +- .../cmsch/component/script/ScriptEntity.kt | 2 +- .../script/ScriptResultController.kt | 2 +- .../component/script/ScriptRunnerDashboard.kt | 2 +- .../cmsch/component/script/ScriptService.kt | 6 +- .../script/ScriptTestConfiguration.kt | 4 +- .../component/script/ScriptsLogsDashboard.kt | 29 ++- .../script/sandbox/ScriptingContext.kt | 4 +- .../script/sandbox/ScriptingCsvUtil.kt | 6 +- .../script/sandbox/ScriptingJsonUtil.kt | 4 +- .../serviceaccount/ServiceAccountComponent.kt | 9 +- .../ServiceAccountComponentConfiguration.kt | 2 +- .../ServiceAccountKeyController.kt | 2 +- .../cmsch/component/sheets/SheetsComponent.kt | 9 +- .../SheetsComponentEntityConfiguration.kt | 4 +- .../component/sheets/SheetsController.kt | 2 +- .../component/sheets/SheetsFormsListener.kt | 8 +- .../component/sheets/SheetsSetupWizard.kt | 6 +- .../component/sheets/SheetsUpdaterService.kt | 10 +- .../staticpage/StaticPageComponent.kt | 9 +- .../StaticPageComponentEntityConfiguration.kt | 2 +- .../staticpage/StaticPageController.kt | 2 +- .../component/task/CheckRatingsController.kt | 2 +- .../component/task/SubmittedTaskController.kt | 2 +- .../component/task/TaskAdminRateController.kt | 6 +- .../component/task/TaskCategoryController.kt | 2 +- .../component/task/TaskCategoryRepository.kt | 2 +- .../sch/cmsch/component/task/TaskComponent.kt | 9 +- .../task/TaskComponentEntityConfiguration.kt | 2 +- .../cmsch/component/task/TaskController.kt | 2 +- .../task/TaskDiscOptimizerDashboard.kt | 205 ------------------ .../sch/cmsch/component/task/TasksService.kt | 7 +- .../sch/cmsch/component/team/TeamComponent.kt | 9 +- .../team/TeamComponentEntityConfiguration.kt | 2 +- .../cmsch/component/team/TeamController.kt | 2 +- .../team/TeamIntroductionReviewController.kt | 2 +- .../component/team/TeamLabelController.kt | 4 +- .../cmsch/component/team/TeamLabelEntity.kt | 2 +- .../sch/cmsch/component/team/TeamService.kt | 23 +- .../token/BulkTokenGeneratorDashboard.kt | 4 +- .../TokenAdminTokensByGroupController.kt | 6 +- .../token/TokenAdminTokensByTeamController.kt | 6 +- .../token/TokenAdminTokensByTypeController.kt | 6 +- .../TokenAdminTokensByUsersController.kt | 6 +- ...kenAdminTokensByUsersOfGroupsController.kt | 2 +- .../component/token/TokenCollectorService.kt | 7 +- .../cmsch/component/token/TokenComponent.kt | 9 +- .../TokenComponentEntityConfiguration.kt | 2 +- .../cmsch/component/token/TokenController.kt | 2 +- .../token/TokenPropertyController.kt | 6 +- .../token/TokenPropertyRepository.kt | 2 +- .../token/TokenPublicTokensStatsController.kt | 2 +- .../hu/bme/sch/cmsch/config/AppConfig.kt | 15 +- .../hu/bme/sch/cmsch/config/SecurityConfig.kt | 7 +- .../controller/ServerSideErrorController.kt | 2 +- .../sch/cmsch/controller/TestController.kt | 9 +- .../controller/admin/BasicAdminController.kt | 4 +- .../controller/admin/OneDeepEntityPage.kt | 2 +- .../controller/admin/SettingsController.kt | 10 +- .../controller/admin/SimpleEntityPage.kt | 2 +- .../controller/admin/TszImportDashboard.kt | 8 +- .../controller/admin/TwoDeepEntityPage.kt | 2 +- .../dashboard/InstanceInfoDashboard.kt | 10 +- .../userhandling/GroupController.kt | 2 +- .../GroupToUserMappingController.kt | 2 +- .../GuildToUserMappingController.kt | 2 +- .../MembersOfMyGroupController.kt | 2 +- .../userhandling/PermissionGroupAssignPage.kt | 2 +- .../userhandling/PermissionGroupController.kt | 2 +- .../PermissionGroupUserListPage.kt | 2 +- .../controller/userhandling/UserController.kt | 2 +- .../cmsch/repository/EntityPageDataSource.kt | 6 +- .../sch/cmsch/repository/ManualRepository.kt | 4 +- .../sch/cmsch/repository/UserRepository.kt | 4 +- .../hu/bme/sch/cmsch/service/UserService.kt | 7 +- .../setting/SettingProviderConfiguration.kt | 11 +- .../sch/cmsch/setting/SettingSerializer.kt | 4 +- .../statistics/StatisticsFilterConfig.kt | 14 +- .../cmsch/statistics/UserActivityFilter.kt | 9 +- .../sch/cmsch/util/StringToArraySerializer.kt | 16 +- .../resources/config/application.properties | 2 - 239 files changed, 537 insertions(+), 992 deletions(-) delete mode 100644 backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskDiscOptimizerDashboard.kt diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 96eb45ef..6174c85d 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -2,12 +2,12 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("org.springframework.boot") version "3.5.5" + id("org.springframework.boot") version "4.0.0" id("io.spring.dependency-management") version "1.1.7" - id("org.owasp.dependencycheck") version "12.1.3" - kotlin("jvm") version "2.2.10" - kotlin("plugin.spring") version "2.2.10" - id("org.sonarqube") version "6.2.0.5505" + id("org.owasp.dependencycheck") version "12.1.9" + kotlin("jvm") version "2.2.21" + kotlin("plugin.spring") version "2.2.21" + id("org.sonarqube") version "7.1.0.6387" } group = "hu.bme.sch" @@ -42,52 +42,48 @@ repositories { } dependencies { - implementation("com.google.firebase:firebase-admin:9.5.0") - implementation("software.amazon.awssdk:s3:2.32.29") - implementation("jakarta.xml.bind:jakarta.xml.bind-api:4.0.2") - implementation("org.springframework.boot:spring-boot-configuration-processor") - implementation("org.springframework.boot:spring-boot-starter-data-jpa") - implementation("org.springframework.boot:spring-boot-starter-oauth2-client") - implementation("org.springframework.boot:spring-boot-starter-security") - implementation("org.springframework.boot:spring-boot-starter-web") - implementation("org.springframework.boot:spring-boot-starter-webflux") - implementation("org.springframework.boot:spring-boot-starter-thymeleaf") - implementation("org.springframework.boot:spring-boot-starter-actuator") - implementation("org.springframework.boot:spring-boot-starter-validation") - implementation("org.springframework.session:spring-session-jdbc") - implementation("org.springframework.retry:spring-retry") - implementation("org.springframework.boot:spring-boot-starter-aop") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin") - implementation("com.squareup.okhttp3:okhttp:5.1.0") - implementation("com.itextpdf:itext-core:9.2.0") + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + developmentOnly("org.springframework.boot:spring-boot-devtools") + implementation("tools.jackson.dataformat:jackson-dataformat-csv") + implementation("tools.jackson.module:jackson-module-kotlin") + implementation("com.fasterxml.uuid:java-uuid-generator:5.1.1") implementation("com.github.spullara.mustache.java:compiler:0.9.14") + implementation("com.google.firebase:firebase-admin:9.7.0") + implementation("com.google.zxing:core:3.5.4") + implementation("com.google.zxing:javase:3.5.4") + implementation("com.itextpdf:itext-core:9.4.0") + implementation("com.squareup.okhttp3:okhttp:5.3.2") + implementation(platform("io.jsonwebtoken:jjwt-bom:0.13.0")) + runtimeOnly("io.jsonwebtoken:jjwt-impl") + runtimeOnly("io.jsonwebtoken:jjwt-jackson") + implementation("io.jsonwebtoken:jjwt-api") + implementation(platform("io.micrometer:micrometer-bom:1.16.0")) + runtimeOnly("io.micrometer:micrometer-core") + runtimeOnly("io.micrometer:micrometer-observation") + runtimeOnly("io.micrometer:micrometer-registry-prometheus") + implementation("org.commonmark:commonmark-ext-gfm-tables:0.27.0") + implementation("org.commonmark:commonmark:0.27.0") implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.11") - implementation("com.google.zxing:core:3.5.3") - implementation("com.google.zxing:javase:3.5.3") implementation("org.jetbrains.kotlin:kotlin-scripting-common") - implementation("org.jetbrains.kotlin:kotlin-scripting-jvm") - implementation("org.jetbrains.kotlin:kotlin-scripting-jvm-host") implementation("org.jetbrains.kotlin:kotlin-scripting-dependencies") implementation("org.jetbrains.kotlin:kotlin-scripting-dependencies-maven") + implementation("org.jetbrains.kotlin:kotlin-scripting-jvm") + implementation("org.jetbrains.kotlin:kotlin-scripting-jvm-host") + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") - implementation(platform("io.jsonwebtoken:jjwt-bom:0.13.0")) - implementation("io.jsonwebtoken:jjwt-api") - runtimeOnly("io.jsonwebtoken:jjwt-impl") - runtimeOnly("io.jsonwebtoken:jjwt-jackson") - implementation("com.fasterxml.uuid:java-uuid-generator:5.1.0") - implementation("org.commonmark:commonmark:0.25.1") - implementation("org.commonmark:commonmark-ext-gfm-tables:0.25.1") - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-csv") - developmentOnly("org.springframework.boot:spring-boot-devtools") - annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.0") + implementation("org.springframework.boot:spring-boot-starter-actuator") + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-oauth2-client") + implementation("org.springframework.boot:spring-boot-starter-security") + implementation("org.springframework.boot:spring-boot-starter-thymeleaf") + implementation("org.springframework.boot:spring-boot-starter-validation") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-webclient") + implementation("org.springframework.session:spring-session-jdbc") + implementation("software.amazon.awssdk:s3:2.39.3") runtimeOnly("com.h2database:h2") - implementation("org.postgresql:postgresql") - implementation(platform("io.micrometer:micrometer-bom:1.15.3")) - implementation("io.micrometer:micrometer-core") - implementation("io.micrometer:micrometer-registry-prometheus") - implementation("io.micrometer:micrometer-observation") + runtimeOnly("org.postgresql:postgresql") testApi("org.springframework.boot:spring-boot-starter-test") testApi("org.springframework.security:spring-security-test") } diff --git a/backend/gradle/wrapper/gradle-wrapper.jar b/backend/gradle/wrapper/gradle-wrapper.jar index 1b33c55baabb587c669f562ae36f953de2481846..f8e1ee3125fe0768e9a76ee977ac089eb657005e 100644 GIT binary patch delta 37442 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

WNp5~7YD4``2J+2^JLXSDAn1#GQa=Wm~d2R({ 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 delta 35599 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 ORzXA2f%7X@nSTIfr%7r6 diff --git a/backend/gradle/wrapper/gradle-wrapper.properties b/backend/gradle/wrapper/gradle-wrapper.properties index ff23a68d..bad7c246 100644 --- a/backend/gradle/wrapper/gradle-wrapper.properties +++ b/backend/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/backend/gradlew b/backend/gradlew index 23d15a93..adff685a 100755 --- a/backend/gradlew +++ b/backend/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/backend/gradlew.bat b/backend/gradlew.bat index db3a6ac2..c4bdd3ab 100644 --- a/backend/gradlew.bat +++ b/backend/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/CMSchApplication.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/CMSchApplication.kt index 729e3704..5bbedda0 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/CMSchApplication.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/CMSchApplication.kt @@ -4,8 +4,8 @@ import hu.bme.sch.cmsch.component.app.ApplicationComponent import hu.bme.sch.cmsch.config.ComponentLoadConfig import hu.bme.sch.cmsch.config.StartupPropertyConfig import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.boot.autoconfigure.domain.EntityScan import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.boot.runApplication @SpringBootApplication diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/indulasch/IndulaschIntegrationService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/indulasch/IndulaschIntegrationService.kt index 64489c94..1ad09abf 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/indulasch/IndulaschIntegrationService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/indulasch/IndulaschIntegrationService.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.addon.indulasch -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.qrfight.QrFightComponent import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationController.kt index d11c27f9..7dd3cef7 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationController.kt @@ -2,19 +2,14 @@ package hu.bme.sch.cmsch.addon.nova import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* @RestController @RequestMapping("/api/nova") -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.ext", - name = ["nova"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.ext.nova"]) class NovaIntegrationController( @param:Value("\${hu.bme.sch.cmsch.token.nova-in:}") private val validTokenIn: String, private val service: NovaIntegrationService diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationService.kt index 744004c8..1ed7552e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/nova/NovaIntegrationService.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.addon.nova -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.ObjectReader +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectReader import hu.bme.sch.cmsch.component.form.FilledOutFormDto import hu.bme.sch.cmsch.component.form.FormRepository import hu.bme.sch.cmsch.component.form.ResponseEntity @@ -15,9 +15,8 @@ import hu.bme.sch.cmsch.model.UserEntity import hu.bme.sch.cmsch.repository.UserRepository import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -28,12 +27,7 @@ const val AVATAR_TAG = "avatar" const val CV_TAG = "cv" @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.ext", - name = ["nova"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.ext.nova"]) class NovaIntegrationService( private val responseRepository: ResponseRepository, private val formRepository: FormRepository, @@ -46,7 +40,7 @@ class NovaIntegrationService( private val log = LoggerFactory.getLogger(javaClass) - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun updateSubmissions(emails: List): Int { val form = formRepository.findAll().firstOrNull { it.selected } @@ -74,7 +68,7 @@ class NovaIntegrationService( return successful } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = true, isolation = Isolation.READ_COMMITTED) fun fetchSubmissions(): List { val form = formRepository.findAll().firstOrNull { it.selected } @@ -151,7 +145,7 @@ class NovaIntegrationService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun setPaymentStatus(email: String, status: Boolean, rejectionMessage: String?) { val form = formRepository.findAll().firstOrNull { it.selected } @@ -173,7 +167,7 @@ class NovaIntegrationService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun setDetailsStatus(email: String, status: Boolean, rejectionMessage: String?) { val form = formRepository.findAll().firstOrNull { it.selected } @@ -195,7 +189,7 @@ class NovaIntegrationService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun setAvatarStatus(email: String, status: Boolean, rejectionMessage: String?) { val user = userRepository.findByEmail(email).orElse(null) ?: return @@ -218,7 +212,7 @@ class NovaIntegrationService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun setCvStatus(email: String, status: Boolean, rejectionMessage: String?) { val user = userRepository.findByEmail(email).orElse(null) ?: return diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/payment/AddonPaymentController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/payment/AddonPaymentController.kt index 4d1a7c40..02ad37d1 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/payment/AddonPaymentController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/addon/payment/AddonPaymentController.kt @@ -5,19 +5,14 @@ import hu.bme.sch.cmsch.component.debt.DebtDto import hu.bme.sch.cmsch.component.debt.SoldProductRepository import hu.bme.sch.cmsch.dto.FullDetails import hu.bme.sch.cmsch.util.getUser -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.security.core.Authentication import org.springframework.stereotype.Controller import org.springframework.ui.Model import org.springframework.web.bind.annotation.GetMapping -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.addon.load", - name = ["payment"], - havingValue = "true", - matchIfMissing = false -) @Controller +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.addon.load.payment"]) class AddonPaymentController( private val debtsRepository: SoldProductRepository, ) { @@ -28,23 +23,20 @@ class AddonPaymentController( val user = auth.getUser() model.addAttribute("user", user) - val debts = debtsRepository.findAllByOwnerId(user.id) - .map { - DebtDto( - it.product, - it.price, - it.sellerName, - it.responsibleName, - it.payed, - it.shipped, - it.log, - it.materialIcon - ) - } + val debts = debtsRepository.findAllByOwnerId(user.id).map { + DebtDto( + it.product, + it.price, + it.sellerName, + it.responsibleName, + it.payed, + it.shipped, + it.log, + it.materialIcon, + ) + } model.addAttribute("debts", debts) - model.addAttribute("sumDebts", debts - .filter { !it.payed } - .sumOf { it.price }) + model.addAttribute("sumDebts", debts.filter { !it.payed }.sumOf { it.price }) return "addon/addonPayments" } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/CsvParserUtil.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/CsvParserUtil.kt index 29193e57..eda7d410 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/CsvParserUtil.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/CsvParserUtil.kt @@ -1,12 +1,12 @@ package hu.bme.sch.cmsch.admin -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.DeserializationFeature -import com.fasterxml.jackson.dataformat.csv.CsvMapper -import com.fasterxml.jackson.dataformat.csv.CsvParser -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import com.fasterxml.jackson.module.kotlin.KotlinModule +import tools.jackson.core.StreamWriteFeature +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.DeserializationFeature +import tools.jackson.dataformat.csv.CsvMapper +import tools.jackson.dataformat.csv.CsvReadFeature +import tools.jackson.dataformat.csv.CsvSchema +import tools.jackson.module.kotlin.kotlinModule import java.io.InputStream import java.io.OutputStream import kotlin.reflect.KClass @@ -15,12 +15,13 @@ import kotlin.reflect.full.memberProperties class CsvParserUtil(private val type: KClass) { - private val mapper = CsvMapper() - .apply { registerModule(KotlinModule.Builder().build()) } - .disable(CsvParser.Feature.FAIL_ON_MISSING_HEADER_COLUMNS) - .disable(CsvParser.Feature.FAIL_ON_MISSING_COLUMNS) + private val mapper = CsvMapper.builder() + .addModule(kotlinModule { }) + .disable(CsvReadFeature.FAIL_ON_MISSING_HEADER_COLUMNS) + .disable(CsvReadFeature.FAIL_ON_MISSING_COLUMNS) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) - .enable(JsonGenerator.Feature.IGNORE_UNKNOWN) + .enable(StreamWriteFeature.IGNORE_UNKNOWN) + .build() private val writerSchema: CsvSchema @@ -57,9 +58,9 @@ class CsvParserUtil(private val type: KClass) { return writer.writeValue(outputStream, data) } - fun importFromCsv(inputStream: InputStream): List { + fun importFromCsv(inputStream: InputStream): MutableList { val reader = mapper.readerFor(type.java).with(readerSchema) return reader.readValues(inputStream).readAll() } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/DashboardPage.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/DashboardPage.kt index e61a5d11..0d11b472 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/DashboardPage.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/DashboardPage.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.admin.dashboard -import com.fasterxml.jackson.dataformat.csv.CsvMapper -import com.fasterxml.jackson.dataformat.csv.CsvSchema +import tools.jackson.dataformat.csv.CsvMapper +import tools.jackson.dataformat.csv.CsvSchema import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.service.AdminMenuEntry diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/SubmissionHistory.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/SubmissionHistory.kt index 7c205076..6a96f04f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/SubmissionHistory.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/admin/dashboard/SubmissionHistory.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.admin.dashboard -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectMapper val historyMapper = ObjectMapper() val historyReader = historyMapper.readerFor(object : TypeReference>() {}) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionByFormController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionByFormController.kt index fe843962..41cdd6aa 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionByFormController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionByFormController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.admission -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.GenerateOverview import hu.bme.sch.cmsch.admin.OverviewType import hu.bme.sch.cmsch.component.form.FormRepository diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponent.kt index c90420a5..b4b6f449 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponent.kt @@ -4,17 +4,12 @@ import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["admission"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.admission"]) class AdmissionComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponentEntityConfiguration.kt index f9c405e9..879ca5e3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.admission import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionController.kt index 1f6c9a91..af758f26 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.admission -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionService.kt index 9f90eadb..73bc376f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/AdmissionService.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.admission -import com.fasterxml.jackson.dataformat.csv.CsvMapper -import com.fasterxml.jackson.dataformat.csv.CsvSchema +import tools.jackson.dataformat.csv.CsvMapper +import tools.jackson.dataformat.csv.CsvSchema import hu.bme.sch.cmsch.component.form.ResponseRepository import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.repository.UserRepository diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/TicketController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/TicketController.kt index e80e3a5e..6290548f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/TicketController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/admission/TicketController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.admission -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationApiController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationApiController.kt index 12d96328..415b9e0d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationApiController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationApiController.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.app import com.fasterxml.jackson.annotation.JsonView -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectMapper import com.google.zxing.BarcodeFormat import com.google.zxing.EncodeHintType import com.google.zxing.MultiFormatWriter @@ -64,7 +64,7 @@ class ApplicationApiController( return ApplicationConfigDto( role = role, menu = listOf(), - components = componentWriter.writeValueAsString(components) + components = components ) } } @@ -74,7 +74,7 @@ class ApplicationApiController( return ApplicationConfigDto( role = role, menu = menuService.getCachedMenuForRole(role), - components = componentWriter.writeValueAsString(components) + components = components ) } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationConfigDto.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationConfigDto.kt index 330fba7a..50ae9a5f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationConfigDto.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationConfigDto.kt @@ -1,9 +1,5 @@ package hu.bme.sch.cmsch.component.app -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonSerialize import hu.bme.sch.cmsch.model.RoleType data class ApplicationConfigDto( @@ -11,12 +7,5 @@ data class ApplicationConfigDto( var menu: List, // Components -> properties -> values: Map> - @field:JsonSerialize(using = ApplicationConfigFastSerializer::class) - var components: String + var components: Map ) - -class ApplicationConfigFastSerializer : JsonSerializer() { - override fun serialize(value: String?, gen: JsonGenerator?, serializers: SerializerProvider?) { - gen?.writeRawValue(value ?: "") - } -} \ No newline at end of file diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ExtraMenuController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ExtraMenuController.kt index 0f5f3841..6692d64f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ExtraMenuController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ExtraMenuController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.app -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuAdminController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuAdminController.kt index 97be9bd0..a59d494a 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuAdminController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuAdminController.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.app -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.dataformat.csv.CsvMapper -import com.fasterxml.jackson.dataformat.csv.CsvSchema +import tools.jackson.databind.ObjectMapper +import tools.jackson.dataformat.csv.CsvMapper +import tools.jackson.dataformat.csv.CsvSchema import hu.bme.sch.cmsch.admin.GenerateOverview import hu.bme.sch.cmsch.admin.OverviewBuilder import hu.bme.sch.cmsch.admin.OverviewType diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuService.kt index d4e693b6..dcfa13dd 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/MenuService.kt @@ -14,8 +14,7 @@ import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.context.event.ContextRefreshedEvent import org.springframework.context.event.EventListener -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.PlatformTransactionManager import org.springframework.transaction.annotation.Isolation @@ -131,7 +130,7 @@ class MenuService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun persistSettings(menus: List, role: RoleType) { menuRepository.deleteAllByRole(role) @@ -197,7 +196,7 @@ class MenuService( var external: Boolean = false, ) - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun importMenu(entries: List, rolesToInclude: List): Pair { var imported = 0 diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponent.kt index b64c228a..3b3a942c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponent.kt @@ -4,17 +4,12 @@ import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["bmejegy"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.bmejegy"]) class BmejegyComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponentEntityConfiguration.kt index d9d109ff..4c29ec78 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.bmejegy import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyController.kt index a72b4baf..909da7b3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.bmejegy -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyRecordRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyRecordRepository.kt index b8e2d289..9548b139 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyRecordRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/BmejegyRecordRepository.kt @@ -10,7 +10,7 @@ import org.springframework.stereotype.Repository interface BmejegyRecordRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findAllByQrCode(qr: String): List diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/CheersBmejegyService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/CheersBmejegyService.kt index cabc386e..4b0d8ff8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/CheersBmejegyService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/CheersBmejegyService.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.bmejegy -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.form.FormService import hu.bme.sch.cmsch.extending.BmeJegyListener import hu.bme.sch.cmsch.model.GroupEntity @@ -12,18 +12,16 @@ import hu.bme.sch.cmsch.repository.UserRepository import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional import java.sql.SQLException -import java.util.Optional @Service @ConditionalOnBean(BmejegyComponent::class) -@ConditionalOnProperty(name = [LEGACY_BMEJEGY_CONFIG_PROPERTY], havingValue = "false", matchIfMissing = true) +@ConditionalOnBooleanProperty(name = [LEGACY_BMEJEGY_CONFIG_PROPERTY], havingValue = false, matchIfMissing = true) class CheersBmejegyService( private val bmejegyRecordRepository: BmejegyRecordRepository, private val formService: FormService, @@ -70,7 +68,7 @@ class CheersBmejegyService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun updateUserStatuses() { val unmatched = bmejegyRecordRepository.findAllByMatchedUserId(0) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyService.kt index c1df5ffc..d5d78a3f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyService.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.bmejegy -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectMapper +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.form.FormService import hu.bme.sch.cmsch.extending.BmeJegyListener import hu.bme.sch.cmsch.model.GroupEntity @@ -14,13 +14,12 @@ import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.http.HttpHeaders import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.http.client.reactive.ReactorClientHttpConnector -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -37,7 +36,7 @@ const val LEGACY_BMEJEGY_CONFIG_PROPERTY = "hu.bme.sch.cmsch.legacy-bmejegy-url" @Service @ConditionalOnBean(BmejegyComponent::class) -@ConditionalOnProperty(name = [LEGACY_BMEJEGY_CONFIG_PROPERTY], havingValue = "true", matchIfMissing = false) +@ConditionalOnBooleanProperty(name = [LEGACY_BMEJEGY_CONFIG_PROPERTY]) class LegacyBmejegyService( @param:Value("\${hu.bme.sch.cmsch.component.bmejegy.bmejegyservice.username:}") private val bmejegyUsername: String, @param:Value("\${hu.bme.sch.cmsch.component.bmejegy.bmejegyservice.password:}") private val bmejegyPassword: String, @@ -65,7 +64,7 @@ class LegacyBmejegyService( return Optional.ofNullable(bmejegyRecordRepository.findAllByQrCode(qr).firstOrNull()) } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun updateTickets(tickets: BmeJegyResponse) { val registered = bmejegyRecordRepository.findAll().associateBy { it.itemId } @@ -101,7 +100,7 @@ class LegacyBmejegyService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun updateUserStatuses() { val unmatched = bmejegyRecordRepository.findAllByMatchedUserId(0) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyTimer.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyTimer.kt index 1d7894e3..433b828e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyTimer.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/bmejegy/LegacyBmejegyTimer.kt @@ -2,14 +2,14 @@ package hu.bme.sch.cmsch.component.bmejegy import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import java.util.concurrent.Executors @Service @ConditionalOnBean(BmejegyComponent::class) -@ConditionalOnProperty(name = [LEGACY_BMEJEGY_CONFIG_PROPERTY], havingValue = "true", matchIfMissing = false) +@ConditionalOnBooleanProperty(name = [LEGACY_BMEJEGY_CONFIG_PROPERTY]) class LegacyBmejegyTimer( private val legacyBmejegyService: LegacyBmejegyService, private val bmejegyComponent: BmejegyComponent diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponent.kt index c69d4515..99d3c7c2 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.service.ImplicitPermissions import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["challenge"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.challenge"]) class ChallengeComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponentEntityConfiguration.kt index 71c53055..9fd62fd3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.challenge import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeController.kt index 5e16a00c..589b7072 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/challenge/ChallengeController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.challenge -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.config.OwnershipType import hu.bme.sch.cmsch.config.StartupPropertyConfig import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponent.kt index 8ffe1ff1..3491bae0 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* import hu.bme.sch.cmsch.util.isAvailableForRole -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["communities"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.communities"]) class CommunitiesComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponentEntityConfiguration.kt index 060ec097..f3025003 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.communities import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesController.kt index c32452ea..06f5cdb3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunitiesController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.communities -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityEntity.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityEntity.kt index 0870553a..af7bceba 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityEntity.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityEntity.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.communities import com.fasterxml.jackson.annotation.JsonView -import com.fasterxml.jackson.databind.annotation.JsonSerialize +import tools.jackson.databind.annotation.JsonSerialize import hu.bme.sch.cmsch.admin.* import hu.bme.sch.cmsch.component.EntityConfig import hu.bme.sch.cmsch.dto.Edit diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityRepository.kt index 25dd75b1..5ad7cb5f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/CommunityRepository.kt @@ -14,6 +14,6 @@ interface CommunityRepository : CrudRepository, override fun findById(id: Int): Optional - override fun findAll(): List + override fun findAll(): MutableList } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationController.kt index c574dfd9..e4fa1df1 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.communities -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationEntity.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationEntity.kt index e2fa1634..e3783429 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationEntity.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationEntity.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.communities import com.fasterxml.jackson.annotation.JsonView -import com.fasterxml.jackson.databind.annotation.JsonSerialize +import tools.jackson.databind.annotation.JsonSerialize import hu.bme.sch.cmsch.admin.* import hu.bme.sch.cmsch.component.EntityConfig import hu.bme.sch.cmsch.dto.Edit diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationRepository.kt index aa441a83..958bb95d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/communities/OrganizationRepository.kt @@ -14,6 +14,6 @@ interface OrganizationRepository : CrudRepository, override fun findById(id: Int): Optional - override fun findAll(): List + override fun findAll(): MutableList } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceCompanyController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceCompanyController.kt index 6f6d22db..51ac3a5c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceCompanyController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceCompanyController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.conference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponent.kt index e7aa042f..1679a053 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponent.kt @@ -4,17 +4,12 @@ import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["conference"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.conference"]) class ConferenceComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponentEntityConfiguration.kt index f91833f1..8f3426f1 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.conference import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceController.kt index 6ef9b84c..4d68b16c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.conference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceOrganizerController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceOrganizerController.kt index bb5df246..08f22e08 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceOrganizerController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceOrganizerController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.conference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresentationController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresentationController.kt index 6a594f69..8310ff08 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresentationController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresentationController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.conference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresenterController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresenterController.kt index 00561a14..77115252 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresenterController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferencePresenterController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.conference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceRepositories.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceRepositories.kt index d3e8a251..8e534877 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceRepositories.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceRepositories.kt @@ -8,7 +8,7 @@ import org.springframework.stereotype.Repository @Repository @ConditionalOnBean(ConferenceComponent::class) interface ConferenceRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableList } @Repository @@ -35,4 +35,4 @@ interface ConferencePresentationRepository : CrudRepository, EntityPageDataSource { fun findAllByVisibleTrue(): List -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceSeedConfig.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceSeedConfig.kt index f55de159..25482650 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceSeedConfig.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/conference/ConferenceSeedConfig.kt @@ -27,8 +27,7 @@ class ConferenceSeedConfig( private fun addConference() { if (conferenceRepository.count() != 0L) return - conferenceRepository.saveAll( - listOf( + conferenceRepository.saveAll(mutableListOf( ConferenceEntity( title = "Test Conference 2022", priority = 0, @@ -51,7 +50,7 @@ class ConferenceSeedConfig( private fun addCompanies() { if (conferenceCompanyRepository.count() != 0L) return conferenceCompanyRepository.saveAll( - listOf( + mutableListOf( ConferenceCompanyEntity( name = "Test Company 1", selector = "test-company-1", @@ -91,7 +90,7 @@ class ConferenceSeedConfig( private fun addPresenters() { if (conferencePresenterRepository.count() != 0L) return conferencePresenterRepository.saveAll( - listOf( + mutableListOf( ConferencePresenterEntity( name = "Test Presenter 1", selector = "test-presenter-1", @@ -123,7 +122,7 @@ class ConferenceSeedConfig( private fun addPresentations() { if (conferencePresentationRepository.count() != 0L) return conferencePresentationRepository.saveAll( - listOf( + mutableListOf( ConferencePresentationEntity( slug = "test-presentation-1", title = "Test Presentation 1", @@ -196,7 +195,7 @@ class ConferenceSeedConfig( private fun addOrganizers() { if (conferenceOrganizerRepository.count() != 0L) return conferenceOrganizerRepository.saveAll( - listOf( + mutableListOf( ConferenceOrganizerEntity( name = "Test Organizer 1", rank = "Test Rank 1", diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/countdown/CountdownComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/countdown/CountdownComponent.kt index a3e6a1c1..852967d2 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/countdown/CountdownComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/countdown/CountdownComponent.kt @@ -5,17 +5,12 @@ import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* import hu.bme.sch.cmsch.util.isAvailableForRole -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["countdown"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.countdown"]) class CountdownComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByGroupController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByGroupController.kt index 89746d31..0920bb72 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByGroupController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByGroupController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.repository.GroupRepository import hu.bme.sch.cmsch.repository.ManualRepository @@ -38,7 +38,7 @@ class DebtAdminDebtsByGroupController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { return soldProductRepository.findAll().groupBy { it.responsibleGroupId } .map { it.value } .filter { it.isNotEmpty() } @@ -51,7 +51,7 @@ class DebtAdminDebtsByGroupController( debts.filter { !it.payed }.sumOf { it.price }, debts.filter { !it.finsihed }.sumOf { it.price } ) - } + }.toMutableList() } }, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByUsersController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByUsersController.kt index b1e5a4ce..19d86f06 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByUsersController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtAdminDebtsByUsersController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.repository.GroupRepository import hu.bme.sch.cmsch.repository.ManualRepository @@ -40,7 +40,7 @@ class DebtAdminDebtsByUsersController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { return soldProductRepository.findAll().groupBy { it.ownerId } .map { it.value } .filter { it.isNotEmpty() } @@ -54,7 +54,7 @@ class DebtAdminDebtsByUsersController( debts.filter { !it.payed }.sumOf { it.price }, debts.filter { !it.finsihed }.sumOf { it.price } ) - } + }.toMutableList() } }, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponent.kt index 8aa19a7c..7957be71 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.debt import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["debt"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.debt"]) class DebtComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponentEntityConfiguration.kt index 7058b138..2feead93 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.debt import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfMyGroupAdminController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfMyGroupAdminController.kt index 40959252..82b22781 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfMyGroupAdminController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfMyGroupAdminController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.INVALID_ID_ERROR import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfUserController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfUserController.kt index b422426e..bb6f451c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfUserController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/DebtsOfUserController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.service.AdminMenuService import hu.bme.sch.cmsch.service.AuditLogService diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductController.kt index 673b02e6..d5c1acc2 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductRepository.kt index 77d7a696..a5d3326e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/ProductRepository.kt @@ -10,7 +10,7 @@ import org.springframework.stereotype.Repository interface ProductRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findAllByType(type: ProductType): List fun findAllByTypeAndVisibleTrue(type: ProductType): List } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SellProductsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SellProductsController.kt index 4fd8b10c..955210a3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SellProductsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SellProductsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.service.AdminMenuService diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductController.kt index abfa843c..fa13f4cb 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductStatsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductStatsController.kt index 3c2da268..4c4dd162 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductStatsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/debt/SoldProductStatsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.debt -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.service.AdminMenuService import hu.bme.sch.cmsch.service.AuditLogService diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponent.kt index 4d802203..375d53c1 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponent.kt @@ -5,17 +5,12 @@ import hu.bme.sch.cmsch.component.event.EventEntity import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["email"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.email"]) class EmailComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponentEntityConfiguration.kt index a6337787..60cf45d6 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.email import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailController.kt index 13daab34..beeeff36 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/EmailController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.email -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.RealEntityController import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/KirMailEmailProvider.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/KirMailEmailProvider.kt index 0ad3f2ea..a5a2bbef 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/KirMailEmailProvider.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/email/KirMailEmailProvider.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.email -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.service.AuditLogService import okhttp3.MediaType.Companion.toMediaTypeOrNull diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponent.kt index b9bdb24c..a1ad5370 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponent.kt @@ -7,17 +7,12 @@ import hu.bme.sch.cmsch.setting.BooleanSettingRef import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["errorlog"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.errorlog"]) class ErrorLogComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponentEntityConfiguration.kt index eb4a3956..c9654a6c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.errorlog import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogController.kt index 76cad146..cc0fdecd 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.errorlog -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogRepository.kt index b2cda46a..4a199ab5 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/errorlog/ErrorLogRepository.kt @@ -13,7 +13,7 @@ import java.util.* interface ErrorLogRepository : CrudRepository, EntityPageDataSource { @Query("select e from ErrorLogEntity e order by e.lastReportedAt desc") - override fun findAll(): List + override fun findAll(): MutableIterable fun findByMessageAndStackAndUserAgentAndHrefAndRole( message: String, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponent.kt index 1fe0ee60..e8c2583d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.event import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["event"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.event"]) class EventComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponentEntityConfiguration.kt index efe42d77..d5b05334 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.event import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventController.kt index 59abfeb6..b320e17f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.event -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventRepository.kt index e10af5e4..4c30b24d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/event/EventRepository.kt @@ -9,7 +9,7 @@ import java.util.* @Repository @ConditionalOnBean(EventComponent::class) interface EventRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findByUrl(url: String): Optional fun findAllByVisibleTrueOrderByTimestampStart(): List } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormApiController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormApiController.kt index d6f5cd7d..508e821e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormApiController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormApiController.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.form import com.fasterxml.jackson.annotation.JsonView -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.dto.FullDetails import hu.bme.sch.cmsch.dto.Preview import hu.bme.sch.cmsch.model.RoleType diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponent.kt index f18c92cf..712a0506 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponent.kt @@ -7,17 +7,12 @@ import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup import hu.bme.sch.cmsch.setting.StringSettingRef -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["form"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.form"]) class FormComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponentEntityConfiguration.kt index 4174c96a..668be43e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.form import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormController.kt index a33d0551..eb093d61 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.form -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.sheets.SHEETS_WIZARD import hu.bme.sch.cmsch.component.sheets.SheetsComponent import hu.bme.sch.cmsch.component.sheets.SheetsUpdaterService diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormEntityDto.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormEntityDto.kt index c96d4d5c..7570266b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormEntityDto.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormEntityDto.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.form import com.fasterxml.jackson.annotation.JsonView -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.ObjectReader +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectReader import hu.bme.sch.cmsch.dto.FullDetails import org.slf4j.LoggerFactory diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormMasterFillDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormMasterFillDashboard.kt index 1af90cb2..91dd2c90 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormMasterFillDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormMasterFillDashboard.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.form -import com.fasterxml.jackson.core.JacksonException -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.JacksonException +import tools.jackson.core.type.TypeReference +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.admin.dashboard.* import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.extending.FormSubmissionListener @@ -217,4 +217,4 @@ class FormMasterFillDashboard( return dashboardPage("$FORM_MASTER_FILL/form/$formId", 2, "Beküldés sikeres!") } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormService.kt index 81a04394..0ac329d8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/FormService.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.form -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.email.EmailService import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.extending.FormSubmissionListener @@ -11,8 +11,7 @@ import hu.bme.sch.cmsch.repository.UserRepository import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -32,7 +31,7 @@ class FormService( private val emailService: Optional ) { - internal final val log = LoggerFactory.getLogger(javaClass) + internal val log = LoggerFactory.getLogger(javaClass) private final val objectMapper = jacksonObjectMapper() private final val gridReader = objectMapper.readerFor(FormGridValue::class.java) @@ -148,7 +147,7 @@ class FormService( ) - @Retryable(value = [SQLException::class], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [SQLException::class], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun submitForm(user: CmschUser?, path: String, data: Map, update: Boolean): FormSubmissionResult { val form = formRepository.findAllByUrl(path).getOrNull(0) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseEntity.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseEntity.kt index 843b44d9..2200632a 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseEntity.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseEntity.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.form import com.fasterxml.jackson.annotation.JsonView -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.* import hu.bme.sch.cmsch.admin.dashboard.SubmissionHistory import hu.bme.sch.cmsch.admin.dashboard.historyReader diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseRepository.kt index ee1fe986..1148f007 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponseRepository.kt @@ -33,6 +33,6 @@ interface ResponseRepository : CrudRepository, fun findTop1ByFormIdAndEntryTokenOrderByLineDesc(formId: Int, entryToken: String): List - override fun findAll(): List + override fun findAll(): MutableList } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponsesController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponsesController.kt index 245ccc81..9464fb6c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponsesController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/ResponsesController.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.form -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.dataformat.csv.CsvMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectMapper +import tools.jackson.dataformat.csv.CsvMapper import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.extending.FormSubmissionListener @@ -46,7 +46,7 @@ class ResponsesController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { return formService.getAllResponses() .groupBy { it.formId } .map { it.value } @@ -64,7 +64,7 @@ class ResponsesController( responses.count { it.detailsValidated }, ) }.orElse(null) - } + }.toMutableList() } }, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteByFormDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteByFormDashboard.kt index a6e629f8..c337cd6d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteByFormDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteByFormDashboard.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.form -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.admin.dashboard.* import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.service.AdminMenuService diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteListDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteListDashboard.kt index 5e4556a5..3a904b14 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteListDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/form/VoteListDashboard.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.form -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.GenerateOverview import hu.bme.sch.cmsch.admin.OverviewType import hu.bme.sch.cmsch.controller.admin.ControlAction diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponent.kt index f19dbfc4..e92558ee 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup import hu.bme.sch.cmsch.setting.StringSettingRef -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["gallery"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.gallery"]) class GalleryComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponentEntityConfiguration.kt index 0f3e731a..92283c55 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.gallery import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryController.kt index 38a4b18d..7e33f0ba 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.gallery -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryRepository.kt index c2ee7122..8de9b01c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryRepository.kt @@ -8,7 +8,7 @@ import org.springframework.stereotype.Repository @Repository @ConditionalOnBean(GalleryComponent::class) interface GalleryRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableList fun findByShowOnHomePage(showOnHomePage: Boolean): List } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryView.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryView.kt index bbdae3f7..fb13c0f9 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryView.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/gallery/GalleryView.kt @@ -7,4 +7,4 @@ import hu.bme.sch.cmsch.dto.Preview data class GalleryView ( @field:JsonView(value = [Preview::class, FullDetails::class]) val photos: List -) \ No newline at end of file +) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionComponent.kt index 92093be7..b4116e8d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionComponent.kt @@ -5,17 +5,12 @@ import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ImplicitPermissions import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["groupselection"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.groupselection"]) class GroupSelectionComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionService.kt index 92e4a04b..f5c63683 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/groupselection/GroupSelectionService.kt @@ -5,8 +5,7 @@ import hu.bme.sch.cmsch.repository.GroupRepository import hu.bme.sch.cmsch.repository.UserRepository import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -21,7 +20,7 @@ class GroupSelectionService( private val log = LoggerFactory.getLogger(javaClass) - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun selectGroup( user: UserEntity, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/home/HomeComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/home/HomeComponent.kt index 044a1add..856a4ee3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/home/HomeComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/home/HomeComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.home import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["home"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.home"]) class HomeComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/impressum/ImpressumComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/impressum/ImpressumComponent.kt index cfdb5772..03a2e5c8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/impressum/ImpressumComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/impressum/ImpressumComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.impressum import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["impressum"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.impressum"]) class ImpressumComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponent.kt index 4d52f435..ab8abbad 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.key import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["accessKeys"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.accessKeys"]) class AccessKeyComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponentEntityConfiguration.kt index 0ded042e..8a02cf79 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.key import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyController.kt index 75a7b87b..abe7f298 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.key -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyRepository.kt index 3bc27f9a..1db9db3e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyRepository.kt @@ -9,10 +9,10 @@ import org.springframework.stereotype.Repository @ConditionalOnBean(AccessKeyComponent::class) interface AccessKeyRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findTop1ByUsedByUserId(userId: Int): List fun findTop1ByAccessKey(accessKey: String): List -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyService.kt index 7061d9b5..cfe36669 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/key/AccessKeyService.kt @@ -7,8 +7,7 @@ import hu.bme.sch.cmsch.service.AuditLogService import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -29,7 +28,7 @@ class AccessKeyService( private val log = LoggerFactory.getLogger(javaClass) - @Retryable(value = [SQLException::class], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [SQLException::class], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun validateKey(user: CmschUser, inputKey: String): AccessKeyResponse { val key = inputKey.trim() diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardComponent.kt index 91603f74..4a14d42b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.leaderboard import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["leaderboard"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.leaderboard"]) class LeaderBoardComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardGroupController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardGroupController.kt index dfea85bd..35a9e3b0 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardGroupController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardGroupController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.leaderboard -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ButtonAction import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardService.kt index b9dd7245..ff87a503 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardService.kt @@ -18,8 +18,7 @@ import hu.bme.sch.cmsch.util.CombinedKey import jakarta.annotation.PostConstruct import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation @@ -135,7 +134,7 @@ open class LeaderBoardService( return null } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE) @Scheduled(fixedRate = 1000L * 60 * 60 * 10) open fun recalculate() { @@ -147,7 +146,7 @@ open class LeaderBoardService( forceRecalculateForUsers() } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE) open fun forceRecalculateForGroups() { val hintPercentage: Float = riddleComponent.map { it.hintScorePercent }.orElse(0) / 100f @@ -157,7 +156,7 @@ open class LeaderBoardService( val tasksPercent = leaderBoardComponent.tasksPercent / 100.0f val tasks = when (startupPropertyConfig.taskOwnershipMode) { OwnershipType.GROUP -> { - taskSubmissions.map { it.findAll() }.orElse(listOf()) + taskSubmissions.map { it.findAll() }.orElse(mutableListOf()) .groupBy { CombinedKey(it.groupId ?: 0, it.groupName) } .filter { groups.findByName(it.key.name).map { m -> m.races }.orElse(false) } .map { @@ -179,7 +178,7 @@ open class LeaderBoardService( val riddleCache = riddleRepository.map { repo -> repo.findAll().associateBy { it.id } }.orElse(mapOf()) val riddles = when (startupPropertyConfig.riddleOwnershipMode) { OwnershipType.GROUP -> { - riddleSubmissions.map { it.findAll() }.orElse(listOf()) + riddleSubmissions.map { it.findAll() }.orElse(mutableListOf()) .groupBy { groups.findById(it.ownerGroupId).orElseThrow() } .filter { it.key?.races ?: false } .map { riddleGroup -> @@ -204,7 +203,7 @@ open class LeaderBoardService( val challengesPercent = leaderBoardComponent.challengesPercent / 100.0f val challenges = when (startupPropertyConfig.challengeOwnershipMode) { OwnershipType.GROUP -> { - challengeSubmissions.map { it.findAll() }.orElse(listOf()) + challengeSubmissions.map { it.findAll() }.orElse(mutableListOf()) .groupBy { CombinedKey(it.groupId ?: 0, it.groupName) } .filter { groups.findByName(it.key.name).map { m -> m.races }.orElse(false) } .map { entity -> @@ -255,7 +254,7 @@ open class LeaderBoardService( tokenScore = tokenScore ) } - }.orElse(listOf()) + }.orElse(mutableListOf()) } } @@ -282,7 +281,7 @@ open class LeaderBoardService( log.info("Recalculating finished") } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE) open fun forceRecalculateForUsers() { val hintPercentage: Float = riddleComponent.map { it.hintScorePercent }.orElse(0) / 100f @@ -293,7 +292,7 @@ open class LeaderBoardService( val tasks = when (startupPropertyConfig.taskOwnershipMode) { OwnershipType.GROUP -> listOf() OwnershipType.USER -> { - taskSubmissions.map { it.findAll() }.orElse(listOf()) + taskSubmissions.map { it.findAll() }.orElse(mutableListOf()) .groupBy { it.userId } .map { entity -> val user = users.findById(entity.key ?: 0) @@ -316,7 +315,7 @@ open class LeaderBoardService( val riddles = when (startupPropertyConfig.riddleOwnershipMode) { OwnershipType.GROUP -> listOf() OwnershipType.USER -> { - riddleSubmissions.map { it.findAll() }.orElse(listOf()) + riddleSubmissions.map { it.findAll() }.orElse(mutableListOf()) .groupBy { users.findById(it.ownerUserId).orElseThrow() } .map { riddleGroup -> LeaderBoardAsUserEntryDto(riddleGroup.key?.id ?: 0, @@ -340,7 +339,7 @@ open class LeaderBoardService( val challenges = when (startupPropertyConfig.challengeOwnershipMode) { OwnershipType.GROUP -> listOf() OwnershipType.USER -> { - challengeSubmissions.map { it.findAll() }.orElse(listOf()) + challengeSubmissions.map { it.findAll() }.orElse(mutableListOf()) .groupBy { it.userId } .map { entity -> entity.value.forEach { challenge -> @@ -365,7 +364,7 @@ open class LeaderBoardService( val tokens = when (startupPropertyConfig.tokenOwnershipMode) { OwnershipType.GROUP -> listOf() OwnershipType.USER -> { - tokenSubmissions.map { it.findAll() }.orElse(listOf()) + tokenSubmissions.map { it.findAll() }.orElse(mutableListOf()) .groupBy { it.ownerUser?.id ?: 0 } .map { entity -> LeaderBoardAsUserEntryDto( diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardUserController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardUserController.kt index a178edc7..2a93157f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardUserController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/leaderboard/LeaderBoardUserController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.leaderboard -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ButtonAction import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponent.kt index 29f3ac9f..2141eff9 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.location import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["location"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.location"]) class LocationComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponentEntityConfiguration.kt index daa51139..731b538f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.location import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationRepository.kt index eadc3cb6..33925511 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationRepository.kt @@ -12,5 +12,5 @@ interface LocationRepository : CrudRepository, EntityPageDataSource { fun findByUserId(userId: Int): Optional - override fun findAll(): List + override fun findAll(): MutableIterable } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationService.kt index 7793622e..db0b5645 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/LocationService.kt @@ -98,9 +98,9 @@ class LocationService( } } - fun findAllLocation(): List { + fun findAllLocation(): MutableList { return tokenToLocationMapping.values.toList() - .sortedBy { it.groupName } + .sortedBy { it.groupName }.toMutableList() } fun clean() { @@ -191,8 +191,8 @@ class LocationService( override fun deleteAll() = clean() - override fun saveAll(entities: Iterable): Iterable { - return entities.filterNotNull().map { save(it) } + override fun saveAll(entities: MutableIterable): MutableIterable { + return entities.map { save(it) }.toMutableList() } override fun save(entity: S): S { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/RawLocationController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/RawLocationController.kt index 73a46d51..1af3d1d4 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/RawLocationController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/RawLocationController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.location -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ButtonAction import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/TrackOneGroupController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/TrackOneGroupController.kt index 6b9efa12..0f07f471 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/TrackOneGroupController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/TrackOneGroupController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.location -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointController.kt index ffa33d3a..d633b3a9 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.location -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointRepository.kt index 27633800..67aab7dc 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/location/WaypointRepository.kt @@ -10,5 +10,5 @@ import org.springframework.stereotype.Repository interface WaypointRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginComponent.kt index 40bdc5ad..a1088149 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginComponent.kt @@ -5,17 +5,12 @@ import hu.bme.sch.cmsch.component.login.authsch.Scope import hu.bme.sch.cmsch.model.* import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["login"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.login"]) class LoginComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/keycloak/KeycloakUserInfoResponse.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/keycloak/KeycloakUserInfoResponse.kt index c0f975a3..259cefc6 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/keycloak/KeycloakUserInfoResponse.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/keycloak/KeycloakUserInfoResponse.kt @@ -23,4 +23,4 @@ data class KeycloakUserInfoResponse( @set:JsonProperty(required = false) @get:JsonProperty(required = false) var groups: List = mutableListOf(), -) \ No newline at end of file +) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingComponent.kt index e4d80202..41595d4c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingComponent.kt @@ -4,17 +4,12 @@ import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["messaging"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.messaging"]) class MessagingComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingService.kt index 14513663..28941991 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/messaging/MessagingService.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.messaging -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.http.HttpHeaders diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponent.kt index 7a24ab3e..b9a8c3dd 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.news import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["news"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.news"]) class NewsComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponentEntityConfiguration.kt index 4ad6f6e4..5045b6b3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.news import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsController.kt index 4cd72eaf..5d7a92b4 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/news/NewsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.news -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileComponent.kt index 8fb474b3..eff95bed 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.profile import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["profile"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.profile"]) class ProfileComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileService.kt index 9fba327c..7fbf1e51 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/profile/ProfileService.kt @@ -26,8 +26,7 @@ import hu.bme.sch.cmsch.service.TimeService import hu.bme.sch.cmsch.util.isAvailableForRole import hu.bme.sch.cmsch.util.mapIfTrue import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -42,14 +41,12 @@ class ProfileService( private val profileComponent: ProfileComponent, private val debtsRepository: Optional, private val locationService: Optional, - private val groupSelectionComponent: Optional, private val tokenService: Optional, private val tokenComponent: Optional, private val tasksService: Optional, private val riddleService: Optional, private val raceService: Optional, private val loginComponent: Optional, - private val legacyBmejegyService: Optional, private val clock: TimeService, private val startupPropertyConfig: StartupPropertyConfig, private val admissionService: Optional, @@ -232,7 +229,7 @@ class ProfileService( .associate { Pair(it.id, it.name) } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun changeAlias(user: UserEntity, newAlias: String): Boolean { return if (newAlias.matches(Regex(profileComponent.aliasRegex))) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponent.kt index d7083d43..cf84726f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.service.ImplicitPermissions import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["proto"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.proto"]) class ProtoComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponentEntityConfiguration.kt index a43d5220..124eaa71 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.proto import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoController.kt index 8acd6bec..9cc44c9b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/proto/ProtoController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.proto -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/FirebaseMessagingConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/FirebaseMessagingConfiguration.kt index 56bd5d94..01acbe91 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/FirebaseMessagingConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/FirebaseMessagingConfiguration.kt @@ -8,9 +8,9 @@ import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.retry.backoff.BackOffPolicyBuilder -import org.springframework.retry.policy.SimpleRetryPolicy -import org.springframework.retry.support.RetryTemplate +import org.springframework.core.retry.RetryPolicy +import org.springframework.core.retry.RetryTemplate +import java.time.Duration @Configuration @ConditionalOnBean(PushNotificationComponent::class) @@ -47,15 +47,14 @@ class FirebaseMessagingConfiguration { @Bean @ConditionalOnBean(PushNotificationComponent::class) fun retryTemplate(): RetryTemplate { - val retryPolicy = SimpleRetryPolicy(5) - val backOffPolicy = BackOffPolicyBuilder.newBuilder() - .delay(500L) + val retryPolicy = RetryPolicy.builder() + .maxRetries(5) + .delay(Duration.ofMillis(500)) .multiplier(1.5) .build() val template = RetryTemplate() template.setRetryPolicy(retryPolicy) - template.setBackOffPolicy(backOffPolicy) return template } } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponent.kt index 2450dec4..6e69a3a3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.pushnotification import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["pushnotification"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.pushnotification"]) class PushNotificationComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponentEntityConfiguration.kt index c3f3c9fc..4ef337c7 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.pushnotification import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationService.kt index de67b638..473f1ec4 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationService.kt @@ -6,7 +6,7 @@ import hu.bme.sch.cmsch.dto.CmschNotification import hu.bme.sch.cmsch.model.RoleType import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.support.RetryTemplate +import org.springframework.core.retry.RetryTemplate import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -53,7 +53,7 @@ class PushNotificationService( var tokensRemaining = tokens val sendResult = runCatching { - retryTemplate.execute { + retryTemplate.execute { log.debug("Attempting notification broadcast to {} devices...", tokensRemaining.size) // The token limit per multicast message is 500 diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponent.kt index 4e2575cb..95872bc6 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponent.kt @@ -4,17 +4,12 @@ import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["qrFight"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.qrFight"]) class QrFightComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponentEntityConfiguration.kt index 6a4d9114..91f8de93 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.qrfight import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightService.kt index a6c6ded6..265b43f7 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrFightService.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.qrfight -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.addon.indulasch.IndulaschIntegrationService import hu.bme.sch.cmsch.addon.indulasch.IndulaschTextWidgetDto import hu.bme.sch.cmsch.component.login.CmschUser @@ -15,8 +15,7 @@ import hu.bme.sch.cmsch.repository.UserRepository import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -613,7 +612,7 @@ class QrFightService( return completedTokens >= level.minAmountToComplete } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun executeTowerTimer() { log.info("Tower time!") @@ -632,7 +631,7 @@ class QrFightService( tower.holder = state.entries.filter { it.key.isNotBlank() }.maxByOrNull { it.value }?.key ?: "0" tower.holderFor = (state.filter { it.key.isNotBlank() }.maxOfOrNull { it.value } ?: 0) * TIMER_OCCURRENCE tower - } + }.toMutableList() qrTowerRepository.saveAll(updated) log.info("Tower for USER timer executed, and updated {}/{} towers", updated.size, towers.size) } @@ -646,7 +645,7 @@ class QrFightService( tower.holder = state.entries.filter { it.key.isNotBlank() }.maxByOrNull { it.value }?.key ?: "" tower.holderFor = (state.filter { it.key.isNotBlank() }.maxOfOrNull { it.value } ?: 0) * TIMER_OCCURRENCE tower - } + }.toMutableList() qrTowerRepository.saveAll(updated) log.info("Tower for GROUP timer executed, and updated {}/{} towers", updated.size, towers.size) } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelController.kt index d55a9036..18d5e9ce 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.qrfight -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelRepository.kt index 1bb78f24..b810f521 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrLevelRepository.kt @@ -10,7 +10,7 @@ import org.springframework.stereotype.Repository interface QrLevelRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findAllByCategory(category: String): List fun findAllByVisibleTrueAndEnabledTrue(): List } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerController.kt index 9ca920c7..47d54360 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.qrfight -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerRepository.kt index 69fe8063..f7061975 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/qrfight/QrTowerRepository.kt @@ -10,7 +10,7 @@ import org.springframework.stereotype.Repository interface QrTowerRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findAllBySelector(selector: String): List fun findAllByCategory(category: String): List fun findAllByRecordTimeTrue(): List diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordController.kt index b9c21d6e..89dcf7ed 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.race -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.config.OwnershipType import hu.bme.sch.cmsch.config.StartupPropertyConfig import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordRepository.kt index 11f56841..17e634ce 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/FreestyleRaceRecordRepository.kt @@ -10,7 +10,7 @@ import org.springframework.stereotype.Repository interface FreestyleRaceRecordRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findByUserId(userId: Int): FreestyleRaceRecordEntity? } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryController.kt index 6ae942d0..c025ce3f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.race -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryRepository.kt index a2f6bcb4..04e4b3b4 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryRepository.kt @@ -11,7 +11,7 @@ import java.util.* interface RaceCategoryRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findByVisibleTrueAndSlug(category: String): Optional override fun findById(id: Int): Optional fun findAllByVisibleTrue(): List diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryStatController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryStatController.kt index 9b034938..0ae1c1cd 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryStatController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceCategoryStatController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.race -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.config.OwnershipType import hu.bme.sch.cmsch.config.StartupPropertyConfig import hu.bme.sch.cmsch.controller.admin.ControlAction diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponent.kt index cb938d4a..64aca59e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* import hu.bme.sch.cmsch.util.isAvailableForRole -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["race"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.race"]) class RaceComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponentEntityConfiguration.kt index 6270e60e..1b9bfb13 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.race import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceLeaderBoardController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceLeaderBoardController.kt index 537835b0..3966027a 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceLeaderBoardController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceLeaderBoardController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.race -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.config.OwnershipType import hu.bme.sch.cmsch.config.StartupPropertyConfig import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage @@ -37,11 +37,11 @@ class RaceLeaderBoardController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableList { return when (startupPropertyConfig.raceOwnershipMode) { OwnershipType.USER -> raceService.getBoardForUsers(DEFAULT_CATEGORY, true) OwnershipType.GROUP -> raceService.getBoardForGroups(DEFAULT_CATEGORY) - } + }.toMutableList() } override fun count() = findAll().count().toLong() diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordController.kt index f7550e04..5878da0b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.race -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.config.OwnershipType import hu.bme.sch.cmsch.config.StartupPropertyConfig import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordRepository.kt index 6e88a754..4064f2ae 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/race/RaceRecordRepository.kt @@ -10,7 +10,7 @@ import org.springframework.stereotype.Repository interface RaceRecordRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findAllByCategory(category: String): List diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleBusinessLogicService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleBusinessLogicService.kt index dca297d5..f8b72e3d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleBusinessLogicService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleBusinessLogicService.kt @@ -4,8 +4,7 @@ import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.service.TimeService import hu.bme.sch.cmsch.service.UserService import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Propagation @@ -128,7 +127,7 @@ class RiddleBusinessLogicService( ) } - @Retryable(value = [SQLException::class], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [SQLException::class], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) override fun unlockHintForUser(user: CmschUser, riddleId: Int): String? { val riddle = riddleCacheManager.getRiddleById(riddleId) ?: return null @@ -153,7 +152,7 @@ class RiddleBusinessLogicService( return riddle.hint } - @Retryable(value = [SQLException::class], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [SQLException::class], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) override fun unlockHintForGroup(user: CmschUser, groupId: Int?, groupName: String, riddleId: Int): String? { if (groupId == null) @@ -180,7 +179,7 @@ class RiddleBusinessLogicService( return riddle.hint } - @Retryable(value = [SQLException::class], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [SQLException::class], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW) override fun submitRiddleForUser( user: CmschUser, @@ -257,7 +256,7 @@ class RiddleBusinessLogicService( } } - @Retryable(value = [SQLException::class], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [SQLException::class], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW) override fun submitRiddleForGroup( user: CmschUser, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCacheManager.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCacheManager.kt index 3156d905..a50a0183 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCacheManager.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCacheManager.kt @@ -5,8 +5,7 @@ import hu.bme.sch.cmsch.model.RoleType import jakarta.annotation.PostConstruct import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation @@ -59,7 +58,7 @@ class RiddleCacheManager( resetCache(persistMapping = false, overrideMappings = true) } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW) fun resetCache(persistMapping: Boolean, overrideMappings: Boolean) { log.info("Getting all locks for 'resetCache({}, {})'", persistMapping, overrideMappings) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCategoryController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCategoryController.kt index e207eb55..abbe4918 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCategoryController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleCategoryController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.riddle -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponent.kt index d17f3a2e..fe6b181f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponent.kt @@ -4,17 +4,12 @@ import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.component.race.RaceCategoryEntity import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["riddle"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.riddle"]) class RiddleComponent( private val riddleModerationService: RiddleModerationService, componentSettingService: ComponentSettingService, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponentEntityConfiguration.kt index 89827083..b5909591 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.riddle import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleController.kt index f6ae719c..f0d25c5b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.riddle -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleEntityRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleEntityRepository.kt index f11a9254..554353ce 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleEntityRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddleEntityRepository.kt @@ -10,6 +10,6 @@ import org.springframework.stereotype.Repository interface RiddleEntityRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlePersistenceService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlePersistenceService.kt index 97c43f32..75ba8ad0 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlePersistenceService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlePersistenceService.kt @@ -1,8 +1,7 @@ package hu.bme.sch.cmsch.component.riddle import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Propagation @@ -16,7 +15,7 @@ class RiddlePersistenceService( private val riddleMappingRepository: RiddleMappingRepository, ) { - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW) fun saveAllRiddleMapping(entities: MutableIterable) { riddleMappingRepository.saveAll(entities) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByGroupsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByGroupsController.kt index ae8524d5..50b49f8d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByGroupsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByGroupsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.riddle -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.ImportFormat import hu.bme.sch.cmsch.admin.OverviewBuilder import hu.bme.sch.cmsch.controller.admin.ButtonAction @@ -47,7 +47,7 @@ class RiddlesByGroupsController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { return transactionManager.transaction(readOnly = true) { riddleMappingRepository.findAll() } .groupBy { it.ownerGroupId } .map { it.value } @@ -60,7 +60,7 @@ class RiddlesByGroupsController( submissions.count { it.completed }, submissions.count { it.hintUsed } ) - } + }.toMutableList() } override fun delete(entity: RiddleStatsVirtualEntity) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByUsersController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByUsersController.kt index 7c3cbc85..45dd0755 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByUsersController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/riddle/RiddlesByUsersController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.riddle -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.repository.ManualRepository import hu.bme.sch.cmsch.repository.UserRepository @@ -37,7 +37,7 @@ class RiddlesByUsersController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { return transactionManager.transaction(readOnly = true) { riddleMappingRepository.findAll() } .groupBy { it.ownerUserId } .map { it.value } @@ -50,7 +50,7 @@ class RiddlesByUsersController( submissions.count { it.completed }, submissions.count { it.hintUsed } ) - } + }.toMutableList() } override fun delete(entity: RiddleStatsVirtualEntity) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponent.kt index 3d4f1a3f..75c1defe 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["script"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.script"]) class ScriptComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponentEntityConfiguration.kt index 3c56129d..47a83672 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.script import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptController.kt index d99659c9..cc90a320 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.script -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptEntity.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptEntity.kt index b6e074fe..ed331889 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptEntity.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptEntity.kt @@ -83,4 +83,4 @@ data class ScriptEntity( return "id = $id, name = $name" } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptResultController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptResultController.kt index bf077452..7eb4fe02 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptResultController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptResultController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.script -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ButtonAction import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptRunnerDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptRunnerDashboard.kt index ba908c19..426dfb17 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptRunnerDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptRunnerDashboard.kt @@ -52,7 +52,7 @@ class ScriptRunnerDashboard( ignoreFromMenu = true ) { - private final val log = LoggerFactory.getLogger(javaClass) + private val log = LoggerFactory.getLogger(javaClass) override fun getComponents(user: CmschUser, requestParams: Map): List { return listOf() diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptService.kt index 0c0175e4..305dc2c2 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptService.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.script -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.component.script.sandbox.* import hu.bme.sch.cmsch.model.Duplicatable @@ -31,7 +31,7 @@ class ScriptService( private val transactionManager: PlatformTransactionManager ) { - private final val log = LoggerFactory.getLogger(javaClass) + private val log = LoggerFactory.getLogger(javaClass) private final val objectMapper = jacksonObjectMapper() private final val artifactWriter = objectMapper.writerFor(object : TypeReference>() {}) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptTestConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptTestConfiguration.kt index 897b6317..7bf33e1c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptTestConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptTestConfiguration.kt @@ -3,7 +3,7 @@ package hu.bme.sch.cmsch.component.script import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Profile -import javax.annotation.PostConstruct +import jakarta.annotation.PostConstruct @Configuration @ConditionalOnBean(ScriptComponent::class) @@ -182,4 +182,4 @@ class ScriptTestConfiguration( } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptsLogsDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptsLogsDashboard.kt index 50fa843f..86480444 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptsLogsDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/ScriptsLogsDashboard.kt @@ -1,12 +1,6 @@ package hu.bme.sch.cmsch.component.script import com.fasterxml.jackson.annotation.JsonView -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.MappingIterator -import com.fasterxml.jackson.dataformat.csv.CsvMapper -import com.fasterxml.jackson.dataformat.csv.CsvParser -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.script.sandbox.ScriptArtifact import hu.bme.sch.cmsch.dto.Edit import hu.bme.sch.cmsch.service.AdminMenuService @@ -19,7 +13,15 @@ import org.springframework.security.core.Authentication import org.springframework.stereotype.Controller import org.springframework.transaction.PlatformTransactionManager import org.springframework.ui.Model -import org.springframework.web.bind.annotation.* +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.ResponseBody +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.MappingIterator +import tools.jackson.dataformat.csv.CsvMapper +import tools.jackson.dataformat.csv.CsvReadFeature +import tools.jackson.dataformat.csv.CsvSchema +import tools.jackson.module.kotlin.jacksonObjectMapper import kotlin.jvm.optionals.getOrNull @@ -37,7 +39,8 @@ class ScriptsLogsDashboard( private final val showPermission = StaffPermissions.PERMISSION_SHOW_SCRIPTS private final val editPermission = StaffPermissions.PERMISSION_EDIT_SCRIPTS private final val view = "script-logs" - private final val artifactReader = jacksonObjectMapper().readerFor(object : TypeReference>() {}) + private final val artifactReader = + jacksonObjectMapper().readerFor(object : TypeReference>() {}) @GetMapping("/admin/control/script-logs/{scriptResultId}") fun viewScript(model: Model, @PathVariable scriptResultId: Int, auth: Authentication): String { @@ -110,7 +113,8 @@ class ScriptsLogsDashboard( model.addAttribute("scriptResultId", scriptResultId) if (scriptResultEntity != null) { - val artifact = artifactReader.readValue>(scriptResultEntity.artifacts).getOrNull(artifactId) + val artifact = + artifactReader.readValue>(scriptResultEntity.artifacts).getOrNull(artifactId) model.addAttribute("name", artifact?.artifactName) if (artifact?.type?.lowercase()?.trim() == "text/csv") { @@ -131,8 +135,9 @@ class ScriptsLogsDashboard( } final fun loadCsvAsList(csv: String): List> { - val mapper = CsvMapper() - mapper.enable(CsvParser.Feature.WRAP_AS_ARRAY) + val mapper = CsvMapper.builder() + .enable(CsvReadFeature.WRAP_AS_ARRAY) + .build() val schema = CsvSchema.emptySchema() val rows: MappingIterator> = mapper.readerFor(Array::class.java) @@ -142,4 +147,4 @@ class ScriptsLogsDashboard( return rows.asSequence().map { row -> row.toList() }.toList() } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingContext.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingContext.kt index 98d7ad10..eefc2ec9 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingContext.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingContext.kt @@ -134,7 +134,7 @@ class ReadOnlyScriptingDbContext(private val supportedRepos: List(private val proxy: CrudRepository) { fun findAll(): List { - return proxy.findAll().mapNotNull { if (it is T) { it.duplicate() as T } else null }.toList() + return proxy.findAll().mapNotNull { it.duplicate() as T }.toList() } fun findById(id: ID): T? { @@ -159,4 +159,4 @@ class ModifyingScriptingComponentContext( ?: error("Cannot find component for $selectedComponent") } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingCsvUtil.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingCsvUtil.kt index cc6ee320..f0e4f75b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingCsvUtil.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingCsvUtil.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.script.sandbox -import com.fasterxml.jackson.dataformat.csv.CsvMapper -import com.fasterxml.jackson.dataformat.csv.CsvSchema +import tools.jackson.dataformat.csv.CsvMapper +import tools.jackson.dataformat.csv.CsvSchema class ScriptingCsvUtil { @@ -39,4 +39,4 @@ class ScriptingCsvUtil { .writeValueAsString(content) } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingJsonUtil.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingJsonUtil.kt index 04d42657..c3fd36c5 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingJsonUtil.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/script/sandbox/ScriptingJsonUtil.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.script.sandbox -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.module.kotlin.jacksonObjectMapper class ScriptingJsonUtil { @@ -12,4 +12,4 @@ class ScriptingJsonUtil { return jacksonObjectMapper().writeValueAsString(value) } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponent.kt index 8abaf20f..843d595c 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponent.kt @@ -5,17 +5,12 @@ import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ImplicitPermissions import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["service-account"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.service-account"]) class ServiceAccountComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponentConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponentConfiguration.kt index 50da1793..db723a3b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponentConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountComponentConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.serviceaccount import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountKeyController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountKeyController.kt index a48c9fce..29e57b15 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountKeyController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/serviceaccount/ServiceAccountKeyController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.serviceaccount -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponent.kt index 02db2e0b..72a6a37d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponent.kt @@ -7,18 +7,13 @@ import hu.bme.sch.cmsch.service.ImplicitPermissions import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["sheets"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.sheets"]) class SheetsComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponentEntityConfiguration.kt index ea79f32a..d92611bf 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsComponentEntityConfiguration.kt @@ -1,10 +1,10 @@ package hu.bme.sch.cmsch.component.sheets import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration @ConditionalOnBean(SheetsComponent::class) @EntityScan(basePackageClasses = [SheetsComponent::class]) -class SheetsComponentEntityConfiguration \ No newline at end of file +class SheetsComponentEntityConfiguration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsController.kt index 486f1f73..34fef9ac 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.sheets -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsFormsListener.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsFormsListener.kt index 8ac3f622..b9151ba8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsFormsListener.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsFormsListener.kt @@ -1,9 +1,9 @@ package hu.bme.sch.cmsch.component.sheets -import com.fasterxml.jackson.core.JacksonException -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectReader -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.JacksonException +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectReader +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.form.FormElement import hu.bme.sch.cmsch.component.form.FormEntity import hu.bme.sch.cmsch.component.form.ResponseEntity diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsSetupWizard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsSetupWizard.kt index 8fff014b..c0f83470 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsSetupWizard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsSetupWizard.kt @@ -1,8 +1,8 @@ package hu.bme.sch.cmsch.component.sheets -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectReader -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectReader +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.admin.dashboard.* import hu.bme.sch.cmsch.component.form.FormElement import hu.bme.sch.cmsch.component.form.FormElementType diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsUpdaterService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsUpdaterService.kt index e5feec98..ad06f3d4 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsUpdaterService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/sheets/SheetsUpdaterService.kt @@ -1,9 +1,9 @@ package hu.bme.sch.cmsch.component.sheets -import com.fasterxml.jackson.core.JacksonException -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectReader -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.JacksonException +import tools.jackson.core.type.TypeReference +import tools.jackson.databind.ObjectReader +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.form.FormElement import hu.bme.sch.cmsch.component.form.FormRepository import hu.bme.sch.cmsch.component.form.ResponseRepository @@ -30,7 +30,7 @@ class SheetsUpdaterService( private val responseRepository: ResponseRepository ) { - private final val log = LoggerFactory.getLogger(javaClass) + private val log = LoggerFactory.getLogger(javaClass) private final val objectMapper = jacksonObjectMapper() private final val sheetsUpdateRequestWriter = objectMapper.writerFor(SheetsUpdateRequest::class.java) private final val sheetsUpdateResponseReader = objectMapper.readerFor(SheetsUpdateResponse::class.java) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponent.kt index fc1f2ed9..32a35475 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.service.ImplicitPermissions import hu.bme.sch.cmsch.setting.ComponentSettingService import hu.bme.sch.cmsch.setting.MinRoleSettingRef import hu.bme.sch.cmsch.setting.SettingGroup -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["staticPage"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.staticPage"]) class StaticPageComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponentEntityConfiguration.kt index b45de957..ed8dd332 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.staticpage import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageController.kt index 35a08ce8..9c09bb22 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/staticpage/StaticPageController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.staticpage -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/CheckRatingsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/CheckRatingsController.kt index 09427c20..3f686401 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/CheckRatingsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/CheckRatingsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.task -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.dto.virtual.CheckRatingVirtualEntity import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/SubmittedTaskController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/SubmittedTaskController.kt index b0cb1ad6..97a2a0f8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/SubmittedTaskController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/SubmittedTaskController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.task -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.ImportFormat import hu.bme.sch.cmsch.admin.OverviewBuilder import hu.bme.sch.cmsch.controller.admin.ButtonAction diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskAdminRateController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskAdminRateController.kt index 943d5cd5..3e8fbb19 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskAdminRateController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskAdminRateController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.task -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.INVALID_ID_ERROR import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage @@ -42,7 +42,7 @@ class TaskAdminRateController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { val aggregatedResults = submittedRepository.findAllAggregated() return aggregatedResults.map { @@ -53,7 +53,7 @@ class TaskAdminRateController( it.rejectedCount.toInt(), it.notGradedCount.toInt() ) - }.sortedByDescending { it.notGraded }.toList() + }.sortedByDescending { it.notGraded }.toMutableList() } }, submittedRepository, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryController.kt index 61678abb..dc361c4b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.task -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryRepository.kt index c3497f60..c5bf953d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskCategoryRepository.kt @@ -10,7 +10,7 @@ import org.springframework.stereotype.Repository interface TaskCategoryRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findAllByAvailableFromLessThanAndAvailableToGreaterThan(availableFrom: Long, availableTo: Long): List fun findAllByCategoryId(categoryId: Int): List fun findAllByType(type: TaskCategoryType): List diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponent.kt index cd11fbc6..8a83544e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.task import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["task"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.task"]) class TaskComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponentEntityConfiguration.kt index c1d14664..1577081a 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.task import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskController.kt index 0edced82..58c4dfeb 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.task -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskDiscOptimizerDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskDiscOptimizerDashboard.kt deleted file mode 100644 index 9a869939..00000000 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TaskDiscOptimizerDashboard.kt +++ /dev/null @@ -1,205 +0,0 @@ -package hu.bme.sch.cmsch.component.task - -import com.google.common.util.concurrent.ThreadFactoryBuilder -import hu.bme.sch.cmsch.admin.dashboard.* -import hu.bme.sch.cmsch.component.app.ApplicationComponent -import hu.bme.sch.cmsch.component.login.CmschUser -import hu.bme.sch.cmsch.config.StartupPropertyConfig -import hu.bme.sch.cmsch.service.AdminMenuService -import hu.bme.sch.cmsch.service.AuditLogService -import hu.bme.sch.cmsch.service.FilesystemStorageService -import hu.bme.sch.cmsch.service.ImplicitPermissions -import hu.bme.sch.cmsch.util.getUser -import org.slf4j.LoggerFactory -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.security.core.Authentication -import org.springframework.stereotype.Controller -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestParam -import java.io.File -import java.nio.file.Files -import java.nio.file.Path -import java.util.concurrent.Executors -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicReference -import java.util.concurrent.atomic.LongAdder -import javax.imageio.ImageIO - -private const val VIEW = "task-disc-optimize" - -@Controller -@RequestMapping("/admin/control/$VIEW") -@ConditionalOnBean(value = [TaskComponent::class, FilesystemStorageService::class]) -class TaskDiscOptimizerDashboard( - adminMenuService: AdminMenuService, - applicationComponent: TaskComponent, - auditLogService: AuditLogService, - private val startupPropertyConfig: StartupPropertyConfig, - private val imageRescaleService: TaskImageRescaleService -) : DashboardPage( - view = VIEW, - title = "Disc Optimizer", - description = "", - wide = false, - adminMenuService = adminMenuService, - component = applicationComponent, - auditLog = auditLogService, - showPermission = ImplicitPermissions.PERMISSION_SUPERUSER_ONLY, - adminMenuCategory = ApplicationComponent.DEVELOPER_CATEGORY, - adminMenuIcon = "delete", - adminMenuPriority = 21 -) { - - companion object { - @JvmStatic - val lock = Any() - } - - private val log = LoggerFactory.getLogger(javaClass) - - internal val processStatus = AtomicReference("nincs exportálva") - internal val processCount = LongAdder() - internal val processReduction = LongAdder() - internal val processRunning = AtomicBoolean(false) - - private val threadFactory = ThreadFactoryBuilder() - .setUncaughtExceptionHandler { _, e -> - log.error("Uncaught exception during Souvenir export", e) - processStatus.set("Error: ${e.message}") - } - .setNameFormat("optimizer-pool-%d") - .build() - private val executorService = Executors.newThreadPerTaskExecutor(threadFactory) - - override fun getComponents(user: CmschUser, requestParams: Map): List { - return listOf( - exportStatus(), - exportPanel(), - permissionCard - ) - } - - private fun exportStatus(): DashboardTableCard { - return DashboardTableCard( - id = 2, - title = "Optimalizálás eredménye", - description = "Ha üres, akkor még nem volt optimalizálva", - header = listOf("Kulcs", "Érték"), - content = listOf( - listOf("Exportálás folyamatban", if (processRunning.get()) "igen" else "nem"), - listOf("Exportálás státusza", processStatus.get()), - listOf("Counter", processCount.sum().toString()), - listOf("Spórolás (byte)", processReduction.sum().toString()), - ), - wide = wide, - exportable = false - ) - } - - fun exportPanel(): DashboardFormCard { - return DashboardFormCard( - id = 3, - wide = wide, - title = "Optimalizálás indítása", - description = "", - content = listOf( - ), - buttonCaption = "Indítás", - buttonIcon = "play_arrow", - action = "optimize", - method = "post", - multipartForm = false, - ) - } - - @PostMapping("/optimize") - fun optimize(auth: Authentication, @RequestParam allRequestParams: Map): String { - val user = auth.getUser() - if (!showPermission.validate(user)) { - throw IllegalStateException("Insufficient permissions") - } - - synchronized(lock) { - if (processRunning.get()) - return dashboardPage(view = VIEW, card = 2, message = "Már fut exportálás") - processRunning.set(true) - executorService.submit(TaskImageOptimizerTask( - processStatus = processStatus, - processRunning = processRunning, - processCount = processCount, - processReduction = processReduction, - startupPropertyConfig = startupPropertyConfig, - imageRescaleService = imageRescaleService, - )) - } - - return dashboardPage(view = VIEW, card = 2, message = "Exportálás beütemezve") - } - - - private val permissionCard = DashboardPermissionCard( - id = 1, - permission = showPermission.permissionString, - description = "Ez a jog szükséges ennek az oldalnak az olvasásához.", - wide = false - ) - -} - -class TaskImageOptimizerTask( - private val processStatus: AtomicReference, - private val processRunning: AtomicBoolean, - private val processCount: LongAdder, - private val processReduction: LongAdder, - private val startupPropertyConfig: StartupPropertyConfig, - - private val imageRescaleService: TaskImageRescaleService, -) : Runnable { - - override fun run() { - processStatus.set("Optimizer elindult") - - Files.walk(Path.of(startupPropertyConfig.filesystemStoragePath, "task")) - .filter { - val fileName = it.fileName.toString().lowercase() - val image = fileName.endsWith(".png") || fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") - println("$fileName $image") - return@filter image - } - .forEach { !resizeImage(it.toFile()) } - - processStatus.set("Optimizer kész") - processRunning.set(false) - } - - private fun resizeImage(inputFile: File): Boolean { - processCount.increment() - val oldLength = inputFile.length() - println("RESCALE $inputFile $oldLength") - val MAX_HEIGHT_WIDTH = 1000 - - val kiloByte = 1024 - if (inputFile.length() > (120 * kiloByte)) { - val inputImage = ImageIO.read(inputFile) - if (inputImage.height > (MAX_HEIGHT_WIDTH + 1) || inputImage.width > (MAX_HEIGHT_WIDTH + 1)) { - val resizedImage = imageRescaleService.resizeImage(inputImage, MAX_HEIGHT_WIDTH, MAX_HEIGHT_WIDTH) - val format = inputFile.name.substringAfterLast(".").lowercase() - println(" - FORMAT: $format") - - ImageIO.write(resizedImage, format, inputFile) - val newLength = inputFile.length() - val diff = oldLength - newLength - println(" - NEW LENGTH: $newLength DIFF: $diff") - processReduction.add(diff) - return true - } - println(" - SMALL ENOUGH by scale") - return false - } else { - println(" - SMALL ENOUGH by volume") - return false - } - } - -} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TasksService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TasksService.kt index 3ea66506..dd227c6b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TasksService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/task/TasksService.kt @@ -10,8 +10,7 @@ import hu.bme.sch.cmsch.service.StorageService import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -117,7 +116,7 @@ class TasksService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun submitTaskReview( taskId: Int, @@ -173,7 +172,7 @@ class TasksService( return true } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun submitTaskForGroup(answer: TaskSubmissionDto, file: MultipartFile?, user: CmschUser): TaskSubmissionStatus { val groupId = user.groupId diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponent.kt index 494b2573..7e0486df 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponent.kt @@ -6,17 +6,12 @@ import hu.bme.sch.cmsch.model.RoleType import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* import hu.bme.sch.cmsch.util.isAvailableForRole -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["team"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.team"]) class TeamComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponentEntityConfiguration.kt index f682a958..f0dfafa7 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamComponentEntityConfiguration.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.team -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamController.kt index 26a30926..a5cda167 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.team -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamIntroductionReviewController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamIntroductionReviewController.kt index 80d02b50..cef8008b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamIntroductionReviewController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamIntroductionReviewController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.team -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelController.kt index 7fdb6510..3f71368b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.team -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.ControlAction import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.model.GroupEntity @@ -75,4 +75,4 @@ class TeamLabelController( return true } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelEntity.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelEntity.kt index 4305f521..5386f7df 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelEntity.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamLabelEntity.kt @@ -81,4 +81,4 @@ data class TeamLabelEntity( override fun getEntityConfig(env: Environment) = null -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamService.kt index 28646d34..076bb361 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/team/TeamService.kt @@ -20,8 +20,7 @@ import hu.bme.sch.cmsch.service.StorageService import hu.bme.sch.cmsch.service.TimeService import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -57,7 +56,7 @@ class TeamService( private val log = LoggerFactory.getLogger(javaClass) - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun createTeam(user: UserEntity, name: String): TeamCreationStatus { if (user.group?.leaveable == false) @@ -117,7 +116,7 @@ class TeamService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun joinTeam(user: UserEntity, groupId: Int): TeamJoinStatus { if (user.group?.leaveable == false) @@ -141,7 +140,7 @@ class TeamService( return TeamJoinStatus.OK } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun cancelJoin(user: CmschUser): TeamJoinStatus { if (!teamComponent.joinEnabled) @@ -152,7 +151,7 @@ class TeamService( return TeamJoinStatus.OK } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun leaveTeam(user: CmschUser): TeamLeaveStatus { if (!teamComponent.leaveEnabled) @@ -410,7 +409,7 @@ class TeamService( .map { TeamMemberView(it.userName, it.userId, isAdmin = false, isYou = false) } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun acceptJoin(userId: Int, group: GroupEntity?): Boolean { if (group == null) @@ -437,7 +436,7 @@ class TeamService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun rejectJoin(userId: Int, groupId: Int?, groupName: String): Boolean { if (groupId == null) @@ -452,7 +451,7 @@ class TeamService( return false } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun toggleUserPermissions(userId: Int, groupId: Int?, groupName: String, adminUser: CmschUser): Boolean { if (groupId == null) @@ -495,7 +494,7 @@ class TeamService( } } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun promoteLeader(userId: Int, groupId: Int?, groupName: String, adminUser: CmschUser): Boolean { if (groupId == null) @@ -537,7 +536,7 @@ class TeamService( return true } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun kickUser(userId: Int, groupId: Int?, groupName: String, adminUser: CmschUser): Boolean { if (groupId == null) @@ -577,7 +576,7 @@ class TeamService( log.info("User '{}' kicked from '{}', reason: by admin '{}'", user.fullName, groupName, adminUser.userName) return true } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun setDescriptionAndLogo(description: String, logo: MultipartFile?, user: CmschUser): TeamEditStatus { val groupId = user.groupId ?: throw IllegalStateException("The user is not member of a group yet") diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/BulkTokenGeneratorDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/BulkTokenGeneratorDashboard.kt index c936ca96..90287d5a 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/BulkTokenGeneratorDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/BulkTokenGeneratorDashboard.kt @@ -155,11 +155,11 @@ class BulkTokenGeneratorDashboard( availableFrom = timeService.getTimeInSeconds(), availableUntil = timeService.getTimeInSeconds() + (dateUntil * 24 * 60 * 60), ) - }) + }.toMutableList()) return@transaction result.count() } return dashboardPage(VIEW, 2, "${n}db token beszúrva") } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByGroupController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByGroupController.kt index a992a6e0..0e4f9ba4 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByGroupController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByGroupController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.repository.GroupRepository import hu.bme.sch.cmsch.repository.ManualRepository @@ -41,7 +41,7 @@ class TokenAdminTokensByGroupController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { return repo.findAll() .groupBy { it.ownerGroup?.id ?: 0 } .map { it.value } @@ -53,7 +53,7 @@ class TokenAdminTokensByGroupController( groupName, token.count() ) - } + }.toMutableList() } override fun delete(entity: TokenListByGroupVirtualEntity) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTeamController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTeamController.kt index 1e33859f..7d5c0990 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTeamController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTeamController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.repository.ManualRepository import hu.bme.sch.cmsch.repository.UserRepository @@ -41,13 +41,13 @@ class TokenAdminTokensByTeamController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { transactionManager.transaction(readOnly = true) { val data = repo.countByAllUserGroup() data.forEach { it.memberCount = userRepository.findAllByGroupName(it.groupName).size } val highestTeamMemberCount = data.maxByOrNull { it.correctedPoints }?.memberCount ?: 0 data.forEach { it.finalPoints = (it.correctedPoints * highestTeamMemberCount).toInt() } - return data + return data.toMutableList() } } }, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTypeController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTypeController.kt index 5f0d4c55..2e064fe8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTypeController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByTypeController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.repository.ManualRepository import hu.bme.sch.cmsch.service.* @@ -32,7 +32,7 @@ class TokenAdminTokensByTypeController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableIterable { return repo.findAll() .groupBy { it.token?.id } .map { it.value } @@ -44,7 +44,7 @@ class TokenAdminTokensByTypeController( tokenProperty[0].token?.type ?: "n/a", tokenProperty.count() ) - } + }.toMutableList() } override fun delete(entity: TokenStatVirtualEntity) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersController.kt index d531302e..92a99510 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.TwoDeepEntityPage import hu.bme.sch.cmsch.repository.GroupRepository import hu.bme.sch.cmsch.repository.ManualRepository @@ -34,7 +34,7 @@ class TokenAdminTokensByUsersController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { + override fun findAll(): MutableList { return repo.findAll() .groupBy { it.ownerUser?.id ?: 0 } .map { it.value } @@ -47,7 +47,7 @@ class TokenAdminTokensByUsersController( groupName, tokenProperty.count() ) - } + }.toMutableList() } override fun delete(entity: TokenListByUserVirtualEntity) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersOfGroupsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersOfGroupsController.kt index 623c4650..bf9e3a51 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersOfGroupsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenAdminTokensByUsersOfGroupsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import com.itextpdf.io.image.ImageDataFactory import com.itextpdf.kernel.font.PdfFont import com.itextpdf.kernel.font.PdfFontFactory diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenCollectorService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenCollectorService.kt index be2ca29c..375ba2c5 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenCollectorService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenCollectorService.kt @@ -10,8 +10,7 @@ import hu.bme.sch.cmsch.repository.GroupRepository import hu.bme.sch.cmsch.service.TimeService import hu.bme.sch.cmsch.service.UserService import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -35,7 +34,7 @@ class TokenCollectorService( private val qrFightComponent: Optional ) { - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun collectToken(user: CmschUser, token: String): TokenSubmittedView { val tokenEntity = tokenRepository.findAllByTokenAndVisibleTrue(token).firstOrNull() @@ -59,7 +58,7 @@ class TokenCollectorService( return TokenSubmittedView(TokenCollectorStatus.WRONG, null, null, null) } - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) fun collectTokenForGroup(user: CmschUser, token: String): TokenSubmittedView { val groupEntity = user.groupId?.let { groupId -> groupRepository.findById(groupId).getOrNull() } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponent.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponent.kt index 132c3dc4..7ae156a8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponent.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponent.kt @@ -3,17 +3,12 @@ package hu.bme.sch.cmsch.component.token import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.setting.* -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.core.env.Environment import org.springframework.stereotype.Service @Service -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["token"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.token"]) class TokenComponent( componentSettingService: ComponentSettingService, env: Environment diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponentEntityConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponentEntityConfiguration.kt index ff9c4bc9..720207d6 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponentEntityConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenComponentEntityConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.component.token import org.springframework.boot.autoconfigure.condition.ConditionalOnBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Configuration @Configuration diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenController.kt index d3122cb8..cdfb9113 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.controller.admin.ButtonAction import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyController.kt index 149c86a6..7e7a256a 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings import hu.bme.sch.cmsch.repository.ManualRepository @@ -33,8 +33,8 @@ class TokenSubmissionsController( transactionManager, object : ManualRepository() { - override fun findAll(): Iterable { - return repo.findAll().map { mapTokenProperty(it) } + override fun findAll(): MutableIterable { + return repo.findAll().map { mapTokenProperty(it) }.toMutableList() } override fun count(): Long { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyRepository.kt index 6e7dafb5..5ff15376 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPropertyRepository.kt @@ -13,7 +13,7 @@ import java.util.* interface TokenPropertyRepository : CrudRepository, EntityPageDataSource { - override fun findAll(): List + override fun findAll(): MutableIterable fun findAllByOwnerUser_Id(owner: Int): List diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPublicTokensStatsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPublicTokensStatsController.kt index ec48544d..28f953d0 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPublicTokensStatsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenPublicTokensStatsController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.component.token -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.login.LoginComponent import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.service.* diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/AppConfig.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/AppConfig.kt index 2472f078..685230ce 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/AppConfig.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/AppConfig.kt @@ -1,8 +1,6 @@ package hu.bme.sch.cmsch.config import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.registerKotlinModule import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.convert.TypeDescriptor @@ -13,6 +11,9 @@ import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator import org.springframework.security.oauth2.core.OAuth2TokenValidator import org.springframework.security.oauth2.core.converter.ClaimConversionService import org.springframework.security.oauth2.jwt.* +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.json.JsonMapper +import tools.jackson.module.kotlin.kotlinModule import java.net.URI import java.net.URL import java.util.* @@ -24,10 +25,10 @@ class AppConfig { @Bean fun objectMapper(): ObjectMapper { - val objectMapper = ObjectMapper() - objectMapper.registerKotlinModule() - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL) - return objectMapper + return JsonMapper.builder() + .addModule(kotlinModule { }) + .changeDefaultPropertyInclusion { it.withValueInclusion(JsonInclude.Include.NON_NULL) } + .build() } @Bean @@ -43,7 +44,7 @@ class AppConfig { } try { return URI("https://$source").toURL() - } catch (ex: Exception) { + } catch (_: Exception) { // Ignore } return null diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt index d1019a0a..538d713b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.config -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.countdown.CountdownFilterConfigurer import hu.bme.sch.cmsch.component.login.LoginComponent import hu.bme.sch.cmsch.component.login.LoginService @@ -17,14 +17,11 @@ import hu.bme.sch.cmsch.service.AuditLogService import hu.bme.sch.cmsch.service.JwtTokenProvider import hu.bme.sch.cmsch.service.StorageService import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.core.Ordered import org.springframework.http.HttpHeaders import org.springframework.http.MediaType -import org.springframework.retry.annotation.EnableRetry import org.springframework.security.config.Customizer import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity @@ -40,7 +37,6 @@ import java.util.* @EnableWebSecurity @Configuration -@EnableRetry(order = Ordered.HIGHEST_PRECEDENCE) @ConditionalOnBean(LoginComponent::class) class SecurityConfig( private val clientRegistrationRepository: ClientRegistrationRepository, @@ -51,7 +47,6 @@ class SecurityConfig( private val authschLoginService: LoginService, private val loginComponent: LoginComponent, private val startupPropertyConfig: StartupPropertyConfig, - @param:Value("\${custom.keycloak.base-url:http://localhost:8081/auth/realms/master}") private val keycloakBaseUrl: String, private val auditLogService: AuditLogService ) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/ServerSideErrorController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/ServerSideErrorController.kt index fc34a548..cb99d3e2 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/ServerSideErrorController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/ServerSideErrorController.kt @@ -5,7 +5,7 @@ import hu.bme.sch.cmsch.util.getUserOrNull import jakarta.servlet.RequestDispatcher import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse -import org.springframework.boot.web.servlet.error.ErrorController +import org.springframework.boot.webmvc.error.ErrorController import org.springframework.security.core.Authentication import org.springframework.stereotype.Controller import org.springframework.ui.Model diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/TestController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/TestController.kt index eb951d7c..6099d14b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/TestController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/TestController.kt @@ -3,18 +3,13 @@ package hu.bme.sch.cmsch.controller import hu.bme.sch.cmsch.service.UserService import hu.bme.sch.cmsch.util.getUserEntityFromDatabaseOrNull import org.slf4j.LoggerFactory -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.security.core.Authentication import org.springframework.stereotype.Controller import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.ResponseBody -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["test"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.test"]) @Controller class TestController(private val userService: UserService) { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/BasicAdminController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/BasicAdminController.kt index 5b8716f9..7f334b6b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/BasicAdminController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/BasicAdminController.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.controller.admin -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.component.app.ApplicationComponent import hu.bme.sch.cmsch.component.staticpage.StaticPageService import hu.bme.sch.cmsch.service.AdminMenuCategory diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/OneDeepEntityPage.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/OneDeepEntityPage.kt index 742c5503..fa1cfaf8 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/OneDeepEntityPage.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/OneDeepEntityPage.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.controller.admin import com.fasterxml.jackson.annotation.JsonIgnore -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.* import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.component.login.CmschUser diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SettingsController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SettingsController.kt index 516bbcb7..68906292 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SettingsController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SettingsController.kt @@ -72,10 +72,12 @@ class SettingsController( auth.getUser().refresh(user) adminMenuService.invalidateUser(user.internalId) - SecurityContextHolder.getContext().authentication = UsernamePasswordAuthenticationToken( - auth.principal, auth.credentials, - mutableListOf(SimpleGrantedAuthority("ROLE_${user.role.name}")) - ) + SecurityContextHolder.getContext().authentication = auth.principal?.let { + UsernamePasswordAuthenticationToken( + it, auth.credentials, + mutableListOf(SimpleGrantedAuthority("ROLE_${user.role.name}")) + ) + } log.info("User ${user.fullName} has just relogged") return "redirect:/admin/control/settings" diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SimpleEntityPage.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SimpleEntityPage.kt index d39a0435..f025b2b3 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SimpleEntityPage.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/SimpleEntityPage.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.admin -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.model.IdentifiableEntity diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TszImportDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TszImportDashboard.kt index 70824626..d0aabce1 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TszImportDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TszImportDashboard.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.controller.admin -import com.fasterxml.jackson.databind.MappingIterator -import com.fasterxml.jackson.dataformat.csv.CsvMapper +import tools.jackson.databind.MappingIterator +import tools.jackson.dataformat.csv.CsvMapper import hu.bme.sch.cmsch.admin.IconStatus import hu.bme.sch.cmsch.admin.dashboard.* import hu.bme.sch.cmsch.component.app.ApplicationComponent @@ -256,7 +256,7 @@ class TszImportDashboard( group.staff3 = if (mappings.value.size > 2) mappings.value[2] else "" group.staff4 = if (mappings.value.size > 3) mappings.value[3] else "" return@map group - } + }.toMutableList() groupRepository.saveAll(affectedGroups) affectedSize = affectedGroups.size } @@ -289,4 +289,4 @@ class TszImportDashboard( return results } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TwoDeepEntityPage.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TwoDeepEntityPage.kt index f6320b73..ddfe3a40 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TwoDeepEntityPage.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/TwoDeepEntityPage.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.admin -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.OverviewBuilder import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.model.IdentifiableEntity diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt index 865c30a8..e5d754be 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt @@ -14,9 +14,9 @@ import hu.bme.sch.cmsch.service.ControlPermissions import hu.bme.sch.cmsch.service.TimeService import hu.bme.sch.cmsch.statistics.UserActivityFilter import org.apache.catalina.util.ServerInfo -import org.springframework.boot.autoconfigure.web.ServerProperties -import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties import org.springframework.boot.info.BuildProperties +import org.springframework.boot.servlet.autoconfigure.MultipartProperties +import org.springframework.boot.web.server.autoconfigure.ServerProperties import org.springframework.core.env.Environment import org.springframework.stereotype.Controller import org.springframework.web.bind.annotation.RequestMapping @@ -100,11 +100,7 @@ class InstanceInfoDashboard( listOf("Token ownership mode", startupPropertyConfig.tokenOwnershipMode.name), listOf("Challenge ownership mode", startupPropertyConfig.challengeOwnershipMode.name), listOf("Race ownership mode", startupPropertyConfig.raceOwnershipMode.name), - listOf("Max threads", serverProperties?.tomcat?.threads?.max?.toString() ?: "n/a"), - listOf("Min spare threads", serverProperties?.tomcat?.threads?.minSpare?.toString() ?: "n/a"), - listOf("Accept count", serverProperties?.tomcat?.acceptCount?.toString() ?: "n/a"), - listOf("Max connections", serverProperties?.tomcat?.maxConnections?.toString() ?: "n/a"), - listOf("Max swallow size ( ͡° ͜ʖ ͡°)", serverProperties?.tomcat?.maxSwallowSize?.toString() ?: "n/a"), + listOf("Max request header size", serverProperties?.maxHttpRequestHeaderSize?.toString() ?: "n/a"), listOf("Max file size", multipartProperties?.maxFileSize?.toString() ?: "n/a"), listOf("Max request size", multipartProperties?.maxRequestSize?.toString() ?: "n/a"), listOf("Datasource url", env.getProperty("spring.datasource.url", "n/a")), diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupController.kt index c3fb8af7..92c36412 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.ImportFormat import hu.bme.sch.cmsch.admin.OverviewBuilder import hu.bme.sch.cmsch.component.app.UserHandlingComponent diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupToUserMappingController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupToUserMappingController.kt index 864b4030..48c18745 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupToUserMappingController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GroupToUserMappingController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.app.ApplicationComponent import hu.bme.sch.cmsch.component.app.UserHandlingComponent import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GuildToUserMappingController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GuildToUserMappingController.kt index 54451ffe..17cb881d 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GuildToUserMappingController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/GuildToUserMappingController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.app.ApplicationComponent import hu.bme.sch.cmsch.component.app.UserHandlingComponent import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/MembersOfMyGroupController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/MembersOfMyGroupController.kt index 95f91b54..fc5a3554 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/MembersOfMyGroupController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/MembersOfMyGroupController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.app.UserHandlingComponent import hu.bme.sch.cmsch.controller.admin.SimpleEntityPage import hu.bme.sch.cmsch.dto.virtual.GroupMemberVirtualEntity diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupAssignPage.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupAssignPage.kt index d6c14be5..229222d7 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupAssignPage.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupAssignPage.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.GenerateOverview import hu.bme.sch.cmsch.admin.OverviewType import hu.bme.sch.cmsch.component.app.UserHandlingComponent diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupController.kt index b92b8224..1ee56b5b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.component.app.UserHandlingComponent import hu.bme.sch.cmsch.component.login.CmschUser diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupUserListPage.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupUserListPage.kt index 9cc5fa68..ecf0d767 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupUserListPage.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/PermissionGroupUserListPage.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.admin.GenerateOverview import hu.bme.sch.cmsch.admin.OverviewType import hu.bme.sch.cmsch.component.app.UserHandlingComponent diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/UserController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/UserController.kt index 790d80a5..0957b22f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/UserController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/userhandling/UserController.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.controller.userhandling -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.ComponentBase import hu.bme.sch.cmsch.component.app.UserHandlingComponent import hu.bme.sch.cmsch.component.login.CmschUser diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/EntityPageDataSource.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/EntityPageDataSource.kt index 0e28b2ea..c3d0d801 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/EntityPageDataSource.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/EntityPageDataSource.kt @@ -4,7 +4,7 @@ import java.util.* interface EntityPageDataSource { - fun findAll(): Iterable + fun findAll(): MutableIterable fun findById(id: ID): Optional @@ -14,8 +14,8 @@ interface EntityPageDataSource { fun save(entity: S): S - fun saveAll(entities: Iterable): Iterable + fun saveAll(entities: MutableIterable): MutableIterable fun deleteAll() -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/ManualRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/ManualRepository.kt index 4daa8fd5..a539a233 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/ManualRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/ManualRepository.kt @@ -4,7 +4,7 @@ import java.util.* abstract class ManualRepository : EntityPageDataSource { - override fun findAll(): Iterable = + override fun findAll(): MutableIterable = throw UnsupportedOperationException("This data source does not support: findAll()") override fun count(): Long = @@ -13,7 +13,7 @@ abstract class ManualRepository : EntityPageDataSource { override fun deleteAll(): Unit = throw UnsupportedOperationException("This data source does not support: deleteAll()") - override fun saveAll(entities: Iterable): Iterable = + override fun saveAll(entities: MutableIterable): MutableIterable = throw UnsupportedOperationException("This data source does not support: saveAll(entities)") override fun save(entity: S): S = diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/UserRepository.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/UserRepository.kt index 9ba8dd13..f836d4f5 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/UserRepository.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/repository/UserRepository.kt @@ -41,8 +41,8 @@ interface UserRepository : CrudRepository, fun findAllByGroupName(groupName: String): List fun findByEmail(email: String): Optional fun countAllByGroup(group: GroupEntity): Long - fun findAllByRoleOrRoleOrPermissionsNot(role1: RoleType, role2: RoleType, emptyString: String): List - fun findAllByRoleOrRole(role1: RoleType, role2: RoleType): List + fun findAllByRoleOrRoleOrPermissionsNot(role1: RoleType, role2: RoleType, emptyString: String): MutableList + fun findAllByRoleOrRole(role1: RoleType, role2: RoleType): MutableList @Query("SELECT NEW hu.bme.sch.cmsch.repository.UserSelectorView(e.id, e.fullName, e.alias, e.provider, e.email) FROM UserEntity e") fun findAllSelectorView(): List diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/service/UserService.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/service/UserService.kt index 2692bc88..0cdae747 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/service/UserService.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/service/UserService.kt @@ -1,6 +1,6 @@ package hu.bme.sch.cmsch.service -import com.fasterxml.jackson.databind.ObjectMapper +import tools.jackson.databind.ObjectMapper import hu.bme.sch.cmsch.component.login.CmschUser import hu.bme.sch.cmsch.dto.UserConfig import hu.bme.sch.cmsch.dto.virtual.GroupMemberVirtualEntity @@ -10,8 +10,7 @@ import hu.bme.sch.cmsch.repository.GroupToUserMappingRepository import hu.bme.sch.cmsch.repository.GuildToUserMappingRepository import hu.bme.sch.cmsch.repository.UserRepository import hu.bme.sch.cmsch.repository.UserSelectorView -import org.springframework.retry.annotation.Backoff -import org.springframework.retry.annotation.Retryable +import org.springframework.resilience.annotation.Retryable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional @@ -29,7 +28,7 @@ open class UserService( private val userConfigReader = objectMapper.readerFor(UserConfig::class.java) - @Retryable(value = [ SQLException::class ], maxAttempts = 5, backoff = Backoff(delay = 500L, multiplier = 1.5)) + @Retryable(value = [ SQLException::class ], maxRetries = 5, delay = 500L, multiplier = 1.5) @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE) open fun save(user: UserEntity) { users.save(user) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingProviderConfiguration.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingProviderConfiguration.kt index d9deb923..7490fe87 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingProviderConfiguration.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingProviderConfiguration.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.setting import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -14,11 +14,10 @@ class SettingProviderConfiguration { @Bean @Qualifier(DATABASE_SETTING_CACHE) - @ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.startup", - name = ["distributed-mode"], - havingValue = "false", - matchIfMissing = true + @ConditionalOnBooleanProperty( + value = ["hu.bme.sch.cmsch.startup.distributed-mode"], + havingValue = false, + matchIfMissing = true, ) fun singletonDatabaseSettingCache(): SettingCache = SettingCache() diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingSerializer.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingSerializer.kt index dcd136cd..90f0178b 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingSerializer.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/setting/SettingSerializer.kt @@ -1,7 +1,7 @@ package hu.bme.sch.cmsch.setting -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import tools.jackson.core.type.TypeReference +import tools.jackson.module.kotlin.jacksonObjectMapper import hu.bme.sch.cmsch.model.RoleType import org.slf4j.LoggerFactory diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/StatisticsFilterConfig.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/StatisticsFilterConfig.kt index 06a4f293..3d1aa35f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/StatisticsFilterConfig.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/StatisticsFilterConfig.kt @@ -1,27 +1,21 @@ package hu.bme.sch.cmsch.statistics -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.boot.web.servlet.FilterRegistrationBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import java.util.* @Configuration -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["stats"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.stats"]) class StatisticsFilterConfig( private var userActivityFilter: Optional ) { @Bean fun userActivityFilterRegistration(): FilterRegistrationBean { - val registration = FilterRegistrationBean() - registration.filter = userActivityFilter.orElseThrow() + val registration = FilterRegistrationBean(userActivityFilter.orElseThrow()) registration.addUrlPatterns("/api/*") return registration } -} \ No newline at end of file +} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/UserActivityFilter.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/UserActivityFilter.kt index af85ca52..b345b295 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/UserActivityFilter.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/statistics/UserActivityFilter.kt @@ -5,7 +5,7 @@ import jakarta.servlet.ServletRequest import jakarta.servlet.ServletResponse import jakarta.servlet.http.HttpServletRequest import org.slf4j.LoggerFactory -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component import org.springframework.web.filter.GenericFilterBean @@ -17,12 +17,7 @@ import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.LongAdder @Component -@ConditionalOnProperty( - prefix = "hu.bme.sch.cmsch.component.load", - name = ["stats"], - havingValue = "true", - matchIfMissing = false -) +@ConditionalOnBooleanProperty(value = ["hu.bme.sch.cmsch.component.load.stats"]) class UserActivityFilter : GenericFilterBean() { private val log = LoggerFactory.getLogger(javaClass) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/util/StringToArraySerializer.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/util/StringToArraySerializer.kt index 5b570dea..c2e62ecc 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/util/StringToArraySerializer.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/util/StringToArraySerializer.kt @@ -1,24 +1,22 @@ package hu.bme.sch.cmsch.util -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider import com.itextpdf.io.exceptions.IOException +import tools.jackson.core.JsonGenerator +import tools.jackson.databind.SerializationContext +import tools.jackson.databind.ValueSerializer -class StringToArraySerializer : JsonSerializer() { +class StringToArraySerializer : ValueSerializer() { @Throws(IOException::class) - override fun serialize(value: String, gen: JsonGenerator, serializers: SerializerProvider) { + override fun serialize(value: String, gen: JsonGenerator, ctxt: SerializationContext) { gen.writeStartArray() if (value.isNotEmpty()) { - for (part in value - .replace("\r", "") - .replace("\n", "") - .split(",")) { + for (part in value.replace("\r", "").replace("\n", "").split(",")) { gen.writeString(part.replace("\"", "\\\"").trim()) } } gen.writeEndArray() } + } diff --git a/backend/src/main/resources/config/application.properties b/backend/src/main/resources/config/application.properties index 136f4d69..2d2337d6 100644 --- a/backend/src/main/resources/config/application.properties +++ b/backend/src/main/resources/config/application.properties @@ -172,5 +172,3 @@ management.endpoint.health.probes.enabled=true management.endpoints.web.exposure.include=* spring.jpa.properties.hibernate.generate_statistics=true management.metrics.tags.application=insert_application_name -# It's spamming the console otherwise -logging.level.org.hibernate=warn