[BAEL-11597] Move and update Etags article
* Moved etags article related code * Fixed existing etag Ignored test * Added etag scentsio adding etag support to a single endpoint * Added tests for single endpoint etag scenario * Cleaned now unused code in spring-rest-full module
This commit is contained in:
@@ -8,11 +8,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.web.context.request.RequestContextListener;
|
||||
import org.springframework.web.filter.ShallowEtagHeaderFilter;
|
||||
|
||||
/**
|
||||
* Main Application Class - uses Spring Boot. Just run this as a normal Java
|
||||
@@ -40,8 +38,4 @@ public class Application extends SpringBootServletInitializer {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ShallowEtagHeaderFilter shallowEtagHeaderFilter() {
|
||||
return new ShallowEtagHeaderFilter();
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.baeldung.persistence.model.Foo;
|
||||
import org.baeldung.persistence.service.IFooService;
|
||||
import org.baeldung.web.hateoas.event.ResourceCreatedEvent;
|
||||
import org.baeldung.web.util.RestPreconditions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@@ -26,9 +24,6 @@ import com.google.common.base.Preconditions;
|
||||
@RequestMapping(value = "/auth/foos")
|
||||
public class FooController {
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private IFooService service;
|
||||
|
||||
@@ -71,9 +66,6 @@ public class FooController {
|
||||
public Foo create(@RequestBody final Foo resource, final HttpServletResponse response) {
|
||||
Preconditions.checkNotNull(resource);
|
||||
final Foo foo = service.create(resource);
|
||||
final Long idOfCreatedResource = foo.getId();
|
||||
|
||||
eventPublisher.publishEvent(new ResourceCreatedEvent(this, response, idOfCreatedResource));
|
||||
|
||||
return foo;
|
||||
}
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package org.baeldung.web.hateoas.event;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
public class ResourceCreatedEvent extends ApplicationEvent {
|
||||
private final HttpServletResponse response;
|
||||
private final long idOfNewResource;
|
||||
|
||||
public ResourceCreatedEvent(final Object source, final HttpServletResponse response, final long idOfNewResource) {
|
||||
super(source);
|
||||
|
||||
this.response = response;
|
||||
this.idOfNewResource = idOfNewResource;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public HttpServletResponse getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public long getIdOfNewResource() {
|
||||
return idOfNewResource;
|
||||
}
|
||||
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package org.baeldung.web.hateoas.listener;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.baeldung.web.hateoas.event.ResourceCreatedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
@Component
|
||||
class ResourceCreatedDiscoverabilityListener implements ApplicationListener<ResourceCreatedEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final ResourceCreatedEvent resourceCreatedEvent) {
|
||||
Preconditions.checkNotNull(resourceCreatedEvent);
|
||||
|
||||
final HttpServletResponse response = resourceCreatedEvent.getResponse();
|
||||
final long idOfNewResource = resourceCreatedEvent.getIdOfNewResource();
|
||||
|
||||
addLinkHeaderOnResourceCreation(response, idOfNewResource);
|
||||
}
|
||||
|
||||
void addLinkHeaderOnResourceCreation(final HttpServletResponse response, final long idOfNewResource) {
|
||||
// final String requestUrl = request.getRequestURL().toString();
|
||||
// final URI uri = new UriTemplate("{requestUrl}/{idOfNewResource}").expand(requestUrl, idOfNewResource);
|
||||
|
||||
final URI uri = ServletUriComponentsBuilder.fromCurrentRequestUri().path("/{idOfNewResource}").buildAndExpand(idOfNewResource).toUri();
|
||||
response.setHeader(HttpHeaders.LOCATION, uri.toASCIIString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,15 +23,6 @@
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<filter>
|
||||
<filter-name>etagFilter</filter-name>
|
||||
<filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>etagFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<!-- Spring child -->
|
||||
<servlet>
|
||||
<servlet-name>api</servlet-name>
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.baeldung;
|
||||
|
||||
import org.baeldung.persistence.PersistenceTestSuite;
|
||||
import org.baeldung.web.LiveTestSuiteLiveTest;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
// @formatter:off
|
||||
PersistenceTestSuite.class
|
||||
,LiveTestSuiteLiveTest.class
|
||||
}) //
|
||||
public class TestSuiteLiveTest {
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package org.baeldung.common.web;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.response.Response;
|
||||
|
||||
public abstract class AbstractBasicLiveTest<T extends Serializable> extends AbstractLiveTest<T> {
|
||||
|
||||
public AbstractBasicLiveTest(final Class<T> clazzToSet) {
|
||||
super(clazzToSet);
|
||||
}
|
||||
|
||||
// tests
|
||||
|
||||
@Test
|
||||
public void givenResourceExists_whenRetrievingResource_thenEtagIsAlsoReturned() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
|
||||
// When
|
||||
final Response findOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertNotNull(findOneResponse.getHeader(HttpHeaders.ETAG));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenResourceWasRetrieved_whenRetrievingAgainWithEtag_thenNotModifiedReturned() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
final Response findOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.get(uriOfResource);
|
||||
final String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
|
||||
|
||||
// When
|
||||
final Response secondFindOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.headers("If-None-Match", etagValue)
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertTrue(secondFindOneResponse.getStatusCode() == 304);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("No Update operation yet")
|
||||
public void givenResourceWasRetrievedThenModified_whenRetrievingAgainWithEtag_thenResourceIsReturned() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
final Response findOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.get(uriOfResource);
|
||||
final String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
|
||||
|
||||
// existingResource.setName(randomAlphabetic(6));
|
||||
// getApi().update(existingResource.setName("randomString"));
|
||||
|
||||
// When
|
||||
final Response secondFindOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.headers("If-None-Match", etagValue)
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertTrue(secondFindOneResponse.getStatusCode() == 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Not Yet Implemented By Spring - https://jira.springsource.org/browse/SPR-10164")
|
||||
public void givenResourceExists_whenRetrievedWithIfMatchIncorrectEtag_then412IsReceived() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
|
||||
// When
|
||||
final Response findOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.headers("If-Match", randomAlphabetic(8))
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertTrue(findOneResponse.getStatusCode() == 412);
|
||||
}
|
||||
|
||||
// find - one
|
||||
|
||||
// find - all
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package org.baeldung.web;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
|
||||
import org.baeldung.common.web.AbstractBasicLiveTest;
|
||||
import org.baeldung.persistence.model.Foo;
|
||||
import org.baeldung.spring.ConfigIntegrationTest;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { ConfigIntegrationTest.class }, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("test")
|
||||
public class FooLiveTest extends AbstractBasicLiveTest<Foo> {
|
||||
|
||||
public FooLiveTest() {
|
||||
super(Foo.class);
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public final void create() {
|
||||
create(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String createAsUri() {
|
||||
return createAsUri(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.baeldung.web;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
// @formatter:off
|
||||
FooLiveTest.class
|
||||
}) //
|
||||
public class LiveTestSuiteLiveTest {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user