DATAREST-1121 - Skip last modified detection for query methods that project.

For an execution of a projecting query method we now skip the last modified detection as it actually doesn't make sense if applied to non-aggregates.
This commit is contained in:
Oliver Gierke
2017-08-24 21:50:31 +02:00
parent 5e5c2fd89b
commit 530e7c773e
6 changed files with 54 additions and 3 deletions

View File

@@ -73,6 +73,9 @@ public class HttpHeadersPreparer {
*/
public HttpHeaders prepareHeaders(PersistentEntity<?, ?> entity, Object value) {
Assert.notNull(entity, "PersistentEntity must not be null!");
Assert.notNull(value, "Entity value must not be null!");
// Add ETag
HttpHeaders headers = ETag.from(entity, value).addTo(new HttpHeaders());

View File

@@ -213,6 +213,11 @@ class RepositorySearchController extends AbstractRepositoryRestController {
PersistentEntity<?, ?> entity = information.getPersistentEntity();
// Returned value is not of the aggregates type - probably some projection
if (!entity.getType().isInstance(it)) {
return ResponseEntity.ok(it);
}
return resourceStatus.getStatusAndHeaders(headers, it, entity).toResponseEntity(//
() -> assembler.toFullResource(it));

View File

@@ -29,6 +29,7 @@ import org.springframework.hateoas.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
/**
* Simple abstraction to capture the status of a resource to determine whether it has been modified or not and produce
@@ -41,6 +42,8 @@ import org.springframework.http.ResponseEntity;
@RequiredArgsConstructor(staticName = "of")
class ResourceStatus {
private static final String INVALID_DOMAIN_OBJECT = "Domain object %s is not an instance of the given PersistentEntity of type %s!";
private final @NonNull HttpHeadersPreparer preparer;
/**
@@ -49,12 +52,18 @@ class ResourceStatus {
*
* @param requestHeaders must not be {@literal null}.
* @param domainObject must not be {@literal null}.
* @param information
* @param entity must not be {@literal null}.
* @return
*/
public StatusAndHeaders getStatusAndHeaders(HttpHeaders requestHeaders, Object domainObject,
PersistentEntity<?, ?> entity) {
Assert.notNull(requestHeaders, "Request headers must not be null!");
Assert.notNull(domainObject, "Domain object must not be null!");
Assert.notNull(entity, "PersistentEntity must not be null!");
Assert.isTrue(entity.getType().isInstance(domainObject),
String.format(INVALID_DOMAIN_OBJECT, domainObject, entity.getType()));
// Check ETag for If-Non-Match
List<String> ifNoneMatch = requestHeaders.getIfNoneMatch();
@@ -64,7 +73,8 @@ class ResourceStatus {
// Check last modification for If-Modified-Since
return eTag.matches(entity, domainObject) || preparer.isObjectStillValid(domainObject, requestHeaders)
? StatusAndHeaders.notModified(responseHeaders) : StatusAndHeaders.modified(responseHeaders);
? StatusAndHeaders.notModified(responseHeaders)
: StatusAndHeaders.modified(responseHeaders);
}
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)

View File

@@ -21,10 +21,13 @@ import static org.mockito.Mockito.*;
import lombok.Value;
import java.util.Date;
import java.util.function.Supplier;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@@ -49,6 +52,8 @@ public class ResourceStatusUnitTests {
@Mock HttpHeadersPreparer preparer;
@Mock Supplier<PersistentEntityResource> supplier;
public @Rule ExpectedException exception = ExpectedException.none();
@Before
public void setUp() {
@@ -87,6 +92,15 @@ public class ResourceStatusUnitTests {
assertNotModified(status.getStatusAndHeaders(new HttpHeaders(), new Sample(0), entity));
}
@Test // DATAREST-1121
public void rejectsInvalidPersistentEntityDomainObjectCombination() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage(entity.getType().getName());
assertModified(status.getStatusAndHeaders(new HttpHeaders(), new Date(), entity));
}
private void assertModified(StatusAndHeaders statusAndHeaders) {
assertThat(statusAndHeaders.isModified()).isTrue();