diff --git a/.github/workflows/build_test_package.yml b/.github/workflows/build_test_package.yml index 11668bde1..6d421eea2 100644 --- a/.github/workflows/build_test_package.yml +++ b/.github/workflows/build_test_package.yml @@ -31,10 +31,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Build with Gradle env: @@ -94,10 +93,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Run ${{ matrix.service.testPrefix }} controller tests env: @@ -125,10 +123,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Run unit tests env: @@ -174,10 +171,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Run RBAC ${{ matrix.service.packageName }} integration tests env: @@ -221,10 +217,9 @@ jobs: run: echo "gitRefName=${GITHUB_REF#refs/*/}" >> "${GITHUB_OUTPUT}" - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Build local Container Image for scanning run: > diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index a645c86d8..03391034d 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -29,10 +29,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Generate Markdown documentation env: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3c7e592cf..5d7aedea2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -33,10 +33,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Check with Spotless env: @@ -61,10 +60,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Check with Detekt env: diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index e4e5b5d92..0fb41fcb9 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -41,10 +41,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Validate '${{ matrix.project }}' definition run: ./gradlew :cosmotech-${{ matrix.project }}:openApiValidate | tee validate.log diff --git a/.github/workflows/openapi_clients.yml b/.github/workflows/openapi_clients.yml index 667db7b30..5092ea51b 100644 --- a/.github/workflows/openapi_clients.yml +++ b/.github/workflows/openapi_clients.yml @@ -44,10 +44,9 @@ jobs: java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Generate Client (${{ matrix.language }}) env: diff --git a/.github/workflows/track_dependencies.yml b/.github/workflows/track_dependencies.yml index cbcb91bc3..d7ad26185 100644 --- a/.github/workflows/track_dependencies.yml +++ b/.github/workflows/track_dependencies.yml @@ -17,10 +17,9 @@ jobs: distribution: 'temurin' java-version: '23' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 with: - gradle-version: '8.14' - cache-disabled: true + gradle-version: '9.4.1' - name: Track dependencies env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/api/build.gradle.kts b/api/build.gradle.kts index b6a9e8e8a..76c380c99 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -21,7 +21,9 @@ dependencies { implementation(projects.cosmotechRunApi) implementation(projects.cosmotechRunnerApi) implementation(projects.cosmotechCommonApi) - testImplementation("org.springframework.security:spring-security-test") + testImplementation("org.springframework.boot:spring-boot-starter-security-test") + testImplementation("org.springframework.boot:spring-boot-restdocs") + testImplementation("org.springframework.boot:spring-boot-webmvc-test") testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc") } diff --git a/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestBase.kt b/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestBase.kt index 16bd13107..889ddb26e 100644 --- a/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestBase.kt +++ b/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestBase.kt @@ -17,7 +17,8 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.extension.ExtendWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs +import org.springframework.boot.restdocs.test.autoconfigure.AutoConfigureRestDocs +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.http.HttpHeaders import org.springframework.restdocs.RestDocumentationContextProvider import org.springframework.restdocs.RestDocumentationExtension @@ -34,6 +35,7 @@ import org.springframework.web.context.WebApplicationContext @EnableWebSecurity @ExtendWith(RestDocumentationExtension::class) @AutoConfigureRestDocs +@AutoConfigureMockMvc abstract class ControllerTestBase : CsmTestBase() { @Autowired private lateinit var context: WebApplicationContext @@ -46,7 +48,6 @@ abstract class ControllerTestBase : CsmTestBase() { @BeforeEach fun beforeEach(restDocumentationContextProvider: RestDocumentationContextProvider) { - rediSearchIndexer.createIndexFor(Organization::class.java) rediSearchIndexer.createIndexFor(Workspace::class.java) rediSearchIndexer.createIndexFor(Dataset::class.java) diff --git a/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestUtils.kt b/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestUtils.kt index 09fba14e6..be9cf3614 100644 --- a/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestUtils.kt +++ b/api/src/integrationTest/kotlin/com/cosmotech/api/home/ControllerTestUtils.kt @@ -36,6 +36,7 @@ import org.springframework.mock.web.MockMultipartFile import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder +import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post @@ -519,3 +520,7 @@ fun MockHttpServletRequestBuilder.withPlatformAdminHeader(): MockHttpServletRequ fun MockHttpServletRequestBuilder.withOrganizationUserHeader(): MockHttpServletRequestBuilder = this.header(ORGANIZATION_USER_EMAIL, ORGANIZATION_USER_API_KEY_VALUE) + +fun MockMultipartHttpServletRequestBuilder.withPlatformAdminHeader(): + MockMultipartHttpServletRequestBuilder = + this.header(PLATFORM_ADMIN_EMAIL, PLATFORM_ADMIN_API_KEY_VALUE) diff --git a/api/src/integrationTest/kotlin/com/cosmotech/api/home/dataset/DatasetControllerTests.kt b/api/src/integrationTest/kotlin/com/cosmotech/api/home/dataset/DatasetControllerTests.kt index fdb31b6d8..fec465b63 100644 --- a/api/src/integrationTest/kotlin/com/cosmotech/api/home/dataset/DatasetControllerTests.kt +++ b/api/src/integrationTest/kotlin/com/cosmotech/api/home/dataset/DatasetControllerTests.kt @@ -81,7 +81,6 @@ class DatasetControllerTests : ControllerTestBase() { @BeforeEach fun beforeEach() { - val runTemplateRunSizing = RunTemplateResourceSizing( com.cosmotech.solution.domain.ResourceSizeInfo("1", "2G"), diff --git a/api/src/integrationTest/kotlin/com/cosmotech/api/home/run/RunControllerTests.kt b/api/src/integrationTest/kotlin/com/cosmotech/api/home/run/RunControllerTests.kt index d95bc8ee1..244165494 100644 --- a/api/src/integrationTest/kotlin/com/cosmotech/api/home/run/RunControllerTests.kt +++ b/api/src/integrationTest/kotlin/com/cosmotech/api/home/run/RunControllerTests.kt @@ -101,7 +101,6 @@ class RunControllerTests : ControllerTestBase() { @BeforeEach fun beforeEach() { - ReflectionTestUtils.setField(runApiService, "containerFactory", containerFactory) ReflectionTestUtils.setField(runApiService, "workflowService", workflowService) ReflectionTestUtils.setField(runApiService, "eventPublisher", eventPublisher) diff --git a/api/src/integrationTest/kotlin/com/cosmotech/api/home/runner/RunnerControllerTests.kt b/api/src/integrationTest/kotlin/com/cosmotech/api/home/runner/RunnerControllerTests.kt index d27cea417..2eff020dd 100644 --- a/api/src/integrationTest/kotlin/com/cosmotech/api/home/runner/RunnerControllerTests.kt +++ b/api/src/integrationTest/kotlin/com/cosmotech/api/home/runner/RunnerControllerTests.kt @@ -77,7 +77,6 @@ class RunnerControllerTests : ControllerTestBase() { @BeforeEach fun beforeEach() { - val tags = mutableListOf("tag1", "tag2") val description = "this_is_a_description" val parameterGroupId = "parameterGroup1" diff --git a/api/src/integrationTest/resources/application-test.yml b/api/src/integrationTest/resources/application-test.yml index 00a51311d..52dcd5823 100644 --- a/api/src/integrationTest/resources/application-test.yml +++ b/api/src/integrationTest/resources/application-test.yml @@ -1,6 +1,6 @@ management: endpoints: - enabled-by-default: false + access.default: none spring: data: diff --git a/api/src/main/resources/application.yml b/api/src/main/resources/application.yml index 2596ee9b1..c2d6e6341 100644 --- a/api/src/main/resources/application.yml +++ b/api/src/main/resources/application.yml @@ -51,11 +51,7 @@ management: port: 8081 server: - error: - whitelabel: - enabled: false - include-stacktrace: never - undertow: + jetty: accesslog: enabled: true @@ -179,3 +175,7 @@ api: swagger-ui: base-path: ${server.servlet.context-path} version: ${csm.platform.api.version} + +spring.web.error.include-stacktrace: never + +spring.web.error.whitelabel.enabled: false diff --git a/build.gradle.kts b/build.gradle.kts index 90a5ae605..8fcf281a2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,8 +13,9 @@ import org.cyclonedx.gradle.CyclonedxDirectTask import org.cyclonedx.model.Component.Type.APPLICATION import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly import org.openapitools.generator.gradle.plugin.tasks.GenerateTask import org.openapitools.generator.gradle.plugin.tasks.ValidateTask import org.springframework.boot.gradle.tasks.bundling.BootJar @@ -25,13 +26,15 @@ import org.springframework.boot.gradle.tasks.run.BootRun // implementations/configurations in a 'buildSrc' included build. // See https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources +val kotlinVersion = "2.2" + plugins { - val kotlinVersion = "2.0.21" - kotlin("jvm") version kotlinVersion - kotlin("plugin.spring") version kotlinVersion apply false + val kotlinCompleteVersion = "2.2.21" + kotlin("jvm") version kotlinCompleteVersion + kotlin("plugin.spring") version kotlinCompleteVersion apply false id("pl.allegro.tech.build.axion-release") version "1.21.1" id("com.diffplug.spotless") version "8.1.0" - id("org.springframework.boot") version "3.5.13" apply false + id("org.springframework.boot") version "4.0.4" apply false id("project-report") id("org.owasp.dependencycheck") version "12.1.9" id("com.github.jk1.dependency-license-report") version "3.0.1" @@ -44,6 +47,8 @@ plugins { scmVersion { tag { prefix.set("") } } +dependencies { runtimeOnly("javax.xml.bind:jaxb-api:2.3.1") } + group = "com.cosmotech" version = scmVersion.version @@ -51,39 +56,33 @@ version = scmVersion.version // Dependencies version val jacksonAnnotationVersion = "2.20" val jacksonDatabindVersion = "2.20.1" -val jacksonModuleKotlinVersion = "2.20.1" +val jacksonModuleKotlinVersion = "3.0.4" val springWebVersion = "6.2.14" val bouncyCastleJdk18Version = "1.83" val springBootVersion = "3.5.8" val springSecurityJwtVersion = "1.1.1.RELEASE" val springOauthAutoConfigureVersion = "2.6.8" val kotlinJvmTarget = 21 -val redisOmSpringVersion = "1.1.1" +val redisOmSpringVersion = "2.0.4" val kotlinCoroutinesVersion = "1.10.2" -val springDocVersion = "2.8.14" +val springDocVersion = "3.0.2" val swaggerParserVersion = "2.1.36" val commonsCsvVersion = "1.14.1" -val apiValidationVersion = "3.1.1" +val apiValidationVersion = "3.0.2" val kubernetesClientVersion = "22.0.0" val orgJsonVersion = "20250517" val testNgVersion = "7.11.0" -val testContainersRedisVersion = "1.6.4" -val testContainersPostgreSQLVersion = "1.21.3" -val testContainersLocalStackVersion = "1.21.3" +val testContainersRedisVersion = "2.2.4" +val testContainersPostgreSQLVersion = "1.21.4" +val testContainersLocalStackVersion = "1.21.4" val commonCompressVersion = "1.28.0" -val awsSpringVersion = "3.4.2" -// The version is fixed to 2.3.20.Final -// due to a undertow bug https://issues.redhat.com/browse/JBEAP-31823 -// the server.undertow.max-http-post-size is not override by -// spring.servlet.multipart.max-file-size -// Fix should be available in 2.3.23.Final -val undertowVersion = "2.3.20.Final" +val awsSpringVersion = "4.0.0" // Checks val detektVersion = "1.23.8" // Tests -val jUnitBomVersion = "6.0.1" +val jUnitBomVersion = "6.0.3" val mockkVersion = "1.14.7" val awaitilityKVersion = "4.3.0" val springMockkVersion = "4.0.2" @@ -108,10 +107,7 @@ licenseReport { "https://raw.githubusercontent.com/Cosmo-Tech/cosmotech-license/refs/heads/main/config/license-normalizer-bundle.json" renderers = arrayOf(InventoryHtmlReportRenderer("index.html")) - filters = - arrayOf( - LicenseBundleNormalizer(uri(bundle).toURL().openStream(), true) - ) + filters = arrayOf(LicenseBundleNormalizer(uri(bundle).toURL().openStream(), true)) } buildscript { @@ -140,6 +136,7 @@ allprojects { sourceCompatibility = JavaVersion.VERSION_21 toolchain { languageVersion.set(JavaLanguageVersion.of(kotlinJvmTarget)) } } + configurations { all { resolutionStrategy { force("com.redis.om:redis-om-spring:2.0.4") } } } repositories { maven { @@ -286,7 +283,7 @@ subprojects { dependencies { // https://youtrack.jetbrains.com/issue/KT-71057/POM-file-unusable-after-upgrading-to-2.0.20-from-2.0.10 - implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.0.21")) + implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.2.21")) detekt("io.gitlab.arturbosch.detekt:detekt-cli:$detektVersion") detekt("io.gitlab.arturbosch.detekt:detekt-formatting:$detektVersion") detektPlugins("io.gitlab.arturbosch.detekt:detekt-rules-libraries:$detektVersion") @@ -299,17 +296,12 @@ subprojects { implementation("org.springframework.boot:spring-boot-starter-actuator") implementation("io.micrometer:micrometer-registry-prometheus") - implementation("org.springframework.boot:spring-boot-starter-web") { + implementation("org.springframework.boot:spring-boot-starter-webmvc") { exclude(group = "org.springframework.boot", module = "spring-boot-starter-tomcat") } - implementation("org.springframework.boot:spring-boot-starter-undertow") { - constraints { - implementation("io.undertow:undertow-core:2.3.24.Final") - implementation("io.undertow:undertow-servlet:2.3.24.Final") - implementation("io.undertow:undertow-websockets-jsr:2.3.24.Final") - } - } - implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + implementation("org.springframework.boot:spring-boot-starter-jetty") + implementation("tools.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + implementation("tools.jackson.dataformat:jackson-dataformat-yaml:3.0.4") // https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api implementation("jakarta.validation:jakarta.validation-api:$apiValidationVersion") implementation("io.kubernetes:client-java:${kubernetesClientVersion}") @@ -336,9 +328,11 @@ subprojects { } } implementation("org.springframework.security:spring-security-oauth2-jose") - implementation("org.springframework.security:spring-security-oauth2-resource-server") + implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server") implementation("org.apache.commons:commons-csv:$commonsCsvVersion") - implementation("com.redis.om:redis-om-spring:${redisOmSpringVersion}") + implementation("com.redis.om:redis-om-spring:${redisOmSpringVersion}") { + exclude(group = "org.springframework.data", module = "spring-data-redis") + } implementation("org.springframework.data:spring-data-redis") implementation("org.springframework:spring-jdbc") implementation("org.postgresql:postgresql") @@ -356,9 +350,7 @@ subprojects { testImplementation("org.awaitility:awaitility-kotlin:$awaitilityKVersion") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutinesVersion") testImplementation("org.testng:testng:$testNgVersion") - testImplementation( - "com.redis.testcontainers:testcontainers-redis-junit:$testContainersRedisVersion" - ) + testImplementation("com.redis:testcontainers-redis:$testContainersRedisVersion") testImplementation("org.testcontainers:postgresql:$testContainersPostgreSQLVersion") testImplementation("org.testcontainers:localstack:$testContainersLocalStackVersion") testImplementation("org.springframework.boot:spring-boot-starter-test") @@ -385,11 +377,11 @@ subprojects { compilerArgs.add("-parameters") } - tasks.withType().configureEach { - kotlinOptions { - languageVersion = "1.9" - freeCompilerArgs = listOf("-Xjsr305=strict") - jvmTarget = kotlinJvmTarget.toString() + kotlin { + compilerOptions { + languageVersion.set(KotlinVersion.fromVersion(kotlinVersion)) + freeCompilerArgs = listOf("-Xjsr305=strict", "-Xannotation-default-target=param-property") + jvmTarget.set(JvmTarget.fromTarget(kotlinJvmTarget.toString())) java { targetCompatibility = JavaVersion.VERSION_21 sourceCompatibility = JavaVersion.VERSION_21 @@ -399,7 +391,7 @@ subprojects { } val integrationTest = - task("integrationTest") { + tasks.register("integrationTest") { description = "Runs integration tests" group = "verification" useJUnitPlatform() @@ -499,7 +491,7 @@ subprojects { ) additionalProperties.set( mapOf( - "title" to "Cosmo Tech ${projectDirName.capitalizeAsciiOnly()} Manager API", + "title" to "Cosmo Tech ${projectDirName} Manager API", "basePackage" to "com.cosmotech", "configPackage" to "com.cosmotech.${projectDirName}.config", "enumPropertyNaming" to "original", @@ -641,13 +633,11 @@ tasks.getByName("spotlessKotlinGradle") { val copySubProjectsDetektReportsTasks = subprojects.flatMap { subProject -> listOf("html", "xml", "txt", "sarif").map { format -> - val formatCapitalized = format.capitalizeAsciiOnly() + val formatCapitalized = format val copyTask = tasks.register( "detektCopy${formatCapitalized}ReportFor" + - "${subProject.projectDir.relativeTo(rootDir)}" - .capitalizeAsciiOnly() - .replace("/", "_") + "${subProject.projectDir.relativeTo(rootDir)}".replace("/", "_") ) { group = "detekt" description = diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 2f160c478..cd1d902f1 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -6,22 +6,23 @@ plugins { id("org.jetbrains.kotlinx.kover") } val hashidsVersion = "1.0.3" val testContainersRedisVersion = "1.6.4" -val testContainersPostgreSQLVersion = "1.21.3" -val testContainersLocalStackVersion = "1.21.3" +val testContainersPostgreSQLVersion = "2.0.4" +val testContainersLocalStackVersion = "2.0.4" val tikaVersion = "3.2.3" val jUnitBomVersion = "6.0.1" dependencies { implementation("org.apache.httpcomponents.client5:httpclient5") + implementation("org.springframework.boot:spring-boot-starter-restclient:4.0.5") implementation("org.hashids:hashids:${hashidsVersion}") implementation( "com.redis.testcontainers:testcontainers-redis-junit:${testContainersRedisVersion}" ) { constraints { implementation("com.redis:lettucemod:4.5.0") } } - implementation("org.testcontainers:postgresql:${testContainersPostgreSQLVersion}") - implementation("org.testcontainers:localstack:${testContainersLocalStackVersion}") + implementation("org.testcontainers:testcontainers-postgresql:${testContainersPostgreSQLVersion}") + implementation("org.testcontainers:testcontainers-localstack:${testContainersLocalStackVersion}") implementation("org.apache.tika:tika-core:${tikaVersion}") implementation("org.springframework.boot:spring-boot-starter-test") diff --git a/common/src/main/kotlin/com/cosmotech/common/config/CsmApiConfiguration.kt b/common/src/main/kotlin/com/cosmotech/common/config/CsmApiConfiguration.kt index 9e30fe442..a6d971a5f 100644 --- a/common/src/main/kotlin/com/cosmotech/common/config/CsmApiConfiguration.kt +++ b/common/src/main/kotlin/com/cosmotech/common/config/CsmApiConfiguration.kt @@ -2,16 +2,15 @@ // Licensed under the MIT license. package com.cosmotech.common.config +import com.cosmotech.common.utils.jsonObjectMapper import com.cosmotech.common.utils.yamlObjectMapper -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory import java.nio.charset.StandardCharsets import java.util.concurrent.Executor import java.util.concurrent.Executors import org.apache.commons.lang3.concurrent.BasicThreadFactory +import org.springframework.boot.EnvironmentPostProcessor import org.springframework.boot.SpringApplication import org.springframework.boot.context.properties.ConfigurationPropertiesScan -import org.springframework.boot.env.EnvironmentPostProcessor import org.springframework.boot.logging.DeferredLog import org.springframework.context.annotation.AdviceMode import org.springframework.context.annotation.Bean @@ -21,7 +20,8 @@ import org.springframework.core.Ordered import org.springframework.core.annotation.Order import org.springframework.core.env.ConfigurableEnvironment import org.springframework.http.MediaType -import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter +import org.springframework.http.converter.yaml.JacksonYamlHttpMessageConverter import org.springframework.scheduling.annotation.EnableAsync import org.springframework.web.servlet.config.annotation.CorsRegistry import org.springframework.web.servlet.config.annotation.WebMvcConfigurer @@ -38,7 +38,29 @@ open class CsmApiConfiguration { BasicThreadFactory.builder().namingPattern("csm-event-handler-%d").build() ) - @Bean open fun yamlHttpMessageConverter(): YamlMessageConverter = YamlMessageConverter() + @Bean + open fun yamlHttpMessageConverter(): JacksonYamlHttpMessageConverter { + val jacksonYamlHttpMessageConverter = JacksonYamlHttpMessageConverter(yamlObjectMapper()) + jacksonYamlHttpMessageConverter.supportedMediaTypes = + listOf( + MediaType("application", "yaml", StandardCharsets.UTF_8), + MediaType("text", "yaml", StandardCharsets.UTF_8), + MediaType("application", "*+yaml", StandardCharsets.UTF_8), + MediaType("application", "yml", StandardCharsets.UTF_8), + MediaType("text", "yml", StandardCharsets.UTF_8), + MediaType("application", "*+yml", StandardCharsets.UTF_8), + ) + return jacksonYamlHttpMessageConverter + } + + @Bean + open fun jsonHttpMessageConverter(): JacksonJsonHttpMessageConverter { + val jacksonJsonHttpMessageConverter = JacksonJsonHttpMessageConverter(jsonObjectMapper()) + val supportedMediaTypes = jacksonJsonHttpMessageConverter.supportedMediaTypes.toMutableList() + supportedMediaTypes.add(MediaType("application", "octet-stream")) + jacksonJsonHttpMessageConverter.supportedMediaTypes = supportedMediaTypes + return jacksonJsonHttpMessageConverter + } } @Order(Ordered.HIGHEST_PRECEDENCE) @@ -64,40 +86,6 @@ open class CsmPlatformEnvironmentPostProcessor : EnvironmentPostProcessor { } } -/** - * Implementation of {@link org.springframework.http.converter.HttpMessageConverter - * HttpMessageConverter} that can read and write YAML using Jackson extension - * component for reading and writing YAML encoded data. - * - * By default, this converter supports {@code application/yaml}, {@code application/yml}, {@code - * text/yaml}, {@code text/yml}, {@code application/<*>+yaml}, and {@code application/<*>+yml} with - * {@code UTF-8} character set. - * - * This can be overridden by setting the {@link #setSupportedMediaTypes supportedMediaTypes} - * property. - */ -class YamlMessageConverter(objectMapper: ObjectMapper) : - AbstractJackson2HttpMessageConverter( - objectMapper, - MediaType("application", "yaml", StandardCharsets.UTF_8), - MediaType("text", "yaml", StandardCharsets.UTF_8), - MediaType("application", "*+yaml", StandardCharsets.UTF_8), - MediaType("application", "yml", StandardCharsets.UTF_8), - MediaType("text", "yml", StandardCharsets.UTF_8), - MediaType("application", "*+yml", StandardCharsets.UTF_8), - ) { - - constructor() : this(yamlObjectMapper()) - - override fun setObjectMapper(objectMapper: ObjectMapper) { - require(objectMapper.factory is YAMLFactory) { - "ObjectMapper must be configured with YAMLFactory" - } - super.setObjectMapper(objectMapper) - } -} - @Configuration internal open class WebConfig : WebMvcConfigurer { diff --git a/common/src/main/kotlin/com/cosmotech/common/config/SwaggerBeanConfiguration.kt b/common/src/main/kotlin/com/cosmotech/common/config/SwaggerBeanConfiguration.kt deleted file mode 100644 index b6b654a41..000000000 --- a/common/src/main/kotlin/com/cosmotech/common/config/SwaggerBeanConfiguration.kt +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Cosmo Tech. -// Licensed under the MIT license. -package com.cosmotech.common.config - -import org.springframework.context.annotation.Configuration -import org.springframework.http.MediaType -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter - -/** - * This class is here as a suggested workaround for the following issues. Swagger UI does not handle - * multipart requests correctly even if `encoding` property is set in openapi.yaml Each part of a - * multipart/form-data is sent with a content-type set to application/octet-stream The following - * workaround adds application/octet-stream has a supported MediaType for the - * MappingJackson2HttpMessageConverter https://github.com/swagger-api/swagger-ui/issues/6462 - * https://github.com/swagger-api/swagger-ui/issues/5356 - * https://github.com/swagger-api/swagger-ui/issues/9548 - * https://github.com/swagger-api/swagger-ui/issues/6462 - * https://github.com/swagger-api/swagger-ui/issues/9548 - */ -@Configuration -open class SwaggerBeanConfiguration(converter: MappingJackson2HttpMessageConverter) { - - init { - val supportedMediaTypes = ArrayList(converter.supportedMediaTypes) - supportedMediaTypes.add(MediaType("application", "octet-stream")) - converter.supportedMediaTypes = supportedMediaTypes - } -} diff --git a/common/src/main/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryService.kt b/common/src/main/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryService.kt index 9b648b864..d5c760403 100644 --- a/common/src/main/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryService.kt +++ b/common/src/main/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryService.kt @@ -16,6 +16,8 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory import org.springframework.stereotype.Service import org.springframework.web.client.RestClient import org.springframework.web.client.RestClientException +import org.springframework.web.client.body +import org.springframework.web.client.toEntity @Service("csmContainerRegistry") class ContainerRegistryService(private val csmPlatformProperties: CsmPlatformProperties) { @@ -61,7 +63,7 @@ class ContainerRegistryService(private val csmPlatformProperties: CsmPlatformPro .uri("/v2/$repository/tags/list") .header(HttpHeaders.AUTHORIZATION, getHeaderAuthorization()) .retrieve() - .body(String::class.java)!! + .body()!! val tags: JSONArray = JSONObject(images).get("tags") as JSONArray if (!tags.contains(tag)) { @@ -84,7 +86,7 @@ class ContainerRegistryService(private val csmPlatformProperties: CsmPlatformPro .header(HttpHeaders.AUTHORIZATION, getHeaderAuthorization()) .header(HttpHeaders.ACCEPT, "application/vnd.docker.distribution.manifest.v2+json") .retrieve() - .body(String::class.java)!! + .body()!! val digest = JSONObject(manifest).getJSONObject("config").getString("digest") @@ -94,17 +96,17 @@ class ContainerRegistryService(private val csmPlatformProperties: CsmPlatformPro .uri("/v2/$repository/blobs/$digest") .header(HttpHeaders.AUTHORIZATION, getHeaderAuthorization()) .retrieve() - .toEntity(String::class.java) + .toEntity() // If we need to follow a redirect, do it without the initial 'Authorization' header or Azure // Blob Storage will complain - var blob = - if (blobResponse.statusCode.is3xxRedirection()) + val blob = + if (blobResponse.statusCode.is3xxRedirection) restClient .get() - .uri(URI(blobResponse.headers.getFirst(HttpHeaders.LOCATION))) + .uri(URI(blobResponse.headers.getFirst(HttpHeaders.LOCATION) ?: "")) .retrieve() - .body(String::class.java)!! + .body()!! else blobResponse.body!! return JSONObject(blob) diff --git a/common/src/main/kotlin/com/cosmotech/common/redis/RedisConfig.kt b/common/src/main/kotlin/com/cosmotech/common/redis/RedisConfig.kt index 78565f66d..458ff7e89 100644 --- a/common/src/main/kotlin/com/cosmotech/common/redis/RedisConfig.kt +++ b/common/src/main/kotlin/com/cosmotech/common/redis/RedisConfig.kt @@ -6,11 +6,16 @@ import org.springframework.beans.factory.annotation.Value import org.springframework.boot.ssl.SslBundles import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.data.redis.connection.RedisConnectionFactory +import org.springframework.data.redis.core.RedisTemplate +import org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer import redis.clients.jedis.DefaultJedisClientConfig import redis.clients.jedis.HostAndPort import redis.clients.jedis.JedisClientConfig import redis.clients.jedis.Protocol +import redis.clients.jedis.RedisClient import redis.clients.jedis.UnifiedJedis +import tools.jackson.databind.json.JsonMapper @Configuration open class RedisConfig { @@ -48,6 +53,20 @@ open class RedisConfig { @Bean open fun unifiedJedis(csmJedisClientConfig: JedisClientConfig): UnifiedJedis { - return UnifiedJedis(HostAndPort(twincacheHost, twincachePort.toInt()), csmJedisClientConfig) + return RedisClient.builder() + .clientConfig(csmJedisClientConfig) + .hostAndPort(HostAndPort(twincacheHost, twincachePort.toInt())) + .build() + } + + @Bean + fun redisTemplate( + connectionFactory: RedisConnectionFactory, + jsonObjectMapper: JsonMapper, + ): RedisTemplate { + val template = RedisTemplate() + template.defaultSerializer = GenericJacksonJsonRedisSerializer(jsonObjectMapper) + template.connectionFactory = connectionFactory + return template } } diff --git a/common/src/main/kotlin/com/cosmotech/common/security/keycloak/KeycloakSecurityConfiguration.kt b/common/src/main/kotlin/com/cosmotech/common/security/keycloak/KeycloakSecurityConfiguration.kt index a6373b98a..2c6fbc25e 100644 --- a/common/src/main/kotlin/com/cosmotech/common/security/keycloak/KeycloakSecurityConfiguration.kt +++ b/common/src/main/kotlin/com/cosmotech/common/security/keycloak/KeycloakSecurityConfiguration.kt @@ -13,9 +13,9 @@ import java.util.stream.Collectors import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties +import org.springframework.boot.restclient.RestTemplateBuilder +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties import org.springframework.boot.ssl.SslBundles -import org.springframework.boot.web.client.RestTemplateBuilder import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.convert.converter.Converter @@ -171,7 +171,8 @@ class KeycloakJwtGrantedAuthoritiesConverter( if (rawRoleClaim is Collection<*>) { return rawRoleClaim .stream() - .map { role: Any? -> SimpleGrantedAuthority((role as? String)) } + .filter(Objects::nonNull) + .map { role -> SimpleGrantedAuthority((role as String)) } .filter(Objects::nonNull) .collect(Collectors.toList()) } else if (rawRoleClaim != null) { diff --git a/common/src/main/kotlin/com/cosmotech/common/tests/CsmTestBase.kt b/common/src/main/kotlin/com/cosmotech/common/tests/CsmTestBase.kt index 98190c1d9..c3ceaa091 100644 --- a/common/src/main/kotlin/com/cosmotech/common/tests/CsmTestBase.kt +++ b/common/src/main/kotlin/com/cosmotech/common/tests/CsmTestBase.kt @@ -2,26 +2,29 @@ // Licensed under the MIT license. package com.cosmotech.common.tests -import com.redis.testcontainers.RedisServer import com.redis.testcontainers.RedisStackContainer -import com.redis.testcontainers.junit.AbstractTestcontainersRedisTestBase import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.TestInstance import org.springframework.test.context.DynamicPropertyRegistry import org.springframework.test.context.DynamicPropertySource -import org.testcontainers.containers.PostgreSQLContainer -import org.testcontainers.containers.PostgreSQLContainer.POSTGRESQL_PORT -import org.testcontainers.containers.localstack.LocalStackContainer +import org.testcontainers.junit.jupiter.Testcontainers +import org.testcontainers.localstack.LocalStackContainer +import org.testcontainers.postgresql.PostgreSQLContainer +import org.testcontainers.postgresql.PostgreSQLContainer.POSTGRESQL_PORT import org.testcontainers.utility.DockerImageName import org.testcontainers.utility.MountableFile -open class CsmTestBase : AbstractTestcontainersRedisTestBase() { +@Testcontainers +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +open class CsmTestBase { companion object { private const val DEFAULT_REDIS_PORT = 6379 private const val LOCALSTACK_FULL_IMAGE_NAME = "localstack/localstack:4.14.0" - var postgres: PostgreSQLContainer<*> = + var postgres: PostgreSQLContainer = PostgreSQLContainer("postgres:latest") .withCopyFileToContainer( MountableFile.forClasspathResource("init-db.sql"), @@ -31,8 +34,7 @@ open class CsmTestBase : AbstractTestcontainersRedisTestBase() { var redisStackServer = RedisStackContainer(RedisStackContainer.DEFAULT_IMAGE_NAME) val localStackServer = - LocalStackContainer(DockerImageName.parse(LOCALSTACK_FULL_IMAGE_NAME)) - .withServices(LocalStackContainer.Service.S3) + LocalStackContainer(DockerImageName.parse(LOCALSTACK_FULL_IMAGE_NAME)).withServices("s3") init { redisStackServer.start() @@ -54,7 +56,7 @@ open class CsmTestBase : AbstractTestcontainersRedisTestBase() { redisStackServer.containerInfo.networkSettings.networks.entries .elementAt(0) .value - .ipAddress + .ipAddress ?: "cannot_find_redis_container_ip" registry.add("spring.data.redis.host") { containerIp } registry.add("spring.data.redis.port") { DEFAULT_REDIS_PORT } @@ -80,14 +82,15 @@ open class CsmTestBase : AbstractTestcontainersRedisTestBase() { postgres.start() } + @BeforeEach + fun flushAll() { + redisStackServer.execInContainer("redis-cli", "flushall") + } + @AfterAll fun afterAll() { postgres.stop() localStackServer.stop() redisStackServer.stop() } - - override fun redisServers(): MutableCollection { - return mutableListOf(redisStackServer) - } } diff --git a/common/src/main/kotlin/com/cosmotech/common/utils/AnyExtensions.kt b/common/src/main/kotlin/com/cosmotech/common/utils/AnyExtensions.kt index d1192ef16..f818bfc69 100644 --- a/common/src/main/kotlin/com/cosmotech/common/utils/AnyExtensions.kt +++ b/common/src/main/kotlin/com/cosmotech/common/utils/AnyExtensions.kt @@ -2,10 +2,10 @@ // Licensed under the MIT license. package com.cosmotech.common.utils -import com.fasterxml.jackson.core.type.TypeReference import java.lang.IllegalArgumentException import kotlin.reflect.KMutableProperty import kotlin.reflect.KProperty +import tools.jackson.core.type.TypeReference /** * Extension function that checks whether the specified member has changed between [this] receiver @@ -28,7 +28,7 @@ inline fun T.changed(old: U?, memberAccessBlock: T.() -> R): B /** Convert any object as a Map, using the Jackson Object Mapper */ fun T.convertToMap(): Map = - objectMapper().convertValue(this, object : TypeReference>() {}) + jsonObjectMapper().convertValue(this, object : TypeReference>() {}) /** * Compare this object against another one of the same type and mutate the former if {@code diff --git a/common/src/main/kotlin/com/cosmotech/common/utils/ObjectMappers.kt b/common/src/main/kotlin/com/cosmotech/common/utils/ObjectMappers.kt index beb988827..d6931cda6 100644 --- a/common/src/main/kotlin/com/cosmotech/common/utils/ObjectMappers.kt +++ b/common/src/main/kotlin/com/cosmotech/common/utils/ObjectMappers.kt @@ -2,19 +2,23 @@ // Licensed under the MIT license. package com.cosmotech.common.utils -import com.fasterxml.jackson.core.JsonFactory -import com.fasterxml.jackson.databind.DeserializationFeature -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.SerializationFeature -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import com.fasterxml.jackson.module.kotlin.registerKotlinModule +import tools.jackson.databind.DeserializationFeature +import tools.jackson.databind.cfg.DateTimeFeature +import tools.jackson.databind.json.JsonMapper +import tools.jackson.dataformat.yaml.YAMLFactory +import tools.jackson.dataformat.yaml.YAMLMapper +import tools.jackson.module.kotlin.jacksonMapperBuilder +import tools.jackson.module.kotlin.kotlinModule -fun objectMapper(jsonFactory: JsonFactory? = null): ObjectMapper = - ObjectMapper(jsonFactory) - .registerKotlinModule() - .registerModule(JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) +fun jsonObjectMapper(): JsonMapper = + jacksonMapperBuilder() + .disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .build() -fun yamlObjectMapper(): ObjectMapper = objectMapper(YAMLFactory()) +fun yamlObjectMapper(): YAMLMapper = + YAMLMapper.Builder(YAMLFactory()) + .addModule(kotlinModule()) + .disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .build() diff --git a/common/src/main/kotlin/com/cosmotech/common/utils/SecurityUtils.kt b/common/src/main/kotlin/com/cosmotech/common/utils/SecurityUtils.kt index aee773d0f..462b54102 100644 --- a/common/src/main/kotlin/com/cosmotech/common/utils/SecurityUtils.kt +++ b/common/src/main/kotlin/com/cosmotech/common/utils/SecurityUtils.kt @@ -1,6 +1,7 @@ // Copyright (c) Cosmo Tech. // Licensed under the MIT license. @file:JvmName("SecurityUtilsKt") +@file:Suppress("UNCHECKED_CAST") package com.cosmotech.common.utils diff --git a/common/src/main/resources/META-INF/spring.factories b/common/src/main/resources/META-INF/spring.factories index 6d2631b76..6a8af407c 100644 --- a/common/src/main/resources/META-INF/spring.factories +++ b/common/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.env.EnvironmentPostProcessor=com.cosmotech.common.config.CsmPlatformEnvironmentPostProcessor \ No newline at end of file +org.springframework.boot.EnvironmentPostProcessor=com.cosmotech.common.config.CsmPlatformEnvironmentPostProcessor \ No newline at end of file diff --git a/common/src/test/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryServiceTest.kt b/common/src/test/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryServiceTest.kt index 6753bdb5a..7a6a36c72 100644 --- a/common/src/test/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryServiceTest.kt +++ b/common/src/test/kotlin/com/cosmotech/common/containerregistry/ContainerRegistryServiceTest.kt @@ -19,12 +19,13 @@ import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.test.util.ReflectionTestUtils -import org.springframework.util.MultiValueMap import org.springframework.web.client.HttpClientErrorException import org.springframework.web.client.HttpServerErrorException import org.springframework.web.client.RestClient import org.springframework.web.client.RestClient.ResponseSpec import org.springframework.web.client.RestClientException +import org.springframework.web.client.body +import org.springframework.web.client.toEntity class ContainerRegistryServiceTest { @@ -52,7 +53,7 @@ class ContainerRegistryServiceTest { .uri("/v2/any/tags/list") .header(HttpHeaders.AUTHORIZATION, any()) .retrieve() - .body(String::class.java) + .body() } throws HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR) containerRegistryService.checkSolutionImage("any", "any") @@ -68,7 +69,7 @@ class ContainerRegistryServiceTest { .uri("/v2/any/tags/list") .header(HttpHeaders.AUTHORIZATION, any()) .retrieve() - .body(String::class.java) + .body() } throws HttpClientErrorException(HttpStatus.BAD_REQUEST) containerRegistryService.checkSolutionImage("any", "any") @@ -91,7 +92,7 @@ class ContainerRegistryServiceTest { .uri("/v2/any/tags/list") .header(HttpHeaders.AUTHORIZATION, any()) .retrieve() - .body(String::class.java) + .body() } returns jo.toString() containerRegistryService.checkSolutionImage("any", "wrong_tag") @@ -117,7 +118,7 @@ class ContainerRegistryServiceTest { } returns responseMockk every { responseMockk.onStatus(any(), any()) } returns responseMockk - every { responseMockk.body(String::class.java) } returns jo.toString() + every { responseMockk.body() } returns jo.toString() containerRegistryService.checkSolutionImage("my-repository", "latest") } @@ -131,7 +132,7 @@ class ContainerRegistryServiceTest { .header(HttpHeaders.AUTHORIZATION, any()) .header(HttpHeaders.ACCEPT, "application/vnd.docker.distribution.manifest.v2+json") .retrieve() - .body(String::class.java) + .body() } returns """{"config":{"digest":"mydigest"}}""" every { @@ -140,7 +141,7 @@ class ContainerRegistryServiceTest { .uri("/v2/myimage/blobs/mydigest") .header(HttpHeaders.AUTHORIZATION, any()) .retrieve() - .toEntity(String::class.java) + .toEntity() } returns ResponseEntity("""{"config":{"Labels":{"mylabel":"myvalue"}}}""", HttpStatus.OK) assertEquals("myvalue", containerRegistryService.getImageLabel("myimage", "mytag", "mylabel")) @@ -155,24 +156,20 @@ class ContainerRegistryServiceTest { .header(HttpHeaders.AUTHORIZATION, any()) .header(HttpHeaders.ACCEPT, "application/vnd.docker.distribution.manifest.v2+json") .retrieve() - .body(String::class.java) + .body() } returns """{"config":{"digest":"mydigest"}}""" - val response = - ResponseEntity( - MultiValueMap.fromSingleValue(mapOf(HttpHeaders.LOCATION to String())), - HttpStatus.TEMPORARY_REDIRECT, - ) + val response = ResponseEntity(HttpHeaders.LOCATION, HttpStatus.TEMPORARY_REDIRECT) every { noRedirectClient .get() .uri("/v2/myimage/blobs/mydigest") .header(HttpHeaders.AUTHORIZATION, any()) .retrieve() - .toEntity(String::class.java) + .toEntity() } returns response - every { restClient.get().uri(any()).retrieve().body(String::class.java) } returns + every { restClient.get().uri(any()).retrieve().body() } returns """{"config":{"Labels":{"mylabel":"myvalue"}}}""" assertEquals("myvalue", containerRegistryService.getImageLabel("myimage", "mytag", "mylabel")) @@ -187,7 +184,7 @@ class ContainerRegistryServiceTest { .header(HttpHeaders.AUTHORIZATION, any()) .header(HttpHeaders.ACCEPT, "application/vnd.docker.distribution.manifest.v2+json") .retrieve() - .body(String::class.java) + .body() } returns """{"config":{"digest":"mydigest"}}""" every { @@ -196,7 +193,7 @@ class ContainerRegistryServiceTest { .uri("/v2/myimage/blobs/mydigest") .header(HttpHeaders.AUTHORIZATION, any()) .retrieve() - .toEntity(String::class.java) + .toEntity() } returns ResponseEntity("""{"config":{"Labels":null}}""", HttpStatus.OK) assertNull(containerRegistryService.getImageLabel("myimage", "mytag", "mylabel")) @@ -211,7 +208,7 @@ class ContainerRegistryServiceTest { .header(HttpHeaders.AUTHORIZATION, any()) .header(HttpHeaders.ACCEPT, "application/vnd.docker.distribution.manifest.v2+json") .retrieve() - .body(String::class.java) + .body() } throws RestClientException("") assertNull(containerRegistryService.getImageLabel("wrong", "wrong", "mylabel")) diff --git a/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceIntegrationTest.kt b/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceIntegrationTest.kt index 1bac04869..b2796a3f9 100644 --- a/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceIntegrationTest.kt +++ b/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceIntegrationTest.kt @@ -62,12 +62,11 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue import org.apache.commons.io.IOUtils -import org.junit.Assert.assertFalse +import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.assertNotNull import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -77,13 +76,9 @@ import org.springframework.http.MediaType import org.springframework.jdbc.core.JdbcTemplate import org.springframework.mock.web.MockMultipartFile import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner @ActiveProfiles(profiles = ["dataset-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class DatasetServiceIntegrationTest() : CsmTestBase() { diff --git a/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceRBACTest.kt b/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceRBACTest.kt index ead309ae5..2660c2d8f 100644 --- a/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceRBACTest.kt +++ b/dataset/src/integrationTest/kotlin/com/cosmotech/dataset/service/DatasetServiceRBACTest.kt @@ -66,7 +66,6 @@ import org.junit.jupiter.api.TestFactory import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -74,14 +73,10 @@ import org.springframework.core.io.ResourceLoader import org.springframework.http.MediaType import org.springframework.mock.web.MockMultipartFile import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner import org.springframework.web.multipart.MultipartFile @ActiveProfiles(profiles = ["dataset-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class DatasetServiceRBACTest : CsmTestBase() { diff --git a/dataset/src/integrationTest/resources/application-dataset-test.yml b/dataset/src/integrationTest/resources/application-dataset-test.yml index 37e6725e4..ce92431c4 100644 --- a/dataset/src/integrationTest/resources/application-dataset-test.yml +++ b/dataset/src/integrationTest/resources/application-dataset-test.yml @@ -1,6 +1,6 @@ management: endpoints: - enabled-by-default: false + access.default: none spring: security: diff --git a/dataset/src/main/kotlin/com/cosmotech/dataset/service/DatasetServiceImpl.kt b/dataset/src/main/kotlin/com/cosmotech/dataset/service/DatasetServiceImpl.kt index bb4111396..a44d02600 100644 --- a/dataset/src/main/kotlin/com/cosmotech/dataset/service/DatasetServiceImpl.kt +++ b/dataset/src/main/kotlin/com/cosmotech/dataset/service/DatasetServiceImpl.kt @@ -161,7 +161,7 @@ class DatasetServiceImpl( .initSecurity(datasetCreateRequest.security.toGenericSecurity(datasetId)) .toResourceSecurity() - val datasetParts = + val datasetParts: MutableList? = datasetCreateRequest.parts ?.map { part -> val constructDatasetPart = diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f..1b33c55ba 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d4081da47..fcb845c03 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,8 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionSha256Sum=2ab2958f2a1e51120c326cad6f385153bb11ee93b3c216c5fccebfdfbb7ec6cb diff --git a/gradlew b/gradlew index b740cf133..23d15a936 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -203,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 7101f8e46..5eed7ee84 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%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" %* :end @rem End local scope for the variables with windows NT shell diff --git a/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceIntegrationTest.kt b/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceIntegrationTest.kt index 15d365aed..d84e6ad3a 100644 --- a/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceIntegrationTest.kt +++ b/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceIntegrationTest.kt @@ -46,7 +46,7 @@ import java.time.Instant import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertTrue -import org.junit.Assert.assertNotEquals +import org.junit.jupiter.api.Assertions.assertNotEquals import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested @@ -54,19 +54,14 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner @ActiveProfiles(profiles = ["organization-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Suppress("FunctionName") @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) diff --git a/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceRBACTest.kt b/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceRBACTest.kt index 57e8525d7..8eb746d43 100644 --- a/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceRBACTest.kt +++ b/organization/src/integrationTest/kotlin/com/cosmotech/organization/service/OrganizationServiceRBACTest.kt @@ -40,17 +40,12 @@ import org.junit.jupiter.api.TestFactory import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner @ActiveProfiles(profiles = ["organization-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) @Suppress("FunctionName") diff --git a/organization/src/integrationTest/resources/application-organization-test.yml b/organization/src/integrationTest/resources/application-organization-test.yml index 3b6adf9db..8dbb67629 100644 --- a/organization/src/integrationTest/resources/application-organization-test.yml +++ b/organization/src/integrationTest/resources/application-organization-test.yml @@ -1,6 +1,6 @@ management: endpoints: - enabled-by-default: false + access.default: none spring: security: diff --git a/run/build.gradle.kts b/run/build.gradle.kts index 46d7e79a2..f843a228d 100644 --- a/run/build.gradle.kts +++ b/run/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { implementation("com.squareup.retrofit2:converter-scalars:$retroFitVersion") implementation(platform("com.squareup.okhttp3:okhttp-bom:$okHttpBom")) implementation("com.squareup.okhttp3:okhttp") + implementation("org.springframework.boot:spring-boot-starter-restclient:4.0.5") implementation("com.squareup.okhttp3:logging-interceptor") } diff --git a/run/src/integrationTest/kotlin/com/cosmotech/run/service/RunServiceIntegrationTest.kt b/run/src/integrationTest/kotlin/com/cosmotech/run/service/RunServiceIntegrationTest.kt index f9bec52b8..19bea98c9 100644 --- a/run/src/integrationTest/kotlin/com/cosmotech/run/service/RunServiceIntegrationTest.kt +++ b/run/src/integrationTest/kotlin/com/cosmotech/run/service/RunServiceIntegrationTest.kt @@ -61,21 +61,16 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.HttpStatus import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner import org.springframework.test.util.ReflectionTestUtils import org.springframework.web.client.RestClientResponseException @ActiveProfiles(profiles = ["run-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) class RunServiceIntegrationTest : CsmTestBase() { diff --git a/run/src/integrationTest/resources/application-run-test.yml b/run/src/integrationTest/resources/application-run-test.yml index 753f0f57b..a760b9ca0 100644 --- a/run/src/integrationTest/resources/application-run-test.yml +++ b/run/src/integrationTest/resources/application-run-test.yml @@ -39,7 +39,7 @@ logging: management: endpoints: - enabled-by-default: false + access.default: none csm: platform: diff --git a/run/src/main/kotlin/com/cosmotech/run/workflow/WorkflowService.kt b/run/src/main/kotlin/com/cosmotech/run/workflow/WorkflowService.kt index 11bbbfafb..9dc548cc7 100644 --- a/run/src/main/kotlin/com/cosmotech/run/workflow/WorkflowService.kt +++ b/run/src/main/kotlin/com/cosmotech/run/workflow/WorkflowService.kt @@ -5,7 +5,7 @@ package com.cosmotech.run.workflow import com.cosmotech.run.domain.Run import com.cosmotech.run.domain.RunContainer import com.cosmotech.run.domain.RunStatus -import org.springframework.boot.actuate.health.HealthIndicator +import org.springframework.boot.health.contributor.HealthIndicator data class RunStartContainers( val generateName: String? = null, diff --git a/run/src/main/kotlin/com/cosmotech/run/workflow/argo/RunArgoWorkflowService.kt b/run/src/main/kotlin/com/cosmotech/run/workflow/argo/RunArgoWorkflowService.kt index 632dec2be..5fba05305 100644 --- a/run/src/main/kotlin/com/cosmotech/run/workflow/argo/RunArgoWorkflowService.kt +++ b/run/src/main/kotlin/com/cosmotech/run/workflow/argo/RunArgoWorkflowService.kt @@ -37,8 +37,8 @@ import okhttp3.OkHttpClient import org.json.JSONObject import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value -import org.springframework.boot.actuate.health.Health import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression +import org.springframework.boot.health.contributor.Health import org.springframework.context.event.EventListener import org.springframework.stereotype.Service import org.springframework.web.client.RestClient diff --git a/run/src/test/kotlin/com/cosmotech/run/workflow/argo/WorkflowBuildersTests.kt b/run/src/test/kotlin/com/cosmotech/run/workflow/argo/WorkflowBuildersTests.kt index a7baff048..d66893bf7 100644 --- a/run/src/test/kotlin/com/cosmotech/run/workflow/argo/WorkflowBuildersTests.kt +++ b/run/src/test/kotlin/com/cosmotech/run/workflow/argo/WorkflowBuildersTests.kt @@ -510,9 +510,9 @@ class WorkflowBuildersTests { val template = buildTemplate(ORGANIZATION_ID, WORKSPACE_ID, src, csmPlatformProperties, true) assertNotNull(template.container) val envFrom = template.container!!.envFrom - assertEquals(1, envFrom.size) + assertEquals(1, envFrom!!.size) assertNotNull(envFrom[0].secretRef) - assertEquals("$ORGANIZATION_ID-$WORKSPACE_ID".lowercase(), envFrom[0].secretRef.name) + assertEquals("$ORGANIZATION_ID-$WORKSPACE_ID".lowercase(), envFrom[0].secretRef!!.name) } @Test @@ -520,7 +520,7 @@ class WorkflowBuildersTests { val src = getRunContainer() val template = buildTemplate(ORGANIZATION_ID, null, src, csmPlatformProperties, true) assertNotNull(template.container) - assertTrue(template.container!!.envFrom.isEmpty()) + assertTrue(template.container!!.envFrom!!.isEmpty()) } private fun getRunContainer(name: String = "default"): RunContainer { diff --git a/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceIntegrationTest.kt b/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceIntegrationTest.kt index 17cc81640..9fb61bb36 100644 --- a/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceIntegrationTest.kt +++ b/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceIntegrationTest.kt @@ -70,7 +70,6 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -79,16 +78,13 @@ import org.springframework.core.io.ResourceLoader import org.springframework.http.MediaType import org.springframework.mock.web.MockMultipartFile import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner import org.springframework.test.util.ReflectionTestUtils @ActiveProfiles(profiles = ["runner-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) +@Suppress("UNCHECKED_CAST") class RunnerServiceIntegrationTest : CsmTestBase() { val CONNECTED_ADMIN_USER = "test.admin@cosmotech.com" @@ -393,7 +389,7 @@ class RunnerServiceIntegrationTest : CsmTestBase() { fun `test CRUD operations on Runner as Platform Admin`() { every { getCurrentAccountIdentifier(any()) } returns "random_user_with_patform_admin_role" every { getCurrentAuthenticatedRoles(any()) } returns listOf(ROLE_PLATFORM_ADMIN) - var initialRunnerList = + val initialRunnerList = runnerApiService.listRunners(organizationSaved.id, workspaceSaved.id, null, null) logger.info("should create a new Runner") @@ -403,7 +399,7 @@ class RunnerServiceIntegrationTest : CsmTestBase() { runnerApiService.createRunner(organizationSaved.id, workspaceSaved.id, newRunner) logger.info("should find all Runners and assert there is one more") - var runnerList = + val runnerList = runnerApiService.listRunners(organizationSaved.id, workspaceSaved.id, null, null) assertEquals(initialRunnerList.size + 1, runnerList.size) @@ -724,7 +720,7 @@ class RunnerServiceIntegrationTest : CsmTestBase() { runnerApiService.createRunner(organizationSaved.id, workspaceSaved.id, parentCreation) val parentRunner2 = runnerApiService.createRunner(organizationSaved.id, workspaceSaved.id, parentCreation) - var childCreation = makeRunnerCreateRequest(parentId = parentRunner1.id) + val childCreation = makeRunnerCreateRequest(parentId = parentRunner1.id) val childRunner1 = runnerApiService.createRunner(organizationSaved.id, workspaceSaved.id, childCreation) childCreation.parentId = parentRunner2.id diff --git a/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceRBACTest.kt b/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceRBACTest.kt index 24da74eb4..23c150f5b 100644 --- a/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceRBACTest.kt +++ b/runner/src/integrationTest/kotlin/com/cosmotech/runner/service/RunnerServiceRBACTest.kt @@ -66,18 +66,13 @@ import org.junit.jupiter.api.TestFactory import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner import org.springframework.test.util.ReflectionTestUtils @ActiveProfiles(profiles = ["runner-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) @Suppress("FunctionName") diff --git a/runner/src/integrationTest/resources/application-runner-test.yml b/runner/src/integrationTest/resources/application-runner-test.yml index 05cafa246..009185fc1 100644 --- a/runner/src/integrationTest/resources/application-runner-test.yml +++ b/runner/src/integrationTest/resources/application-runner-test.yml @@ -33,7 +33,7 @@ spring: management: endpoints: - enabled-by-default: false + access.default: none csm: platform: diff --git a/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerApiServiceImpl.kt b/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerApiServiceImpl.kt index edbd387ec..7b0af9025 100644 --- a/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerApiServiceImpl.kt +++ b/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerApiServiceImpl.kt @@ -29,7 +29,7 @@ import org.springframework.data.domain.PageRequest import org.springframework.stereotype.Service @Service -@Suppress("TooManyFunctions", "UnusedPrivateMember") +@Suppress("TooManyFunctions", "UnusedPrivateMember", "UNCHECKED_CAST") internal class RunnerApiServiceImpl( private val csmPlatformProperties: CsmPlatformProperties, private val runnerServiceManager: RunnerServiceManager, @@ -74,7 +74,7 @@ internal class RunnerApiServiceImpl( null, ) - return runnerSaved.apply { datasets.parameters = listDatasetParts as MutableList? } + return runnerSaved.apply { datasets.parameters = listDatasetParts as MutableList } } override fun getRunner(organizationId: String, workspaceId: String, runnerId: String): Runner { @@ -89,7 +89,7 @@ internal class RunnerApiServiceImpl( null, null, ) - return runner.apply { datasets.parameters = listDatasetParts as MutableList? } + return runner.apply { datasets.parameters = listDatasetParts as MutableList } } override fun updateRunner( @@ -113,7 +113,7 @@ internal class RunnerApiServiceImpl( null, ) - return runnerSaved.apply { datasets.parameters = listDatasetParts as MutableList? } + return runnerSaved.apply { datasets.parameters = listDatasetParts as MutableList } } override fun deleteRunner(organizationId: String, workspaceId: String, runnerId: String) { diff --git a/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerService.kt b/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerService.kt index 57b599dad..b2a179291 100644 --- a/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerService.kt +++ b/runner/src/main/kotlin/com/cosmotech/runner/service/RunnerService.kt @@ -67,7 +67,7 @@ const val DATASET_PART_VARTYPE_DB = "%DATASET_PART_ID_DB%" @Component @Scope("prototype") -@Suppress("TooManyFunctions", "LargeClass") +@Suppress("TooManyFunctions", "LargeClass", "UNCHECKED_CAST") class RunnerService( private val runnerRepository: RunnerRepository, private val organizationApiService: OrganizationApiServiceInterface, @@ -272,7 +272,7 @@ class RunnerService( } runner.apply { lastRunInfo.lastRunStatus = lastRunStatus - datasets.parameters = listDatasetParts as MutableList? + datasets.parameters = listDatasetParts as MutableList security = updateSecurityVisibility(this).security } } diff --git a/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceIntegrationTest.kt b/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceIntegrationTest.kt index 28f1d0fae..3cd3c2f12 100644 --- a/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceIntegrationTest.kt +++ b/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceIntegrationTest.kt @@ -42,13 +42,10 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestFactory import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner import org.springframework.test.util.ReflectionTestUtils const val CONNECTED_ADMIN_USER = "test.admin@cosmotech.com" @@ -56,8 +53,6 @@ const val CONNECTED_READER_USER = "test.user@cosmotech.com" @ActiveProfiles(profiles = ["solution-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) @Suppress("FunctionName") diff --git a/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceRBACTest.kt b/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceRBACTest.kt index f6aea25f9..7ce102338 100644 --- a/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceRBACTest.kt +++ b/solution/src/integrationTest/kotlin/com/cosmotech/solution/service/SolutionServiceRBACTest.kt @@ -45,19 +45,14 @@ import org.junit.jupiter.api.TestFactory import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.core.io.Resource import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner import org.springframework.test.util.ReflectionTestUtils @ActiveProfiles(profiles = ["solution-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) class SolutionServiceRBACTest : CsmTestBase() { diff --git a/solution/src/integrationTest/resources/application-solution-test.yml b/solution/src/integrationTest/resources/application-solution-test.yml index 37ce6565d..26b7c0e77 100644 --- a/solution/src/integrationTest/resources/application-solution-test.yml +++ b/solution/src/integrationTest/resources/application-solution-test.yml @@ -1,6 +1,6 @@ management: endpoints: - enabled-by-default: false + access.default: none spring: security: diff --git a/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceIntegrationTest.kt b/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceIntegrationTest.kt index 2bc5cfe3d..48a2e2de2 100644 --- a/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceIntegrationTest.kt +++ b/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceIntegrationTest.kt @@ -40,20 +40,15 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.core.io.ResourceLoader import org.springframework.mock.web.MockMultipartFile import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner @ActiveProfiles(profiles = ["workspace-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) @Suppress("FunctionName") diff --git a/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceRBACTest.kt b/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceRBACTest.kt index e4a8b9465..c75103376 100644 --- a/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceRBACTest.kt +++ b/workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceRBACTest.kt @@ -54,20 +54,15 @@ import org.junit.jupiter.api.TestFactory import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith -import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.context.junit4.SpringRunner import org.springframework.test.util.ReflectionTestUtils import org.springframework.web.multipart.MultipartFile import software.amazon.awssdk.services.s3.S3Client @ActiveProfiles(profiles = ["workspace-test"]) @ExtendWith(MockKExtension::class) -@ExtendWith(SpringExtension::class) -@RunWith(SpringRunner::class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableRedisDocumentRepositories(basePackages = ["com.cosmotech"]) @Suppress("FunctionName") diff --git a/workspace/src/integrationTest/resources/application-workspace-test.yml b/workspace/src/integrationTest/resources/application-workspace-test.yml index b64c8d913..f9550f30b 100644 --- a/workspace/src/integrationTest/resources/application-workspace-test.yml +++ b/workspace/src/integrationTest/resources/application-workspace-test.yml @@ -1,6 +1,6 @@ management: endpoints: - enabled-by-default: false + access.default: none spring: security: