Skip to content

Commit 899b4b4

Browse files
authored
Merge pull request #1288 from amvanbaren/spring-boot-v3.5.3
Update Spring Boot to 3.5.3
2 parents 7dda317 + 421d628 commit 899b4b4

18 files changed

+130
-80
lines changed

server/build.gradle

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
id 'jacoco'
1212
id 'nu.studer.jooq' version '8.2.1'
1313
id 'de.undercouch.download' version '5.4.0'
14-
id 'org.springframework.boot' version '3.3.11'
14+
id 'org.springframework.boot' version '3.5.3'
1515
id 'io.spring.dependency-management' version '1.1.0'
1616
id 'io.gatling.gradle' version '3.9.5'
1717
id 'java'
@@ -38,7 +38,6 @@ def versions = [
3838
tika: '3.1.0',
3939
bouncycastle: '1.80',
4040
commons_lang3: '3.12.0',
41-
httpclient5: '5.2.1',
4241
jaxb_api: '2.3.1',
4342
jaxb_impl: '2.3.8',
4443
gatling: '3.13.5',
@@ -107,7 +106,7 @@ dependencies {
107106
implementation "javax.xml.bind:jaxb-api:${versions.jaxb_api}"
108107
implementation "com.sun.xml.bind:jaxb-impl:${versions.jaxb_impl}"
109108
implementation "org.apache.commons:commons-lang3:${versions.commons_lang3}"
110-
implementation "org.apache.httpcomponents.client5:httpclient5:${versions.httpclient5}"
109+
implementation "org.apache.httpcomponents.client5:httpclient5"
111110
implementation "org.apache.tika:tika-core:${versions.tika}"
112111
implementation "com.github.loki4j:loki-logback-appender:${versions.loki4j}"
113112
implementation "io.micrometer:micrometer-tracing"

server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* ****************************************************************************** */
1010
package org.eclipse.openvsx.migration;
1111

12+
import io.micrometer.common.util.StringUtils;
1213
import org.eclipse.openvsx.admin.RemoveFileJobRequest;
1314
import org.eclipse.openvsx.entities.ExtensionVersion;
1415
import org.eclipse.openvsx.entities.FileResource;
@@ -63,8 +64,10 @@ public void run(HandlerJobRequest<?> jobRequest) throws Exception {
6364
deleteKeyPairs();
6465
break;
6566
default:
66-
var values = String.join(",", KEYPAIR_MODE_CREATE, KEYPAIR_MODE_RENEW, KEYPAIR_MODE_DELETE);
67-
throw new IllegalArgumentException("Unsupported value for 'ovsx.integrity.key-pair' defined. Supported values are: " + values);
67+
if(StringUtils.isNotEmpty(keyPairMode)) {
68+
var values = String.join(",", KEYPAIR_MODE_CREATE, KEYPAIR_MODE_RENEW, KEYPAIR_MODE_DELETE);
69+
throw new IllegalArgumentException("Unsupported value '" + keyPairMode + "' for 'ovsx.integrity.key-pair' defined. Supported values are: " + values);
70+
}
6871
}
6972
}
7073

server/src/main/java/org/eclipse/openvsx/search/DatabaseSearchService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.scheduling.annotation.Async;
2727
import org.springframework.stereotype.Component;
2828

29+
import java.time.Duration;
2930
import java.util.*;
3031
import java.util.stream.Stream;
3132

@@ -70,7 +71,7 @@ public SearchHits<ExtensionSearch> search(ISearchService.Options options) {
7071
.map(extensionSearch -> new SearchHit<>(null, null, null, 0.0f, null, null, null, null, null, null, extensionSearch))
7172
.toList();
7273

73-
return new SearchHitsImpl<>(totalHits, TotalHitsRelation.OFF, 0f, null, null, searchHits, null, null, null);
74+
return new SearchHitsImpl<>(totalHits, TotalHitsRelation.OFF, 0f, Duration.ZERO, null, null, searchHits, null, null, null);
7475
}
7576

7677
private List<ExtensionSearch> applyPaging(Options options, List<ExtensionSearch> sortedExtensions) {

server/src/main/java/org/eclipse/openvsx/search/ElasticSearchService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.springframework.stereotype.Component;
4242
import org.springframework.util.StopWatch;
4343

44+
import java.time.Duration;
4445
import java.time.ZoneId;
4546
import java.util.*;
4647
import java.util.concurrent.locks.ReadWriteLock;
@@ -249,7 +250,7 @@ public void removeSearchEntry(Extension extension) {
249250
public SearchHits<ExtensionSearch> search(Options options) {
250251
var resultWindow = options.requestedOffset() + options.requestedSize();
251252
if(resultWindow > getMaxResultWindow()) {
252-
return new SearchHitsImpl<>(0, TotalHitsRelation.OFF, 0f, null, null, Collections.emptyList(), null, null, null);
253+
return new SearchHitsImpl<>(0, TotalHitsRelation.OFF, 0f, Duration.ZERO, null, null, Collections.emptyList(), null, null, null);
253254
}
254255

255256
var queryBuilder = new NativeQueryBuilder();
@@ -291,6 +292,7 @@ public SearchHits<ExtensionSearch> search(Options options) {
291292
firstSearchHitsPage.getTotalHits(),
292293
firstSearchHitsPage.getTotalHitsRelation(),
293294
firstSearchHitsPage.getMaxScore(),
295+
Duration.ZERO,
294296
null,
295297
null,
296298
searchHits,

server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
1818
import org.springframework.security.web.SecurityFilterChain;
1919
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
20-
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
20+
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
2121
import org.springframework.security.web.util.matcher.RequestMatcher;
2222

2323
@Configuration
@@ -34,21 +34,21 @@ public class SecurityConfig {
3434
public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices userServices) throws Exception {
3535
var filterChain = http.authorizeHttpRequests(
3636
registry -> registry
37-
.requestMatchers(antMatchers("/*", "/login/**", "/oauth2/**", "/login-providers", "/user", "/user/auth-error", "/logout", "/actuator/health/**", "/actuator/metrics", "/actuator/metrics/**", "/actuator/prometheus", "/v3/api-docs/**", "/swagger-resources/**", "/swagger-ui/**", "/webjars/**"))
37+
.requestMatchers(pathMatchers("/*", "/login/**", "/oauth2/**", "/login-providers", "/user", "/user/auth-error", "/logout", "/actuator/health/**", "/actuator/metrics", "/actuator/metrics/**", "/actuator/prometheus", "/v3/api-docs/**", "/swagger-resources/**", "/swagger-ui/**", "/webjars/**"))
3838
.permitAll()
39-
.requestMatchers(antMatchers("/api/*/*/review", "/api/*/*/review/delete", "/api/user/publish", "/api/user/namespace/create"))
39+
.requestMatchers(pathMatchers("/api/*/*/review", "/api/*/*/review/delete", "/api/user/publish", "/api/user/namespace/create"))
4040
.authenticated()
41-
.requestMatchers(antMatchers("/api/**", "/vscode/**", "/documents/**", "/admin/api/**", "/admin/report"))
41+
.requestMatchers(pathMatchers("/api/**", "/vscode/**", "/documents/**", "/admin/api/**", "/admin/report"))
4242
.permitAll()
43-
.requestMatchers(antMatchers("/admin/**"))
43+
.requestMatchers(pathMatchers("/admin/**"))
4444
.hasAuthority("ROLE_ADMIN")
45-
.requestMatchers(antMatchers(frontendRoutes))
45+
.requestMatchers(pathMatchers(frontendRoutes))
4646
.permitAll()
4747
.anyRequest()
4848
.authenticated()
4949
)
5050
.cors(configurer -> configurer.configure(http))
51-
.csrf(configurer -> configurer.ignoringRequestMatchers(antMatchers("/api/-/publish", "/api/-/namespace/create", "/api/-/query", "/vscode/**", "/admin/api/**")))
51+
.csrf(configurer -> configurer.ignoringRequestMatchers(pathMatchers("/api/-/publish", "/api/-/namespace/create", "/api/-/query", "/vscode/**", "/admin/api/**")))
5252
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(new Http403ForbiddenEntryPoint()));
5353

5454
if(userServices.canLogin()) {
@@ -65,13 +65,13 @@ public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices use
6565
return filterChain.build();
6666
}
6767

68-
private RequestMatcher[] antMatchers(String... patterns)
68+
private RequestMatcher[] pathMatchers(String... patterns)
6969
{
70-
var antMatchers = new RequestMatcher[patterns.length];
70+
var pathMatchers = new RequestMatcher[patterns.length];
7171
for(var i = 0; i < patterns.length; i++) {
72-
antMatchers[i] = AntPathRequestMatcher.antMatcher(patterns[i]);
72+
pathMatchers[i] = PathPatternRequestMatcher.withDefaults().matcher(patterns[i]);
7373
}
7474

75-
return antMatchers;
75+
return pathMatchers;
7676
}
7777
}

server/src/test/java/org/eclipse/openvsx/IntegrationTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.boot.test.web.server.LocalServerPort;
2323
import org.springframework.http.HttpStatus;
2424
import org.springframework.test.context.ActiveProfiles;
25+
import org.springframework.web.client.RestTemplate;
2526

2627
import javax.cache.CacheManager;
2728
import java.io.IOException;
@@ -44,6 +45,9 @@ class IntegrationTest {
4445
@Autowired
4546
TestRestTemplate restTemplate;
4647

48+
@Autowired
49+
RestTemplate nonRedirectingRestTemplate;
50+
4751
@Autowired
4852
TestService testService;
4953

@@ -218,7 +222,7 @@ private void searchExtension() {
218222

219223
void getVscodeDownloadLink() throws URISyntaxException {
220224
var path = "/vscode/gallery/publishers/editorconfig/vsextensions/editorconfig/0.16.6/vspackage";
221-
var response = restTemplate.getForEntity(apiCall(path), String.class);
225+
var response = nonRedirectingRestTemplate.getForEntity(apiCall(path), String.class);
222226
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FOUND);
223227
var expectedPath = "/vscode/asset/EditorConfig/EditorConfig/0.16.6/Microsoft.VisualStudio.Services.VSIXPackage";
224228
assertThat(response.getHeaders().getLocation()).isEqualTo(new URI(apiCall(expectedPath)));

server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747
import org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient;
4848
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
4949
import org.springframework.boot.test.context.TestConfiguration;
50-
import org.springframework.boot.test.mock.mockito.MockBean;
51-
import org.springframework.boot.test.mock.mockito.SpyBean;
5250
import org.springframework.context.annotation.Bean;
5351
import org.springframework.context.annotation.Import;
5452
import org.springframework.data.domain.Page;
@@ -60,6 +58,8 @@
6058
import org.springframework.data.util.Streamable;
6159
import org.springframework.http.MediaType;
6260
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
61+
import org.springframework.test.context.bean.override.mockito.MockitoBean;
62+
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
6363
import org.springframework.test.web.servlet.MockMvc;
6464
import org.springframework.test.web.servlet.MvcResult;
6565
import org.springframework.transaction.support.TransactionTemplate;
@@ -68,6 +68,7 @@
6868
import java.io.IOException;
6969
import java.nio.file.Files;
7070
import java.nio.file.Path;
71+
import java.time.Duration;
7172
import java.time.LocalDateTime;
7273
import java.util.*;
7374
import java.util.function.BiFunction;
@@ -87,27 +88,27 @@
8788

8889
@WebMvcTest(RegistryAPI.class)
8990
@AutoConfigureWebClient
90-
@MockBean({
91+
@MockitoBean(types = {
9192
ClientRegistrationRepository.class, UpstreamRegistryService.class, GoogleCloudStorageService.class,
9293
AzureBlobStorageService.class, AwsStorageService.class, VSCodeIdService.class, AzureDownloadCountService.class,
9394
CacheService.class, EclipseService.class, PublishExtensionVersionService.class, SimpleMeterRegistry.class,
9495
JobRequestScheduler.class, ExtensionControlService.class, FileCacheDurationConfig.class
9596
})
9697
class RegistryAPITest {
9798

98-
@SpyBean
99+
@MockitoSpyBean
99100
UserService users;
100101

101-
@MockBean
102+
@MockitoBean
102103
RepositoryService repositories;
103104

104-
@MockBean
105+
@MockitoBean
105106
SearchUtilService search;
106107

107-
@MockBean
108+
@MockitoBean
108109
ExtensionVersionIntegrityService integrityService;
109110

110-
@MockBean
111+
@MockitoBean
111112
EntityManager entityManager;
112113

113114
@Autowired
@@ -2184,7 +2185,7 @@ private List<ExtensionVersion> mockSearch() {
21842185
var entry1 = new ExtensionSearch();
21852186
entry1.setId(1);
21862187
var searchHit = new SearchHit<>("0", "1", null, 1.0f, null, null, null, null, null, null, entry1);
2187-
var searchHits = new SearchHitsImpl<>(1, TotalHitsRelation.EQUAL_TO, 1.0f, "1", null, List.of(searchHit), null, null, null);
2188+
var searchHits = new SearchHitsImpl<>(1, TotalHitsRelation.EQUAL_TO, 1.0f, Duration.ZERO, null, null, List.of(searchHit), null, null, null);
21882189
Mockito.when(search.isEnabled())
21892190
.thenReturn(true);
21902191
var searchOptions = new ISearchService.Options("foo", null, null, 10, 0, "desc", "relevance", false, null);
@@ -2389,6 +2390,19 @@ TransactionTemplate transactionTemplate() {
23892390
return new MockTransactionTemplate();
23902391
}
23912392

2393+
@Bean
2394+
UserService userService(
2395+
EntityManager entityManager,
2396+
RepositoryService repositories,
2397+
StorageUtilService storageUtil,
2398+
CacheService cache,
2399+
ExtensionValidator validator,
2400+
@Autowired(required = false) ClientRegistrationRepository clientRegistrationRepository,
2401+
OAuth2AttributesConfig attributesConfig
2402+
) {
2403+
return new UserService(entityManager, repositories, storageUtil, cache, validator, clientRegistrationRepository, attributesConfig);
2404+
}
2405+
23922406
@Bean
23932407
OAuth2UserServices oauth2UserServices(
23942408
UserService users,

server/src/test/java/org/eclipse/openvsx/UserAPITest.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@
3333
import org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient;
3434
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
3535
import org.springframework.boot.test.context.TestConfiguration;
36-
import org.springframework.boot.test.mock.mockito.MockBean;
37-
import org.springframework.boot.test.mock.mockito.SpyBean;
3836
import org.springframework.context.annotation.Bean;
3937
import org.springframework.context.annotation.Import;
4038
import org.springframework.data.util.Streamable;
4139
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
40+
import org.springframework.test.context.bean.override.mockito.MockitoBean;
41+
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
4242
import org.springframework.test.web.servlet.MockMvc;
4343
import org.springframework.transaction.support.TransactionTemplate;
4444

@@ -57,19 +57,19 @@
5757

5858
@WebMvcTest(UserAPI.class)
5959
@AutoConfigureWebClient
60-
@MockBean({
60+
@MockitoBean(types = {
6161
EclipseService.class, ClientRegistrationRepository.class, StorageUtilService.class, CacheService.class,
6262
ExtensionValidator.class, SimpleMeterRegistry.class
6363
})
6464
class UserAPITest {
6565

66-
@SpyBean
66+
@MockitoSpyBean
6767
UserService users;
6868

69-
@MockBean
69+
@MockitoBean
7070
EntityManager entityManager;
7171

72-
@MockBean
72+
@MockitoBean
7373
RepositoryService repositories;
7474

7575
@Autowired
@@ -550,6 +550,19 @@ TransactionTemplate transactionTemplate() {
550550
return new MockTransactionTemplate();
551551
}
552552

553+
@Bean
554+
UserService userService(
555+
EntityManager entityManager,
556+
RepositoryService repositories,
557+
StorageUtilService storageUtil,
558+
CacheService cache,
559+
ExtensionValidator validator,
560+
@Autowired(required = false) ClientRegistrationRepository clientRegistrationRepository,
561+
OAuth2AttributesConfig attributesConfig
562+
) {
563+
return new UserService(entityManager, repositories, storageUtil, cache, validator, clientRegistrationRepository, attributesConfig);
564+
}
565+
553566
@Bean
554567
OAuth2UserServices oauth2UserServices(
555568
UserService users,

server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient;
4141
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
4242
import org.springframework.boot.test.context.TestConfiguration;
43-
import org.springframework.boot.test.mock.mockito.MockBean;
4443
import org.springframework.context.annotation.Bean;
4544
import org.springframework.context.annotation.Import;
4645
import org.springframework.data.elasticsearch.core.SearchHit;
@@ -49,6 +48,7 @@
4948
import org.springframework.data.util.Streamable;
5049
import org.springframework.http.MediaType;
5150
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
51+
import org.springframework.test.context.bean.override.mockito.MockitoBean;
5252
import org.springframework.test.web.servlet.MockMvc;
5353
import org.springframework.test.web.servlet.MvcResult;
5454
import org.springframework.transaction.support.TransactionTemplate;
@@ -59,6 +59,7 @@
5959
import java.nio.file.Files;
6060
import java.nio.file.Path;
6161
import java.nio.file.StandardCopyOption;
62+
import java.time.Duration;
6263
import java.time.LocalDateTime;
6364
import java.util.*;
6465
import java.util.stream.Collectors;
@@ -72,24 +73,24 @@
7273

7374
@WebMvcTest(VSCodeAPI.class)
7475
@AutoConfigureWebClient
75-
@MockBean({
76+
@MockitoBean( types = {
7677
ClientRegistrationRepository.class, GoogleCloudStorageService.class, AzureBlobStorageService.class,
7778
AwsStorageService.class, AzureDownloadCountService.class, CacheService.class, UpstreamVSCodeService.class,
78-
VSCodeIdService.class, EntityManager.class, EclipseService.class, ExtensionValidator.class, SimpleMeterRegistry.class,
79+
VSCodeIdService.class, EclipseService.class, ExtensionValidator.class, SimpleMeterRegistry.class,
7980
FileCacheDurationConfig.class
8081
})
8182
class VSCodeAPITest {
8283

83-
@MockBean
84+
@MockitoBean
8485
EntityManager entityManager;
8586

86-
@MockBean
87+
@MockitoBean
8788
RepositoryService repositories;
8889

89-
@MockBean
90+
@MockitoBean
9091
SearchUtilService search;
9192

92-
@MockBean
93+
@MockitoBean
9394
ExtensionVersionIntegrityService integrityService;
9495

9596
@Autowired
@@ -632,7 +633,7 @@ private Extension mockSearch(String targetPlatform, String namespaceName, boolea
632633
List<SearchHit<ExtensionSearch>> searchResults = !builtInExtensionNamespace.equals(namespaceName)
633634
? Collections.singletonList(new SearchHit<>("0", "1", null, 1.0f, null, null, null, null, null, null, entry1))
634635
: Collections.emptyList();
635-
var searchHits = new SearchHitsImpl<>(searchResults.size(), TotalHitsRelation.EQUAL_TO, 1.0f, "1", null,
636+
var searchHits = new SearchHitsImpl<>(searchResults.size(), TotalHitsRelation.EQUAL_TO, 1.0f, Duration.ZERO, null, null,
636637
searchResults, null, null, null);
637638

638639
Mockito.when(integrityService.isEnabled())

0 commit comments

Comments
 (0)