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:
Oliver Drotbohm
2020-06-24 15:17:32 +02:00
parent 46f2171b49
commit a9576991fe
7 changed files with 44 additions and 49 deletions

View File

@@ -69,8 +69,7 @@ public class CorsIntegrationTests extends AbstractWebIntegrationTests {
mvc.perform(options(findItems.expand().getHref()).header(HttpHeaders.ORIGIN, "http://far.far.example")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
.andExpect(status().isOk()) //
.andExpect(
header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE"));
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST"));
}
@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")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
.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_CREDENTIALS, "true")) //
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,PATCH,POST"));

View File

@@ -56,7 +56,6 @@ public class LocalConfigCorsIntegrationTests extends AbstractWebIntegrationTests
mvc.perform(options(findItems.expand().getHref()).header(HttpHeaders.ORIGIN, "http://far.far.example")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
.andExpect(status().isOk()) //
.andExpect(
header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE"));
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD,POST"));
}
}

View File

@@ -18,7 +18,6 @@ package org.springframework.data.rest.webmvc;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
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.webmvc.support.JpaHelper;
import org.springframework.data.util.ProxyUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
import org.springframework.web.bind.annotation.CrossOrigin;
@@ -346,28 +343,7 @@ public class RepositoryRestHandlerMapping extends BasePathAwareHandlerMapping {
CorsConfiguration config = new CorsConfiguration();
updateCorsConfig(config, typeAnnotation);
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);
}
config.applyPermitDefaultValues();
return config;
}

View File

@@ -33,6 +33,7 @@ import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.MatchableHandlerMapping;
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
@@ -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
private static class HandlerSelectionResult {

View File

@@ -25,7 +25,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.repository.support.Repositories;
import org.springframework.data.rest.core.mapping.ResourceMappings;
import org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.NoOpStringValueResolver;
@@ -62,11 +61,10 @@ public class RepositoryCorsConfigurationAccessorUnitTests {
CorsConfiguration configuration = accessor.createConfiguration(AnnotatedRepository.class);
assertThat(configuration).isNotNull();
assertThat(configuration.getAllowCredentials()).isFalse();
assertThat(configuration.getAllowCredentials()).isNull();
assertThat(configuration.getAllowedHeaders()).contains("*");
assertThat(configuration.getAllowedOrigins()).contains("*");
assertThat(configuration.getAllowedMethods()).contains("OPTIONS", "HEAD", "GET", "PATCH", "POST", "PUT", "DELETE",
"TRACE");
assertThat(configuration.getAllowedMethods()).contains("HEAD", "GET", "POST");
assertThat(configuration.getMaxAge()).isEqualTo(1800L);
}

View File

@@ -21,6 +21,8 @@ import static org.mockito.Mockito.*;
import java.lang.reflect.Method;
import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -69,7 +71,7 @@ public class RepositoryRestHandlerMappingUnitTests {
@Mock Repositories repositories;
RepositoryRestConfiguration configuration;
RepositoryRestHandlerMapping handlerMapping;
HandlerMappingStub handlerMapping;
MockHttpServletRequest mockRequest;
Method listEntitiesMethod, rootHandlerMethod;
@@ -79,7 +81,7 @@ public class RepositoryRestHandlerMappingUnitTests {
configuration = new RepositoryRestConfiguration(new ProjectionDefinitionConfiguration(),
new MetadataConfiguration(), mock(EnumTranslationConfiguration.class));
handlerMapping = new RepositoryRestHandlerMapping(mappings, configuration, repositories);
handlerMapping = new HandlerMappingStub(mappings, configuration, repositories);
handlerMapping.setApplicationContext(CONTEXT);
mockRequest = new MockHttpServletRequest();
@@ -103,7 +105,7 @@ public class RepositoryRestHandlerMappingUnitTests {
public void returnsNullForUriNotMapped() throws Exception {
handlerMapping.afterPropertiesSet();
assertThat(handlerMapping.lookupHandlerMethod("/foo", mockRequest)).isNull();
assertThat(handlerMapping.getHandler(mockRequest)).isNull();
}
@Test // DATAREST-111
@@ -113,7 +115,7 @@ public class RepositoryRestHandlerMappingUnitTests {
mockRequest = new MockHttpServletRequest("GET", "/people");
handlerMapping.afterPropertiesSet();
HandlerMethod method = handlerMapping.lookupHandlerMethod("/people", mockRequest);
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
assertThat(method).isNotNull();
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
@@ -128,7 +130,7 @@ public class RepositoryRestHandlerMappingUnitTests {
configuration.setBasePath("/base");
handlerMapping.afterPropertiesSet();
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base/people", mockRequest);
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
assertThat(method).isNotNull();
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
@@ -142,7 +144,7 @@ public class RepositoryRestHandlerMappingUnitTests {
configuration.setBasePath("/base");
handlerMapping.afterPropertiesSet();
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base", mockRequest);
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
assertThat(method).isNotNull();
assertThat(method.getMethod()).isEqualTo(rootHandlerMethod);
@@ -157,7 +159,7 @@ public class RepositoryRestHandlerMappingUnitTests {
configuration.setBasePath("/base");
handlerMapping.afterPropertiesSet();
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base/people/", mockRequest);
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
assertThat(method).isNotNull();
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
@@ -173,7 +175,7 @@ public class RepositoryRestHandlerMappingUnitTests {
configuration.setBasePath("/base");
handlerMapping.afterPropertiesSet();
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base/people", mockRequest);
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
assertThat(method).isNotNull();
assertThat(method.getMethod()).isEqualTo(listEntitiesMethod);
@@ -187,7 +189,7 @@ public class RepositoryRestHandlerMappingUnitTests {
configuration.setBasePath("/base");
HandlerMethod method = handlerMapping.lookupHandlerMethod("/servlet-path", mockRequest);
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
assertThat(method).isNull();
}
@@ -204,7 +206,7 @@ public class RepositoryRestHandlerMappingUnitTests {
configuration.setBasePath(baseUri);
HandlerMethod method = handlerMapping.lookupHandlerMethod("/people", mockRequest);
HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest);
assertThat(method).isNull();
}
@@ -280,7 +282,7 @@ public class RepositoryRestHandlerMappingUnitTests {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", "/people/search/findByLastnameLike");
handlerMapping.afterPropertiesSet();
handlerMapping.lookupHandlerMethod("/people/search/findByLastnameLike", mockRequest);
handlerMapping.getHandlerInternal(mockRequest);
assertThat(mockRequest.getAttribute(RepositoryRestHandlerMapping.EFFECTIVE_LOOKUP_PATH_ATTRIBUTE)) //
.isInstanceOfSatisfying(PathPattern.class, it -> {
@@ -299,8 +301,7 @@ public class RepositoryRestHandlerMappingUnitTests {
handlerMapping.afterPropertiesSet();
assertThatCode(() -> handlerMapping.lookupHandlerMethod("/people/search", request)) //
.doesNotThrowAnyException();
assertThatCode(() -> handlerMapping.getHandlerInternal(request)).doesNotThrowAnyException();
}
private static Class<?> createProxy(Object source) {
@@ -322,9 +323,23 @@ public class RepositoryRestHandlerMappingUnitTests {
super(mappings, configuration);
}
public HandlerMappingStub(ResourceMappings mappings, RepositoryRestConfiguration configuration,
Repositories repositories) {
super(mappings, configuration, repositories);
}
@Override
public boolean isHandler(Class<?> 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);
}
}
}

View File

@@ -66,12 +66,12 @@ public class DelegatingHandlerMappingUnitTests {
// Given:
// A matching mapping that doesn't get selected
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
RequestMatchResult result = mock(RequestMatchResult.class);
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));