[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:
Ger Roza
2019-02-23 14:49:01 -03:00
parent 23eecb7cb1
commit 52b164ffca
18 changed files with 256 additions and 255 deletions
@@ -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;
}
@@ -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;
}
}
@@ -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 {
}