diff --git a/pom.xml b/pom.xml index 225920df..604037ea 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.1 + 3.2.3 @@ -134,12 +134,6 @@ org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - de.bwaldvogel @@ -151,6 +145,12 @@ greenmail 2.0.1 test + + + junit + junit + + @@ -281,6 +281,25 @@ + + + org.openrewrite.maven + rewrite-maven-plugin + 5.24.0 + + + org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2 + + + + + org.openrewrite.recipe + rewrite-spring + 5.6.0 + + + + diff --git a/src/main/java/com/aidanwhiteley/books/controller/BookController.java b/src/main/java/com/aidanwhiteley/books/controller/BookController.java index 1c4dc8c6..e6d1ae45 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/BookController.java +++ b/src/main/java/com/aidanwhiteley/books/controller/BookController.java @@ -8,7 +8,6 @@ import com.aidanwhiteley.books.repository.dtos.BooksByGenre; import com.aidanwhiteley.books.service.StatsService; import com.aidanwhiteley.books.service.dtos.SummaryStats; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -38,7 +37,6 @@ public class BookController { @Value("${books.users.max.page.size}") private int maxPageSize; - @Autowired public BookController(BookRepository bookRepository, StatsService statsService) { this.bookRepository = bookRepository; this.statsService = statsService; @@ -50,33 +48,33 @@ public Page findAllByCreatedDateTimeDesc(Principal principal) { } @GetMapping(value = {"/books", "/books/"}, params = {"page", "size"}) - public Page findAllByCreatedDateTimeDesc(@RequestParam(value = "page") int page, - @RequestParam(value = "size") int size, Principal principal) { + public Page findAllByCreatedDateTimeDesc(@RequestParam int page, + @RequestParam int size, Principal principal) { PageRequest pageObj = PageRequest.of(page, size); return bookRepository.findAllByOrderByCreatedDateTimeDesc(pageObj); } @GetMapping(value = "/books/{id}") - public Book findBookById(@PathVariable("id") String id, Principal principal) { + public Book findBookById(@PathVariable String id, Principal principal) { return bookRepository.findById(id).orElseThrow(() -> new NotFoundException("Book id " + id + " not found")); } @GetMapping(value = {"/books", "/books/"}, params = {"author"}) - public Page findByAuthor(@RequestParam("author") String author, Principal principal) { + public Page findByAuthor(@RequestParam String author, Principal principal) { return findByAuthor(author, 0, defaultPageSize, principal); } @GetMapping(value = {"/books", "books/"}, params = {"author", "page", "size"}) - public Page findByAuthor(@RequestParam("author") String author, @RequestParam(value = "page") int page, - @RequestParam(value = "size") int size, Principal principal) { + public Page findByAuthor(@RequestParam String author, @RequestParam int page, + @RequestParam int size, Principal principal) { if (null == author || author.trim().isEmpty()) { throw new IllegalArgumentException("Author parameter cannot be empty"); } if (size > maxPageSize) { - throw new IllegalArgumentException(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize)); + throw new IllegalArgumentException(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize)); } PageRequest pageObj = PageRequest.of(page, size); @@ -84,20 +82,20 @@ public Page findByAuthor(@RequestParam("author") String author, @RequestPa } @GetMapping(value = {"/books", "/books/"}, params = {"search"}) - public Page findBySearch(@RequestParam("search") String search, Principal principal) { + public Page findBySearch(@RequestParam String search, Principal principal) { return findBySearch(search, 0, defaultPageSize, principal); } @GetMapping(value = {"/books", "/books/"}, params = {"search", "page", "size"}) - public Page findBySearch(@RequestParam("search") String search, @RequestParam(value = "page") int page, - @RequestParam(value = "size") int size, Principal principal) { + public Page findBySearch(@RequestParam String search, @RequestParam int page, + @RequestParam int size, Principal principal) { if (null == search || search.trim().isEmpty()) { throw new IllegalArgumentException("Search query string cannot be empty"); } if (size > maxPageSize) { - throw new IllegalArgumentException(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize)); + throw new IllegalArgumentException(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize)); } PageRequest pageObj = PageRequest.of(page, size); @@ -105,20 +103,20 @@ public Page findBySearch(@RequestParam("search") String search, @RequestPa } @GetMapping(value = {"/books", "/books/"}, params = {"genre"}) - public Page findByGenre(@RequestParam("genre") String genre, Principal principal) { + public Page findByGenre(@RequestParam String genre, Principal principal) { return findByGenre(genre, 0, defaultPageSize, principal); } @GetMapping(value = {"/books", "/books/"}, params = {"genre", "page", "size"}) - public Page findByGenre(@RequestParam("genre") String genre, @RequestParam(value = "page") int page, - @RequestParam(value = "size") int size, Principal principal) { + public Page findByGenre(@RequestParam String genre, @RequestParam int page, + @RequestParam int size, Principal principal) { if (null == genre || genre.trim().isEmpty()) { throw new IllegalArgumentException("Genre parameter cannot be empty"); } if (size > maxPageSize) { - throw new IllegalArgumentException(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize)); + throw new IllegalArgumentException(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize)); } PageRequest pageObj = PageRequest.of(page, size); @@ -141,13 +139,13 @@ public List findBookAuthors() { } @GetMapping(value = {"/books", "/books/"}, params = {"rating"}) - public Page findByRating(@RequestParam("rating") String rating, Principal principal) { + public Page findByRating(@RequestParam String rating, Principal principal) { return findByRating(rating, 0, defaultPageSize, principal); } @GetMapping(value = {"/books", "/books/"}, params = {"rating", "page", "size"}) - public Page findByRating(@RequestParam("rating") String rating, @RequestParam(value = "page") int page, - @RequestParam(value = "size") int size, Principal principal) { + public Page findByRating(@RequestParam String rating, @RequestParam int page, + @RequestParam int size, Principal principal) { if (null == rating || rating.trim().isEmpty()) { throw new IllegalArgumentException("Rating parameter cannot be empty"); @@ -159,7 +157,7 @@ public Page findByRating(@RequestParam("rating") String rating, @RequestPa } if (size > maxPageSize) { - throw new IllegalArgumentException(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize)); + throw new IllegalArgumentException(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize)); } PageRequest pageObj = PageRequest.of(page, size); diff --git a/src/main/java/com/aidanwhiteley/books/controller/BookSecureController.java b/src/main/java/com/aidanwhiteley/books/controller/BookSecureController.java index ef08e43c..6bcd3cce 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/BookSecureController.java +++ b/src/main/java/com/aidanwhiteley/books/controller/BookSecureController.java @@ -15,7 +15,6 @@ import com.aidanwhiteley.books.util.JwtAuthenticationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -67,7 +66,6 @@ public class BookSecureController { @Value("${books.users.max.page.size}") private int maxPageSize; - @Autowired public BookSecureController(BookRepository bookRepository, GoogleBooksDaoSync googleBooksDaoSync, GoogleBooksDaoAsync googleBooksDaoAsync, JwtAuthenticationUtils jwtAuthenticationUtils) { this.bookRepository = bookRepository; @@ -140,7 +138,7 @@ public ResponseEntity updateBook(@Valid @RequestBody Book book, Principal } @DeleteMapping(value = "/books/{id}") - public ResponseEntity deleteBookById(@PathVariable("id") String id, Principal principal) { + public ResponseEntity deleteBookById(@PathVariable String id, Principal principal) { Optional user = authUtils.extractUserFromPrincipal(principal, false); if (user.isPresent()) { @@ -159,7 +157,7 @@ public ResponseEntity deleteBookById(@PathVariable("id") String id, Princi } @PostMapping(value = "/books/{id}/comments") - public Book addCommentToBook(@PathVariable("id") String id, @Valid @RequestBody Comment comment, + public Book addCommentToBook(@PathVariable String id, @Valid @RequestBody Comment comment, Principal principal) { Optional user = authUtils.extractUserFromPrincipal(principal, false); @@ -173,7 +171,7 @@ public Book addCommentToBook(@PathVariable("id") String id, @Valid @RequestBody } @DeleteMapping(value = "/books/{id}/comments/{commentId}") - public Book removeCommentFromBook(@PathVariable("id") String id, @PathVariable("commentId") String commentId, + public Book removeCommentFromBook(@PathVariable String id, @PathVariable String commentId, Principal principal) { Optional user = authUtils.extractUserFromPrincipal(principal, false); @@ -203,15 +201,15 @@ public Book removeCommentFromBook(@PathVariable("id") String id, @PathVariable(" * least ROLE_EDITOR */ @GetMapping(value = {"/books", "/books/"}) - public Page findByReader(@RequestParam String reader, @RequestParam(value = "page", defaultValue = "0") int page, - @RequestParam(value = "size", defaultValue = "5") int size, Principal principal) { + public Page findByReader(@RequestParam String reader, @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "5") int size, Principal principal) { if (null == reader || reader.trim().isEmpty()) { throw new IllegalArgumentException("Reader parameter cannot be empty"); } if (size > maxPageSize) { - throw new IllegalArgumentException(String.format("Cannot request a page of data containing more that %s elements", maxPageSize)); + throw new IllegalArgumentException("Cannot request a page of data containing more that %s elements".formatted(maxPageSize)); } PageRequest pageObj = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdDateTime")); @@ -219,7 +217,7 @@ public Page findByReader(@RequestParam String reader, @RequestParam(value } @GetMapping(value = {"/googlebooks", "googlebooks/"}, params = "title") - public BookSearchResult findGoogleBooksByTitle(@RequestParam("title") String title) { + public BookSearchResult findGoogleBooksByTitle(@RequestParam String title) { return googleBooksDaoSync.searchGoogBooksByTitle(title); } diff --git a/src/main/java/com/aidanwhiteley/books/controller/FeedsController.java b/src/main/java/com/aidanwhiteley/books/controller/FeedsController.java index f54d9a0c..9184d0ff 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/FeedsController.java +++ b/src/main/java/com/aidanwhiteley/books/controller/FeedsController.java @@ -2,7 +2,6 @@ import com.aidanwhiteley.books.util.SiteRssFeed; import com.rometools.rome.feed.rss.Channel; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -13,7 +12,6 @@ public class FeedsController { private final SiteRssFeed siteRssFeed; - @Autowired public FeedsController(SiteRssFeed siteRssFeed) { this.siteRssFeed = siteRssFeed; } diff --git a/src/main/java/com/aidanwhiteley/books/controller/UserController.java b/src/main/java/com/aidanwhiteley/books/controller/UserController.java index 304e31cc..b35603c9 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/UserController.java +++ b/src/main/java/com/aidanwhiteley/books/controller/UserController.java @@ -8,7 +8,6 @@ import com.aidanwhiteley.books.util.JwtAuthenticationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -40,7 +39,6 @@ public class UserController { private final JwtAuthenticationService authService; - @Autowired public UserController(UserRepository userRepository, JwtAuthenticationUtils jwtAuthenticationUtils, JwtAuthenticationService jwtAuthenticationService) { this.userRepository = userRepository; @@ -80,7 +78,7 @@ public List users(Principal principal) { @DeleteMapping(value = "/users/{id}") @PreAuthorize("hasRole('ROLE_ADMIN')") - public ResponseEntity deleteUserById(@PathVariable("id") String id, Principal principal) { + public ResponseEntity deleteUserById(@PathVariable String id, Principal principal) { Optional user = authUtils.extractUserFromPrincipal(principal, false); if (user.isPresent()) { @@ -100,7 +98,7 @@ public ResponseEntity deleteUserById(@PathVariable("id") String id, Prin @PatchMapping(value = "/users/{id}") @PreAuthorize("hasRole('ROLE_ADMIN')") - public ResponseEntity patchUserRolesById(@PathVariable("id") String id, @RequestBody ClientRoles clientRoles, + public ResponseEntity patchUserRolesById(@PathVariable String id, @RequestBody ClientRoles clientRoles, Principal principal) { Optional user = authUtils.extractUserFromPrincipal(principal, false); diff --git a/src/main/java/com/aidanwhiteley/books/controller/aspect/LimitDataVisibilityAspect.java b/src/main/java/com/aidanwhiteley/books/controller/aspect/LimitDataVisibilityAspect.java index c0526d08..60350d74 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/aspect/LimitDataVisibilityAspect.java +++ b/src/main/java/com/aidanwhiteley/books/controller/aspect/LimitDataVisibilityAspect.java @@ -9,7 +9,6 @@ import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; @@ -45,7 +44,6 @@ public class LimitDataVisibilityAspect { private final JwtAuthenticationUtils authUtils; - @Autowired public LimitDataVisibilityAspect(JwtAuthenticationUtils jwtAuthenticationUtils) { this.authUtils = jwtAuthenticationUtils; } diff --git a/src/main/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepository.java b/src/main/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepository.java index e988f595..ca24ceb8 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/src/main/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -8,7 +8,6 @@ import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; @@ -31,7 +30,7 @@ class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationReq public static final String COOKIE_NAME = "cloudy-oauth2-auth"; - public HttpCookieOAuth2AuthorizationRequestRepository(@Autowired ObjectMapper authRequestJsonMapper) { + public HttpCookieOAuth2AuthorizationRequestRepository(ObjectMapper authRequestJsonMapper) { this.authRequestJsonMapper = authRequestJsonMapper; } diff --git a/src/main/java/com/aidanwhiteley/books/controller/config/WebSecurityConfiguration.java b/src/main/java/com/aidanwhiteley/books/controller/config/WebSecurityConfiguration.java index ccecf539..65ffa641 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/config/WebSecurityConfiguration.java +++ b/src/main/java/com/aidanwhiteley/books/controller/config/WebSecurityConfiguration.java @@ -12,7 +12,6 @@ import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.health.HealthEndpoint; @@ -48,6 +47,7 @@ import static com.aidanwhiteley.books.domain.User.Role.ROLE_ACTUATOR; import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.security.config.Customizer.withDefaults; @Configuration @EnableMethodSecurity() @@ -89,7 +89,6 @@ public class WebSecurityConfiguration { @Value("${books.client.postLogonUrl}") private String postLogonUrl; - @Autowired public WebSecurityConfiguration(JwtAuthenticationFilter jwtAuthenticationFilter, JwtAuthenticationService jwtAuthenticationService, UserService userService) { @@ -106,7 +105,6 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti // Normally only expected to be used in dev when there is no "front // proxy" of some sort if (enableCORS) { - http.cors(); } // Getting required server side config for enabling Angular to send X-CSRF-TOKEN request header across @@ -117,7 +115,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti // // So if using CORS, there's no XSRF protection! if (enableCORS) { - http.csrf().disable(); // lgtm [java/spring-disabled-csrf-protection] + http.csrf(csrf -> csrf.disable()); // lgtm [java/spring-disabled-csrf-protection] LOGGER.warn(""); LOGGER.warn("**********************************************************************"); LOGGER.warn("*** WARNING! ***"); @@ -136,36 +134,32 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti // The CSRF cookie is also read and sent by Angular - hence it being marked as not "httpOnly". // The JWT token is stored in a cookie that IS httpOnly. - http.csrf(). - csrfTokenRequestHandler(requestHandler). - csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); + http.csrf(csrf -> csrf. + csrfTokenRequestHandler(requestHandler). + csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())); } http - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).enableSessionUrlRewriting(false) - .and() + .sessionManagement(management -> management.sessionCreationPolicy(SessionCreationPolicy.STATELESS).enableSessionUrlRewriting(false)) .authorizeHttpRequests(authz -> - authz - // Make sure Actuator endpoints are protected - .requestMatchers(EndpointRequest.toAnyEndpoint().excluding(HealthEndpoint.class).excluding(InfoEndpoint.class)). - hasRole(ROLE_ACTUATOR.getShortName()) - // We permitAll here (getting us back to the Spring Boot 2 default) as we have method level security - // applied rather than request level - .anyRequest().permitAll() + authz + // Make sure Actuator endpoints are protected + .requestMatchers(EndpointRequest.toAnyEndpoint().excluding(HealthEndpoint.class).excluding(InfoEndpoint.class)). + hasRole(ROLE_ACTUATOR.getShortName()) + // We permitAll here (getting us back to the Spring Boot 2 default) as we have method level security + // applied rather than request level + .anyRequest().permitAll() ) - .exceptionHandling() - .defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS) - .and() + .exceptionHandling(handling -> handling + .defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)) .addFilterBefore(jwtAuththenticationFilter, UsernamePasswordAuthenticationFilter.class) - .oauth2Login() - .authorizationEndpoint().baseUri("/login") - .authorizationRequestRepository(cookieBasedAuthorizationRequestRepository()) - .and() - .successHandler(new Oauth2AuthenticationSuccessHandler()) - .and() - .formLogin().disable() - .httpBasic().disable() - .headers().referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN); + .oauth2Login(login -> login + .authorizationEndpoint(endpoint -> endpoint.baseUri("/login") + .authorizationRequestRepository(cookieBasedAuthorizationRequestRepository())) + .successHandler(new Oauth2AuthenticationSuccessHandler())) + .formLogin(login -> login.disable()) + .httpBasic(basic -> basic.disable()) + .headers(headers -> headers.referrerPolicy(policy -> policy.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN))); return http.build(); diff --git a/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationFilter.java b/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationFilter.java index 12aa3fab..c0f4bd11 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationFilter.java @@ -3,7 +3,6 @@ import com.aidanwhiteley.books.domain.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.lang.NonNull; import org.springframework.security.core.context.SecurityContextHolder; @@ -30,7 +29,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { @Value("${books.reload.development.data}") private boolean reloadDevelopmentData; - @Autowired public JwtAuthenticationFilter(JwtAuthenticationService jwtAuthenticationService) { this.jwtService = jwtAuthenticationService; } diff --git a/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationService.java b/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationService.java index dcba7d81..58591720 100644 --- a/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationService.java +++ b/src/main/java/com/aidanwhiteley/books/controller/jwt/JwtAuthenticationService.java @@ -4,7 +4,6 @@ import io.jsonwebtoken.ExpiredJwtException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -42,7 +41,6 @@ public class JwtAuthenticationService { @Value("${books.jwt.cookieSameSiteStrict}") private boolean cookieSameSiteStrict; - @Autowired public JwtAuthenticationService(JwtUtils jwtUtils) { this.jwtUtils = jwtUtils; } diff --git a/src/main/java/com/aidanwhiteley/books/domain/audit/BookAuditor.java b/src/main/java/com/aidanwhiteley/books/domain/audit/BookAuditor.java index fedc80cf..e1aca999 100644 --- a/src/main/java/com/aidanwhiteley/books/domain/audit/BookAuditor.java +++ b/src/main/java/com/aidanwhiteley/books/domain/audit/BookAuditor.java @@ -4,7 +4,6 @@ import com.aidanwhiteley.books.domain.User; import com.aidanwhiteley.books.repository.UserRepository; import com.aidanwhiteley.books.util.JwtAuthenticationUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.AuditorAware; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -20,7 +19,6 @@ public class BookAuditor implements AuditorAware { private final UserRepository userRepository; - @Autowired public BookAuditor(JwtAuthenticationUtils jwtAuthenticationUtils, UserRepository userRepository) { this.jwtAuthenticationUtils = jwtAuthenticationUtils; this.userRepository = userRepository; diff --git a/src/main/java/com/aidanwhiteley/books/repository/BookRepositoryImpl.java b/src/main/java/com/aidanwhiteley/books/repository/BookRepositoryImpl.java index df6c46a3..782cbc6d 100644 --- a/src/main/java/com/aidanwhiteley/books/repository/BookRepositoryImpl.java +++ b/src/main/java/com/aidanwhiteley/books/repository/BookRepositoryImpl.java @@ -11,7 +11,6 @@ import com.mongodb.client.result.UpdateResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -47,7 +46,6 @@ public class BookRepositoryImpl implements BookRepositoryCustomMethods { private final MongoTemplate mongoTemplate; - @Autowired public BookRepositoryImpl(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoAsync.java b/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoAsync.java index 098a4fac..402337ad 100644 --- a/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoAsync.java +++ b/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoAsync.java @@ -4,7 +4,6 @@ import com.aidanwhiteley.books.domain.googlebooks.Item; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.scheduling.annotation.Async; @@ -26,7 +25,6 @@ public class GoogleBooksDaoAsync extends GoogleBooksApiConfig { private final BookRepository bookRepository; private final GoogleBooksApiConfig googleBooksApiConfig; - @Autowired public GoogleBooksDaoAsync(BookRepository bookRepository, GoogleBooksApiConfig googleBooksApiConfig) { this.webClient = WebClient.builder() .defaultHeader(HttpHeaders.USER_AGENT, BOOKS_WEB_CLIENT) diff --git a/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoSync.java b/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoSync.java index 2416f1d4..4a331862 100644 --- a/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoSync.java +++ b/src/main/java/com/aidanwhiteley/books/repository/GoogleBooksDaoSync.java @@ -4,7 +4,6 @@ import com.aidanwhiteley.books.domain.googlebooks.Item; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.stereotype.Repository; @@ -24,7 +23,6 @@ public class GoogleBooksDaoSync { private final GoogleBooksApiConfig googleBooksApiConfig; private RestTemplate googleBooksRestTemplate; - @Autowired public GoogleBooksDaoSync(GoogleBooksApiConfig googleBooksApiConfig) { this.googleBooksApiConfig = googleBooksApiConfig; } diff --git a/src/main/java/com/aidanwhiteley/books/repository/UserRepositoryImpl.java b/src/main/java/com/aidanwhiteley/books/repository/UserRepositoryImpl.java index fe35296f..ad656a02 100644 --- a/src/main/java/com/aidanwhiteley/books/repository/UserRepositoryImpl.java +++ b/src/main/java/com/aidanwhiteley/books/repository/UserRepositoryImpl.java @@ -5,7 +5,6 @@ import com.mongodb.client.result.UpdateResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @@ -22,7 +21,6 @@ public class UserRepositoryImpl implements UserRepositoryCustomMethods { private final MongoTemplate mongoTemplate; - @Autowired public UserRepositoryImpl(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/src/main/java/com/aidanwhiteley/books/service/SignUpNotificationService.java b/src/main/java/com/aidanwhiteley/books/service/SignUpNotificationService.java index d24f342a..0c80b8fb 100644 --- a/src/main/java/com/aidanwhiteley/books/service/SignUpNotificationService.java +++ b/src/main/java/com/aidanwhiteley/books/service/SignUpNotificationService.java @@ -5,7 +5,6 @@ import com.aidanwhiteley.books.util.MailClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -24,7 +23,6 @@ public class SignUpNotificationService { private final UserRepository userRepository; private final MailClient mailClient; - @Autowired public SignUpNotificationService(UserRepository userRepository, MailClient mailClient) { this.userRepository = userRepository; this.mailClient = mailClient; diff --git a/src/main/java/com/aidanwhiteley/books/service/StatsService.java b/src/main/java/com/aidanwhiteley/books/service/StatsService.java index 85756ab0..e1c5f002 100644 --- a/src/main/java/com/aidanwhiteley/books/service/StatsService.java +++ b/src/main/java/com/aidanwhiteley/books/service/StatsService.java @@ -3,7 +3,6 @@ import com.aidanwhiteley.books.repository.BookRepository; import com.aidanwhiteley.books.repository.dtos.BooksByRating; import com.aidanwhiteley.books.service.dtos.SummaryStats; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -15,7 +14,6 @@ public class StatsService { private final BookRepository bookRepository; - @Autowired public StatsService(BookRepository bookRepository) { this.bookRepository = bookRepository; } diff --git a/src/main/java/com/aidanwhiteley/books/util/JwtAuthenticationUtils.java b/src/main/java/com/aidanwhiteley/books/util/JwtAuthenticationUtils.java index 24b9dda4..19d64c65 100644 --- a/src/main/java/com/aidanwhiteley/books/util/JwtAuthenticationUtils.java +++ b/src/main/java/com/aidanwhiteley/books/util/JwtAuthenticationUtils.java @@ -7,7 +7,6 @@ import com.aidanwhiteley.books.service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @@ -29,7 +28,6 @@ public class JwtAuthenticationUtils { private final JwtUtils jwtUtils; - @Autowired public JwtAuthenticationUtils(UserRepository userRepository, UserService userService, JwtUtils jwtUtils) { this.userRepository = userRepository; this.userService = userService; diff --git a/src/main/java/com/aidanwhiteley/books/util/MailClient.java b/src/main/java/com/aidanwhiteley/books/util/MailClient.java index 85b49da9..af737d72 100644 --- a/src/main/java/com/aidanwhiteley/books/util/MailClient.java +++ b/src/main/java/com/aidanwhiteley/books/util/MailClient.java @@ -3,7 +3,6 @@ import com.aidanwhiteley.books.domain.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.MailException; import org.springframework.mail.javamail.JavaMailSender; @@ -35,7 +34,6 @@ public class MailClient { @Value("${books.users.registrationAdminEmail.emailTo}") private String registrationAdminEmailTo; - @Autowired public MailClient(JavaMailSender mailSender) { this.mailSender = mailSender; } diff --git a/src/main/java/com/aidanwhiteley/books/util/Oauth2AuthenticationUtils.java b/src/main/java/com/aidanwhiteley/books/util/Oauth2AuthenticationUtils.java index 36d201f6..fdb622c0 100644 --- a/src/main/java/com/aidanwhiteley/books/util/Oauth2AuthenticationUtils.java +++ b/src/main/java/com/aidanwhiteley/books/util/Oauth2AuthenticationUtils.java @@ -4,7 +4,6 @@ import com.aidanwhiteley.books.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; @@ -34,7 +33,6 @@ public class Oauth2AuthenticationUtils { @Value("${spring.security.oauth2.client.registration.facebook.client-id}") private String facebookClientClientId; - @Autowired public Oauth2AuthenticationUtils(UserRepository userRepository, OAuth2AuthorizedClientService authorizedClientService) { this.userRepository = userRepository; this.authorizedClientService = authorizedClientService; diff --git a/src/main/java/com/aidanwhiteley/books/util/SiteRssFeed.java b/src/main/java/com/aidanwhiteley/books/util/SiteRssFeed.java index 765e82f5..04c41898 100644 --- a/src/main/java/com/aidanwhiteley/books/util/SiteRssFeed.java +++ b/src/main/java/com/aidanwhiteley/books/util/SiteRssFeed.java @@ -6,7 +6,6 @@ import com.rometools.rome.feed.rss.Content; import com.rometools.rome.feed.rss.Guid; import com.rometools.rome.feed.rss.Item; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -35,7 +34,6 @@ public class SiteRssFeed { private final BookRepository bookRepository; - @Autowired public SiteRssFeed(BookRepository bookRepository) { this.bookRepository = bookRepository; } diff --git a/src/main/java/com/aidanwhiteley/books/util/preprod/DataLoader.java b/src/main/java/com/aidanwhiteley/books/util/preprod/DataLoader.java index ef79bad9..b5e56390 100644 --- a/src/main/java/com/aidanwhiteley/books/util/preprod/DataLoader.java +++ b/src/main/java/com/aidanwhiteley/books/util/preprod/DataLoader.java @@ -4,7 +4,6 @@ import org.bson.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Bean; @@ -43,7 +42,6 @@ public class DataLoader { @Value("${books.autoAuthUser}") private boolean autoAuthUser; - @Autowired public DataLoader(MongoTemplate mongoTemplate, PreProdWarnings preProdWarnings, Environment environment) { this.template = mongoTemplate; this.preProdWarnings = preProdWarnings; diff --git a/src/main/java/com/aidanwhiteley/books/util/preprod/MongoJavaServerConfig.java b/src/main/java/com/aidanwhiteley/books/util/preprod/MongoJavaServerConfig.java index 93742ddf..8b75c64a 100644 --- a/src/main/java/com/aidanwhiteley/books/util/preprod/MongoJavaServerConfig.java +++ b/src/main/java/com/aidanwhiteley/books/util/preprod/MongoJavaServerConfig.java @@ -5,7 +5,6 @@ import com.mongodb.lang.NonNull; import de.bwaldvogel.mongo.MongoServer; import de.bwaldvogel.mongo.backend.memory.MemoryBackend; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; @@ -25,7 +24,6 @@ public class MongoJavaServerConfig extends AbstractMongoClientConfiguration { private static final String DB_NAME = "books-mongo-in-memory"; private final PreProdWarnings preProdWarnings; - @Autowired public MongoJavaServerConfig(PreProdWarnings preProdWarnings) { this.preProdWarnings = preProdWarnings; } diff --git a/src/main/java/com/aidanwhiteley/books/util/preprod/PreProdWarnings.java b/src/main/java/com/aidanwhiteley/books/util/preprod/PreProdWarnings.java index 8a7cfa7e..2d0795c3 100644 --- a/src/main/java/com/aidanwhiteley/books/util/preprod/PreProdWarnings.java +++ b/src/main/java/com/aidanwhiteley/books/util/preprod/PreProdWarnings.java @@ -2,7 +2,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; @@ -13,7 +12,6 @@ public class PreProdWarnings { private static final String SEPARATOR = "**********************************************************************"; private final Environment environment; - @Autowired public PreProdWarnings(Environment environment) { this.environment = environment; } @@ -47,6 +45,6 @@ public void displayMongoJavaServerWarningMessage() { } private String padRight(String s, int n) { - return String.format("%-" + n + "s", s); + return ("%-" + n + "s").formatted(s); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2d0787c0..a4bccde1 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -55,7 +55,10 @@ spring: register-management: off loadbalancer: ribbon: - enabled: false # RibbonLoadBalancerClient deprecated. This setting uses BlockingLoadBalancerClient + enabled: false + threads: + virtual: + enabled: true # RibbonLoadBalancerClient deprecated. This setting uses BlockingLoadBalancerClient # If running in containers we want to set a random port (i.e. override to set to 0) server: diff --git a/src/test/java/com/aidanwhiteley/books/controller/BookControllerTest.java b/src/test/java/com/aidanwhiteley/books/controller/BookControllerTest.java index f068f10a..b89a5956 100644 --- a/src/test/java/com/aidanwhiteley/books/controller/BookControllerTest.java +++ b/src/test/java/com/aidanwhiteley/books/controller/BookControllerTest.java @@ -286,19 +286,19 @@ void askForTooManyDataItems() { ResponseEntity response = testRestTemplate.exchange("/api/books/?author=someone&page=0&size=" + tooBig, HttpMethod.GET, null, String.class); assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); - assertTrue(response.toString().contains(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize))); + assertTrue(response.toString().contains(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize))); response = testRestTemplate.exchange("/api/books/?search=something&page=0&size=" + tooBig, HttpMethod.GET, null, String.class); assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); - assertTrue(response.toString().contains(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize))); + assertTrue(response.toString().contains(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize))); response = testRestTemplate.exchange("/api/books/?genre=somegenre&page=0&size=" + tooBig, HttpMethod.GET, null, String.class); assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); - assertTrue(response.toString().contains(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize))); + assertTrue(response.toString().contains(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize))); response = testRestTemplate.exchange("/api/books/?rating=great&page=0&size=" + tooBig, HttpMethod.GET, null, String.class); assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); - assertTrue(response.toString().contains(String.format(PAGE_REQUEST_TOO_BIG_MESSAGE, maxPageSize))); + assertTrue(response.toString().contains(PAGE_REQUEST_TOO_BIG_MESSAGE.formatted(maxPageSize))); } @Test diff --git a/src/test/java/com/aidanwhiteley/books/controller/BookControllerTestUtils.java b/src/test/java/com/aidanwhiteley/books/controller/BookControllerTestUtils.java index b3b06b56..26e00e1e 100644 --- a/src/test/java/com/aidanwhiteley/books/controller/BookControllerTestUtils.java +++ b/src/test/java/com/aidanwhiteley/books/controller/BookControllerTestUtils.java @@ -17,8 +17,8 @@ import java.time.LocalDateTime; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; public class BookControllerTestUtils { diff --git a/src/test/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepositoryTest.java b/src/test/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepositoryTest.java index c664cc31..491c51a8 100644 --- a/src/test/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepositoryTest.java +++ b/src/test/java/com/aidanwhiteley/books/controller/config/HttpCookieOAuth2AuthorizationRequestRepositoryTest.java @@ -6,7 +6,6 @@ import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; diff --git a/src/test/java/com/aidanwhiteley/books/service/UserServiceTest.java b/src/test/java/com/aidanwhiteley/books/service/UserServiceTest.java index 18ce5ade..43991686 100644 --- a/src/test/java/com/aidanwhiteley/books/service/UserServiceTest.java +++ b/src/test/java/com/aidanwhiteley/books/service/UserServiceTest.java @@ -4,12 +4,11 @@ import com.aidanwhiteley.books.repository.UserRepository; import com.aidanwhiteley.books.util.IntegrationTest; import com.aidanwhiteley.books.util.Oauth2AuthenticationUtils; -import org.junit.Rule; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.GrantedAuthority; @@ -32,6 +31,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; +@ExtendWith(MockitoExtension.class) class UserServiceTest extends IntegrationTest { private static final String DUMMY = "dummy"; @@ -39,9 +39,6 @@ class UserServiceTest extends IntegrationTest { private static final String NEW_USER_2 = "New User 2"; private static final String UPDATED_USER_1 = "Updated User 1"; private static final String UPDATED_USER_2 = "Updated User 2"; - - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); @Autowired private UserRepository userRepository; diff --git a/src/test/java/com/aidanwhiteley/books/util/IntegrationTest.java b/src/test/java/com/aidanwhiteley/books/util/IntegrationTest.java index cb0861b1..7b57986c 100644 --- a/src/test/java/com/aidanwhiteley/books/util/IntegrationTest.java +++ b/src/test/java/com/aidanwhiteley/books/util/IntegrationTest.java @@ -1,10 +1,7 @@ package com.aidanwhiteley.books.util; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"books.client.enableCORS=false"}) public abstract class IntegrationTest { diff --git a/src/test/java/com/aidanwhiteley/books/util/WithCorsBasicTest.java b/src/test/java/com/aidanwhiteley/books/util/WithCorsBasicTest.java index 58822022..968e5288 100644 --- a/src/test/java/com/aidanwhiteley/books/util/WithCorsBasicTest.java +++ b/src/test/java/com/aidanwhiteley/books/util/WithCorsBasicTest.java @@ -6,15 +6,12 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; import static org.junit.jupiter.api.Assertions.assertTrue; -@ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"books.client.enableCORS=true"}) class WithCorsBasicTest {