DATAREST-1535 - Adapt to changes in Spring Framework 5.3.
We now implement getPatternParser() in DelegatingHandlerMapping introduced in Spring 5.3. Adapt to changes in CORS handling.
This commit is contained in:
@@ -69,8 +69,7 @@ public class CorsIntegrationTests extends AbstractWebIntegrationTests {
|
|||||||
mvc.perform(options(findItems.expand().getHref()).header(HttpHeaders.ORIGIN, "http://far.far.example")
|
mvc.perform(options(findItems.expand().getHref()).header(HttpHeaders.ORIGIN, "http://far.far.example")
|
||||||
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
|
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
|
||||||
.andExpect(status().isOk()) //
|
.andExpect(status().isOk()) //
|
||||||
.andExpect(
|
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST"));
|
||||||
header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAREST-573
|
@Test // DATAREST-573
|
||||||
@@ -140,7 +139,6 @@ public class CorsIntegrationTests extends AbstractWebIntegrationTests {
|
|||||||
mvc.perform(options(authorsLink.expand().getHref()).header(HttpHeaders.ORIGIN, "http://not.so.far.example")
|
mvc.perform(options(authorsLink.expand().getHref()).header(HttpHeaders.ORIGIN, "http://not.so.far.example")
|
||||||
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
|
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
|
||||||
.andExpect(status().isOk()) //
|
.andExpect(status().isOk()) //
|
||||||
.andExpect(header().longValue(HttpHeaders.ACCESS_CONTROL_MAX_AGE, 1234)) //
|
|
||||||
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "http://not.so.far.example")) //
|
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "http://not.so.far.example")) //
|
||||||
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true")) //
|
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true")) //
|
||||||
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,PATCH,POST"));
|
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,PATCH,POST"));
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public class LocalConfigCorsIntegrationTests extends AbstractWebIntegrationTests
|
|||||||
mvc.perform(options(findItems.expand().getHref()).header(HttpHeaders.ORIGIN, "http://far.far.example")
|
mvc.perform(options(findItems.expand().getHref()).header(HttpHeaders.ORIGIN, "http://far.far.example")
|
||||||
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
|
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
|
||||||
.andExpect(status().isOk()) //
|
.andExpect(status().isOk()) //
|
||||||
.andExpect(
|
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST"));
|
||||||
header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package org.springframework.data.rest.webmvc;
|
|||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
@@ -37,11 +36,9 @@ import org.springframework.data.rest.core.mapping.ResourceMappings;
|
|||||||
import org.springframework.data.rest.core.mapping.ResourceMetadata;
|
import org.springframework.data.rest.core.mapping.ResourceMetadata;
|
||||||
import org.springframework.data.rest.webmvc.support.JpaHelper;
|
import org.springframework.data.rest.webmvc.support.JpaHelper;
|
||||||
import org.springframework.data.util.ProxyUtils;
|
import org.springframework.data.util.ProxyUtils;
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
|
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.util.StringValueResolver;
|
import org.springframework.util.StringValueResolver;
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
@@ -346,28 +343,7 @@ public class RepositoryRestHandlerMapping extends BasePathAwareHandlerMapping {
|
|||||||
|
|
||||||
CorsConfiguration config = new CorsConfiguration();
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
updateCorsConfig(config, typeAnnotation);
|
updateCorsConfig(config, typeAnnotation);
|
||||||
|
config.applyPermitDefaultValues();
|
||||||
if (CollectionUtils.isEmpty(config.getAllowedOrigins())) {
|
|
||||||
config.setAllowedOrigins(Arrays.asList(CrossOrigin.DEFAULT_ORIGINS));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(config.getAllowedMethods())) {
|
|
||||||
for (HttpMethod httpMethod : HttpMethod.values()) {
|
|
||||||
config.addAllowedMethod(httpMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(config.getAllowedHeaders())) {
|
|
||||||
config.setAllowedHeaders(Arrays.asList(CrossOrigin.DEFAULT_ALLOWED_HEADERS));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.getAllowCredentials() == null) {
|
|
||||||
config.setAllowCredentials(CrossOrigin.DEFAULT_ALLOW_CREDENTIALS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.getMaxAge() == null) {
|
|
||||||
config.setMaxAge(CrossOrigin.DEFAULT_MAX_AGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.springframework.web.servlet.HandlerExecutionChain;
|
|||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.servlet.handler.MatchableHandlerMapping;
|
import org.springframework.web.servlet.handler.MatchableHandlerMapping;
|
||||||
import org.springframework.web.servlet.handler.RequestMatchResult;
|
import org.springframework.web.servlet.handler.RequestMatchResult;
|
||||||
|
import org.springframework.web.util.pattern.PathPatternParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link HandlerMapping} that considers a {@link List} of delegates. It will keep on traversing the delegates in case
|
* A {@link HandlerMapping} that considers a {@link List} of delegates. It will keep on traversing the delegates in case
|
||||||
@@ -89,6 +90,14 @@ public class DelegatingHandlerMapping implements HandlerMapping, Ordered, Matcha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.web.servlet.handler.MatchableHandlerMapping#getPatternParser()
|
||||||
|
*/
|
||||||
|
public PathPatternParser getPatternParser() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Value
|
@Value
|
||||||
private static class HandlerSelectionResult {
|
private static class HandlerSelectionResult {
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
import org.springframework.data.repository.support.Repositories;
|
import org.springframework.data.repository.support.Repositories;
|
||||||
import org.springframework.data.rest.core.mapping.ResourceMappings;
|
import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||||
import org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.NoOpStringValueResolver;
|
import org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.NoOpStringValueResolver;
|
||||||
@@ -62,11 +61,10 @@ public class RepositoryCorsConfigurationAccessorUnitTests {
|
|||||||
CorsConfiguration configuration = accessor.createConfiguration(AnnotatedRepository.class);
|
CorsConfiguration configuration = accessor.createConfiguration(AnnotatedRepository.class);
|
||||||
|
|
||||||
assertThat(configuration).isNotNull();
|
assertThat(configuration).isNotNull();
|
||||||
assertThat(configuration.getAllowCredentials()).isFalse();
|
assertThat(configuration.getAllowCredentials()).isNull();
|
||||||
assertThat(configuration.getAllowedHeaders()).contains("*");
|
assertThat(configuration.getAllowedHeaders()).contains("*");
|
||||||
assertThat(configuration.getAllowedOrigins()).contains("*");
|
assertThat(configuration.getAllowedOrigins()).contains("*");
|
||||||
assertThat(configuration.getAllowedMethods()).contains("OPTIONS", "HEAD", "GET", "PATCH", "POST", "PUT", "DELETE",
|
assertThat(configuration.getAllowedMethods()).contains("HEAD", "GET", "POST");
|
||||||
"TRACE");
|
|
||||||
assertThat(configuration.getMaxAge()).isEqualTo(1800L);
|
assertThat(configuration.getMaxAge()).isEqualTo(1800L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import static org.mockito.Mockito.*;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -69,7 +71,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
@Mock Repositories repositories;
|
@Mock Repositories repositories;
|
||||||
|
|
||||||
RepositoryRestConfiguration configuration;
|
RepositoryRestConfiguration configuration;
|
||||||
RepositoryRestHandlerMapping handlerMapping;
|
HandlerMappingStub handlerMapping;
|
||||||
MockHttpServletRequest mockRequest;
|
MockHttpServletRequest mockRequest;
|
||||||
Method listEntitiesMethod, rootHandlerMethod;
|
Method listEntitiesMethod, rootHandlerMethod;
|
||||||
|
|
||||||
@@ -79,7 +81,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
configuration = new RepositoryRestConfiguration(new ProjectionDefinitionConfiguration(),
|
configuration = new RepositoryRestConfiguration(new ProjectionDefinitionConfiguration(),
|
||||||
new MetadataConfiguration(), mock(EnumTranslationConfiguration.class));
|
new MetadataConfiguration(), mock(EnumTranslationConfiguration.class));
|
||||||
|
|
||||||
handlerMapping = new RepositoryRestHandlerMapping(mappings, configuration, repositories);
|
handlerMapping = new HandlerMappingStub(mappings, configuration, repositories);
|
||||||
handlerMapping.setApplicationContext(CONTEXT);
|
handlerMapping.setApplicationContext(CONTEXT);
|
||||||
|
|
||||||
mockRequest = new MockHttpServletRequest();
|
mockRequest = new MockHttpServletRequest();
|
||||||
@@ -103,7 +105,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
public void returnsNullForUriNotMapped() throws Exception {
|
public void returnsNullForUriNotMapped() throws Exception {
|
||||||
|
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
assertThat(handlerMapping.lookupHandlerMethod("/foo", mockRequest)).isNull();
|
assertThat(handlerMapping.getHandler(mockRequest)).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAREST-111
|
@Test // DATAREST-111
|
||||||
@@ -113,7 +115,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
mockRequest = new MockHttpServletRequest("GET", "/people");
|
mockRequest = new MockHttpServletRequest("GET", "/people");
|
||||||
|
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
HandlerMethod method = handlerMapping.lookupHandlerMethod("/people", mockRequest);
|
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(method).isNotNull();
|
assertThat(method).isNotNull();
|
||||||
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
||||||
@@ -128,7 +130,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
configuration.setBasePath("/base");
|
configuration.setBasePath("/base");
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
|
|
||||||
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base/people", mockRequest);
|
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(method).isNotNull();
|
assertThat(method).isNotNull();
|
||||||
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
||||||
@@ -142,7 +144,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
configuration.setBasePath("/base");
|
configuration.setBasePath("/base");
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
|
|
||||||
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base", mockRequest);
|
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(method).isNotNull();
|
assertThat(method).isNotNull();
|
||||||
assertThat(method.getMethod()).isEqualTo(rootHandlerMethod);
|
assertThat(method.getMethod()).isEqualTo(rootHandlerMethod);
|
||||||
@@ -157,7 +159,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
configuration.setBasePath("/base");
|
configuration.setBasePath("/base");
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
|
|
||||||
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base/people/", mockRequest);
|
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(method).isNotNull();
|
assertThat(method).isNotNull();
|
||||||
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
||||||
@@ -173,7 +175,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
configuration.setBasePath("/base");
|
configuration.setBasePath("/base");
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
|
|
||||||
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base/people", mockRequest);
|
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(method).isNotNull();
|
assertThat(method).isNotNull();
|
||||||
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
|
||||||
@@ -187,7 +189,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
|
|
||||||
configuration.setBasePath("/base");
|
configuration.setBasePath("/base");
|
||||||
|
|
||||||
HandlerMethod method = handlerMapping.lookupHandlerMethod("/servlet-path", mockRequest);
|
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(method).isNull();
|
assertThat(method).isNull();
|
||||||
}
|
}
|
||||||
@@ -204,7 +206,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
|
|
||||||
configuration.setBasePath(baseUri);
|
configuration.setBasePath(baseUri);
|
||||||
|
|
||||||
HandlerMethod method = handlerMapping.lookupHandlerMethod("/people", mockRequest);
|
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(method).isNull();
|
assertThat(method).isNull();
|
||||||
}
|
}
|
||||||
@@ -280,7 +282,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", "/people/search/findByLastnameLike");
|
MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", "/people/search/findByLastnameLike");
|
||||||
|
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
handlerMapping.lookupHandlerMethod("/people/search/findByLastnameLike", mockRequest);
|
handlerMapping.getHandlerInternal(mockRequest);
|
||||||
|
|
||||||
assertThat(mockRequest.getAttribute(RepositoryRestHandlerMapping.EFFECTIVE_LOOKUP_PATH_ATTRIBUTE)) //
|
assertThat(mockRequest.getAttribute(RepositoryRestHandlerMapping.EFFECTIVE_LOOKUP_PATH_ATTRIBUTE)) //
|
||||||
.isInstanceOfSatisfying(PathPattern.class, it -> {
|
.isInstanceOfSatisfying(PathPattern.class, it -> {
|
||||||
@@ -299,8 +301,7 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
|
|
||||||
handlerMapping.afterPropertiesSet();
|
handlerMapping.afterPropertiesSet();
|
||||||
|
|
||||||
assertThatCode(() -> handlerMapping.lookupHandlerMethod("/people/search", request)) //
|
assertThatCode(() -> handlerMapping.getHandlerInternal(request)).doesNotThrowAnyException();
|
||||||
.doesNotThrowAnyException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Class<?> createProxy(Object source) {
|
private static Class<?> createProxy(Object source) {
|
||||||
@@ -322,9 +323,23 @@ public class RepositoryRestHandlerMappingUnitTests {
|
|||||||
super(mappings, configuration);
|
super(mappings, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HandlerMappingStub(ResourceMappings mappings, RepositoryRestConfiguration configuration,
|
||||||
|
Repositories repositories) {
|
||||||
|
super(mappings, configuration, repositories);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isHandler(Class<?> beanType) {
|
public boolean isHandler(Class<?> beanType) {
|
||||||
return super.isHandler(beanType);
|
return super.isHandler(beanType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#getHandlerInternal(javax.servlet.http.HttpServletRequest)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
|
||||||
|
return super.getHandlerInternal(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ public class DelegatingHandlerMappingUnitTests {
|
|||||||
// Given:
|
// Given:
|
||||||
// A matching mapping that doesn't get selected
|
// A matching mapping that doesn't get selected
|
||||||
MatchableHandlerMapping third = mock(MatchableHandlerMapping.class);
|
MatchableHandlerMapping third = mock(MatchableHandlerMapping.class);
|
||||||
doReturn(mock(RequestMatchResult.class)).when(third).match(any(), any());
|
doReturn(mock(RequestMatchResult.class)).when(third).match(any(), any(String.class));
|
||||||
|
|
||||||
// A matching mapping that gets selected
|
// A matching mapping that gets selected
|
||||||
RequestMatchResult result = mock(RequestMatchResult.class);
|
RequestMatchResult result = mock(RequestMatchResult.class);
|
||||||
MatchableHandlerMapping fourth = mock(MatchableHandlerMapping.class, Answers.RETURNS_MOCKS);
|
MatchableHandlerMapping fourth = mock(MatchableHandlerMapping.class, Answers.RETURNS_MOCKS);
|
||||||
doReturn(result).when(fourth).match(any(), any());
|
doReturn(result).when(fourth).match(any(), any(String.class));
|
||||||
|
|
||||||
DelegatingHandlerMapping mapping = new DelegatingHandlerMapping(Arrays.asList(first, second, third, fourth));
|
DelegatingHandlerMapping mapping = new DelegatingHandlerMapping(Arrays.asList(first, second, third, fourth));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user