Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⬆️ upgrade to spring boot 3 #1505

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ subprojects {
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.1")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.1")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.1")
implementation("org.yaml:snakeyaml:1.33")

testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.9.1")
testImplementation("com.jayway.jsonpath:json-path-assert:2.7.0")
Expand Down
3 changes: 2 additions & 1 deletion server/zally-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ dependencies {
kapt("com.google.auto.service:auto-service:1.0.1")

api(project(":zally-rule-api"))
api("io.swagger.parser.v3:swagger-parser:2.1.12")
api("io.swagger.parser.v3:swagger-parser:2.1.16")
api("com.sun.mail:mailapi:1.6.2")
api("io.github.config4k:config4k:0.5.0")
implementation("com.google.auto.service:auto-service:1.0.1")

Expand Down
13 changes: 6 additions & 7 deletions server/zally-server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
kotlin("plugin.spring") version kotlinVersion
kotlin("plugin.allopen") version kotlinVersion

id("org.springframework.boot") version "2.7.7"
id("org.springframework.boot") version "3.3.3"
}

apply(plugin = "io.spring.dependency-management")
Expand All @@ -28,14 +28,13 @@ dependencies {
}
implementation("org.flywaydb:flyway-core:9.11.0")
implementation("org.hsqldb:hsqldb:2.7.1")
implementation("org.postgresql:postgresql:42.5.1")
implementation("org.hibernate:hibernate-core")
implementation("org.jadira.usertype:usertype.core:7.0.0.CR1") {
exclude("org.hibernate", "hibernate-entitymanager")
}
implementation("org.postgresql:postgresql:42.7.2")
implementation("org.hibernate.orm:hibernate-core")

implementation("org.zalando.stups:stups-spring-oauth2-server:1.0.24")
implementation("org.zalando:problem:0.27.1")
implementation("org.zalando:problem-spring-web:0.27.0")
implementation("org.zalando:jackson-datatype-problem:0.27.1")
implementation("org.zalando:problem-spring-web:0.29.1")
implementation("org.zalando:twintip-spring-web:1.2.0")

testImplementation(project(":zally-test"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ApiDefinitionReader(private val client: RestTemplate) {
} catch (exception: HttpClientErrorException) {
throw InaccessibleResourceUrlException(
"${exception.message} while retrieving api definition url",
exception.statusCode
HttpStatus.valueOf(exception.statusCode.value())
)
} catch (exception: ResourceAccessException) {
throw InaccessibleResourceUrlException(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package org.zalando.zally.apireview

import org.hibernate.annotations.Parameter
import org.hibernate.annotations.Type
import jakarta.persistence.CascadeType
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.FetchType
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.OneToMany
import org.zalando.zally.core.Result
import org.zalando.zally.dto.ApiDefinitionRequest
import org.zalando.zally.rule.api.Severity
Expand All @@ -11,14 +17,6 @@ import java.time.LocalDate
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.util.UUID
import javax.persistence.CascadeType
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.FetchType
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
import javax.persistence.OneToMany

@Suppress("unused")
@Entity
Expand All @@ -29,10 +27,7 @@ class ApiReview(
violations: List<Result> = emptyList(),
val name: String? = OpenApiHelper.extractApiName(apiDefinition),
val apiId: String? = OpenApiHelper.extractApiId(apiDefinition),
@Type(
type = "org.jadira.usertype.dateandtime.threeten.PersistentOffsetDateTime",
parameters = [Parameter(name = "javaZone", value = "UTC")]
)

@Column(nullable = false)
val created: OffsetDateTime = Instant.now().atOffset(ZoneOffset.UTC),
@Column(nullable = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ interface ApiReviewRepository : CrudRepository<ApiReview, Long> {
SELECT new org.zalando.zally.statistic.ReviewStatistics(
COUNT(r) AS totalReviews,
COUNT(DISTINCT r.name) AS totalReviewDeduplicated,
COALESCE(SUM(CASE WHEN r.isSuccessfulProcessed = 'True' THEN 1 ELSE 0 END),0) AS successfulReviews,
COALESCE(SUM(CASE WHEN r.isSuccessfulProcessed = true THEN 1 ELSE 0 END),0) AS successfulReviews,
COALESCE(SUM(r.numberOfEndpoints),0) AS numberOfEndpoints,
COALESCE(SUM(r.mustViolations),0) AS mustViolations,
COALESCE(SUM(r.shouldViolations),0) AS shouldViolations,
COALESCE(SUM(r.mayViolations),0) AS mayViolations,
COALESCE(SUM(r.hintViolations),0) AS hintViolations)
FROM org.zalando.zally.apireview.ApiReview r
WHERE day >= :from AND day <= :to AND user_agent LIKE :userAgent
WHERE day >= :from AND day <= :to AND userAgent LIKE :userAgent
"""
)
fun getReviewStatistics(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class ApiViolationsController(
@ResponseBody
@GetMapping("/api-violations/{externalId}")
fun getExistingViolationResponse(
@PathVariable(value = "externalId") externalId: UUID
@PathVariable externalId: UUID
): ApiDefinitionResponse {
val review = apiReviewRepository.findByExternalId(externalId) ?: throw ApiReviewNotFoundException()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package org.zalando.zally.apireview

import com.fasterxml.jackson.annotation.JsonIgnore
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.EnumType
import jakarta.persistence.Enumerated
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.ManyToOne
import org.zalando.zally.core.Result
import org.zalando.zally.rule.api.Severity
import java.io.Serializable
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
import javax.persistence.ManyToOne

@Entity
class RuleViolation(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package org.zalando.zally.configuration

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Profile
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.web.SecurityFilterChain

@Profile("dev", "test")
@Configuration
class NoSecurityConfiguration : WebSecurityConfigurerAdapter() {
@EnableWebSecurity
class NoSecurityConfiguration {

@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http.httpBasic().disable()
.csrf().disable()
.authorizeRequests().antMatchers("/**").permitAll()
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http
.httpBasic { basic -> basic.disable() }
.csrf { csrf -> csrf.disable() }
.authorizeHttpRequests { requests ->
requests
.requestMatchers("/**").permitAll()
}

return http.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,30 @@ class OAuthConfiguration : ResourceServerConfigurerAdapter() {
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http
.httpBasic().disable()
.requestMatchers().antMatchers("/**")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.regexMatchers("/health/?").permitAll()
.regexMatchers(
"/metrics/?(\\?.*)?",
"/api-violations/?([a-z0-9-]+/?)?(\\?)?",
"/supported-rules/?(\\?.*)?",
"/review-statistics/?(\\?.*)?"
)
.access("#oauth2.hasScope('uid')")
.antMatchers("**").denyAll()
.authorizeHttpRequests { it.requestMatchers("/**") }
.httpBasic { it.disable() }
.sessionManagement {
it.sessionCreationPolicy(SessionCreationPolicy.NEVER)
}
.authorizeHttpRequests {
it.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers("/health/?").permitAll()
.requestMatchers(
"/metrics/?(\\?.*)?",
"/api-violations/?([a-z0-9-]+/?)?(\\?)?",
"/supported-rules/?(\\?.*)?",
"/review-statistics/?(\\?.*)?"
)
.hasAuthority("SCOPE_uid")
.anyRequest().denyAll()
}

http
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.exceptionHandling { handling ->
handling
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
}
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,32 @@ import org.zalando.problem.spring.web.advice.SpringAdviceTrait
@ControllerAdvice
class ExceptionHandling : ProblemHandling, SpringAdviceTrait {

@ExceptionHandler
@ExceptionHandler(MissingApiDefinitionException::class)
fun handleMissingApiDefinitionException(
exception: MissingApiDefinitionException,
request: NativeWebRequest
): ResponseEntity<Problem> {
return create(HttpStatus.BAD_REQUEST, exception, request)
}

@ExceptionHandler
@ExceptionHandler(InaccessibleResourceUrlException::class)
fun handleUnaccessibleResourceUrlException(
exception: InaccessibleResourceUrlException,
request: NativeWebRequest
): ResponseEntity<Problem> {
return create(exception.httpStatus, exception, request)
}

@ExceptionHandler
fun handleUnsufficientTimeIntervalParameterException(
@ExceptionHandler(InsufficientTimeIntervalParameterException::class)
fun handleInsufficientTimeIntervalParameterException(
exception: InsufficientTimeIntervalParameterException,
request: NativeWebRequest
): ResponseEntity<Problem> {
return create(HttpStatus.BAD_REQUEST, exception, request)
}

@ExceptionHandler
fun handleUnsufficientTimeIntervalParameterException(
@ExceptionHandler(TimeParameterIsInTheFutureException::class)
fun handleTimeParameterIsInTheFutureException(
exception: TimeParameterIsInTheFutureException,
request: NativeWebRequest
): ResponseEntity<Problem> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ class ReviewStatisticsController(private val apiReviewRepository: ApiReviewRepos
@ResponseBody
@GetMapping("/review-statistics")
fun retrieveReviewStatistics(
@RequestParam(value = "from", required = false)
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
from: LocalDate?,
@RequestParam(value = "to", required = false)
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
to: LocalDate?,
@RequestParam(value = "user_agent", required = false) userAgent: String?
Expand Down
8 changes: 4 additions & 4 deletions server/zally-server/src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

endpoints:
enabled: false
health:
enabled: true
metrics:
enabled: true
sensitive: false

spring:
Expand All @@ -28,3 +25,6 @@ zally:
deprecatedCliAgents: unirest-java/1.3.11,Zally-CLI/1.0

TOKEN_INFO_URI: https://auth.example.com/oauth2/tokeninfo
management.endpoints.enabled-by-default: false
management.endpoint.health.enabled: true
management.endpoint.metrics.enabled: true
2 changes: 1 addition & 1 deletion server/zally-server/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ zally:
releasesPage: https://github.com/zalando/zally/releases
deprecatedCliAgents: unirest-java/1.3.11,Zally-CLI/1.0
---
spring.profiles: local
spring.config.activate.on-profile: local
TOKEN_INFO_URI: https://auth.example.com/oauth2/tokeninfo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import org.springframework.http.HttpStatusCode
import org.springframework.http.RequestEntity
import org.springframework.test.context.ActiveProfiles

Expand All @@ -12,12 +13,12 @@ class RestCorsWithOAuthTest : RestApiBaseTest() {

@Test
fun shouldSupportCorsWhenOAuthIsEnabledOnAllResources() {
assertThat(optionsRequest(RestApiBaseTest.API_VIOLATIONS_URL)).isEqualTo(HttpStatus.OK)
assertThat(optionsRequest(RestApiBaseTest.SUPPORTED_RULES_URL)).isEqualTo(HttpStatus.OK)
assertThat(optionsRequest(RestApiBaseTest.REVIEW_STATISTICS_URL)).isEqualTo(HttpStatus.OK)
assertThat(optionsRequest(API_VIOLATIONS_URL)).isEqualTo(HttpStatus.OK)
assertThat(optionsRequest(SUPPORTED_RULES_URL)).isEqualTo(HttpStatus.OK)
assertThat(optionsRequest(REVIEW_STATISTICS_URL)).isEqualTo(HttpStatus.OK)
}

private fun optionsRequest(url: String): HttpStatus {
private fun optionsRequest(url: String): HttpStatusCode {
return restTemplate.exchange(url, HttpMethod.OPTIONS, RequestEntity.EMPTY, String::class.java).statusCode
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.zalando.zally.configuration

import jakarta.servlet.http.HttpServletRequest
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.mockito.Mockito
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
import org.springframework.security.web.util.matcher.RegexRequestMatcher
import javax.servlet.http.HttpServletRequest

/**
* This serves as a reminder/documentation of how the matchers do work.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object JadlerUtil {
val url = String.format("http://localhost:%d/%s", port(), resourceName)

onRequest()
.havingMethodEqualTo(GET.name)
.havingMethodEqualTo(GET.name())
.havingPathEqualTo("/$resourceName")
.respond()
.withStatus(status)
Expand All @@ -39,7 +39,7 @@ object JadlerUtil {
val url = "http://localhost:" + port() + remotePath

onRequest()
.havingMethodEqualTo(GET.name)
.havingMethodEqualTo(GET.name())
.havingPathEqualTo(remotePath)
.respond()
.withStatus(NOT_FOUND.value())
Expand Down