You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2019/05/08 17:09:24 UTC

[cxf] branch master updated: Adding Client Cache tests for JAX-RS

This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/master by this push:
     new 4fea734  Adding Client Cache tests for JAX-RS
4fea734 is described below

commit 4fea734b1349ba023c2e560deda4aa0eaede7f3b
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Wed May 8 18:08:53 2019 +0100

    Adding Client Cache tests for JAX-RS
---
 systests/jaxrs/pom.xml                             |  12 ++
 .../org/apache/cxf/systest/jaxrs/BookStore.java    |  51 ++++++++-
 .../systest/jaxrs/JAXRSClientServerBookTest.java   | 123 ++++++++++++++++++++-
 3 files changed, 177 insertions(+), 9 deletions(-)

diff --git a/systests/jaxrs/pom.xml b/systests/jaxrs/pom.xml
index f2eea86..98b9fe7 100644
--- a/systests/jaxrs/pom.xml
+++ b/systests/jaxrs/pom.xml
@@ -537,6 +537,18 @@
             <version>${cxf.reactor.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>javax.cache</groupId>
+            <artifactId>cache-api</artifactId>
+            <version>${cxf.jcache.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ehcache</groupId>
+            <artifactId>ehcache</artifactId>
+            <version>${cxf.ehcache3.version}</version>
+            <scope>test</scope>
+       </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
index aa4cc0a..5c6ba99 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
@@ -19,7 +19,6 @@
 
 package org.apache.cxf.systest.jaxrs;
 
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -32,6 +31,7 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collections;
+import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.List;
@@ -61,6 +61,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.container.ResourceContext;
+import javax.ws.rs.core.CacheControl;
 import javax.ws.rs.core.Configuration;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Cookie;
@@ -1030,17 +1031,59 @@ public class BookStore {
         return books.get(id + 123);
     }
 
-
-
     @GET
     @Path("/books/response/{bookId}/")
     @Produces("application/xml")
     public Response getBookAsResponse(@PathParam("bookId") String id) throws BookNotFoundFault {
         Book entity = doGetBook(id);
         EntityTag etag = new EntityTag(Integer.toString(entity.hashCode()));
-        return Response.ok().tag(etag).entity(entity).build();
+
+        CacheControl cacheControl = new CacheControl();
+        cacheControl.setMaxAge(100000);
+        cacheControl.setPrivate(true);
+
+        return Response.ok().tag(etag).entity(entity).cacheControl(cacheControl).build();
+    }
+
+    @GET
+    @Path("/books/response2/{bookId}/")
+    @Produces("application/xml")
+    public Response getBookAsResponse2(@PathParam("bookId") String id) throws BookNotFoundFault {
+        Book entity = doGetBook(id);
+        EntityTag etag = new EntityTag(Integer.toString(entity.hashCode()));
+
+        CacheControl cacheControl = new CacheControl();
+        cacheControl.setMaxAge(1);
+        cacheControl.setPrivate(true);
+
+        return Response.ok().tag(etag).entity(entity).cacheControl(cacheControl).build();
+    }
+
+    @GET
+    @Path("/books/response3/{bookId}/")
+    @Produces("application/xml")
+    public Response getBookAsResponse3(@PathParam("bookId") String id,
+                                       @HeaderParam("If-Modified-Since") String modifiedSince
+    ) throws BookNotFoundFault {
+        Book entity = doGetBook(id);
+
+        EntityTag etag = new EntityTag(Integer.toString(entity.hashCode()));
+
+        CacheControl cacheControl = new CacheControl();
+        cacheControl.setMaxAge(1);
+        cacheControl.setPrivate(true);
+
+        if (modifiedSince != null) {
+            return Response.status(304).tag(etag)
+                .cacheControl(cacheControl).lastModified(new Date()).build();
+        } else {
+            return Response.ok().tag(etag).entity(entity)
+                .cacheControl(cacheControl).lastModified(new Date()).build();
+        }
     }
 
+
+
     @GET
     @Path("/books/{bookId}/cglib")
     @Produces("application/xml")
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
index a7b1f27..289dfe2 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
@@ -43,7 +43,10 @@ import javax.ws.rs.NotAcceptableException;
 import javax.ws.rs.ProcessingException;
 import javax.ws.rs.ServerErrorException;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.client.ResponseProcessingException;
+import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.Form;
 import javax.ws.rs.core.GenericEntity;
 import javax.ws.rs.core.GenericType;
@@ -62,6 +65,7 @@ import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.client.cache.CacheControlFeature;
 import org.apache.cxf.jaxrs.ext.xml.XMLSource;
 import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
 import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
@@ -767,21 +771,130 @@ public class JAXRSClientServerBookTest extends AbstractBusClientServerTestBase {
     }
 
     @Test
-    public void testGetBookResponseAndETag() throws Exception {
+    public void testCaching() throws Exception {
 
         String endpointAddress =
             "http://localhost:" + PORT + "/bookstore/books/response/123";
-        WebClient wc = WebClient.create(endpointAddress);
-        Book book = wc.get(Book.class);
-        assertEquals(200, wc.getResponse().getStatus());
+
+        // Add the CacheControlFeature to cache books returned by the service on the client side
+        CacheControlFeature cacheControlFeature = new CacheControlFeature();
+        cacheControlFeature.setCacheResponseInputStream(true);
+        Client client = ClientBuilder.newBuilder()
+            .register(cacheControlFeature)
+            .build();
+        WebTarget target = client.target(endpointAddress);
+
+        // First call
+        Response response = target.request().get();
+        assertEquals(200, response.getStatus());
+        Book book = response.readEntity(Book.class);
         assertEquals(123L, book.getId());
-        MultivaluedMap<String, Object> headers = wc.getResponse().getMetadata();
+
+        MultivaluedMap<String, Object> headers = response.getMetadata();
         assertFalse(headers.isEmpty());
         Object etag = headers.getFirst("ETag");
         assertNotNull(etag);
         assertTrue(etag.toString().startsWith("\""));
         assertTrue(etag.toString().endsWith("\""));
 
+        Object cacheControl = headers.getFirst("Cache-Control");
+        assertNotNull(cacheControl);
+        assertTrue(cacheControl.toString().contains("private"));
+        assertTrue(cacheControl.toString().contains("max-age=100000"));
+
+        // Now make a second call. This should be retrieved from the client's cache
+        target.request().get();
+        assertEquals(200, response.getStatus());
+        book = response.readEntity(Book.class);
+        assertEquals(123L, book.getId());
+
+        cacheControlFeature.close();
+    }
+
+    @Test
+    public void testCachingExpires() throws Exception {
+
+        String endpointAddress =
+            "http://localhost:" + PORT + "/bookstore/books/response2/123";
+
+        // Add the CacheControlFeature to cache books returned by the service on the client side
+        CacheControlFeature cacheControlFeature = new CacheControlFeature();
+        cacheControlFeature.setCacheResponseInputStream(true);
+        Client client = ClientBuilder.newBuilder()
+            .register(cacheControlFeature)
+            .build();
+        WebTarget target = client.target(endpointAddress);
+
+        // First call
+        Response response = target.request().get();
+        assertEquals(200, response.getStatus());
+        Book book = response.readEntity(Book.class);
+        assertEquals(123L, book.getId());
+
+        MultivaluedMap<String, Object> headers = response.getMetadata();
+        assertFalse(headers.isEmpty());
+        Object etag = headers.getFirst("ETag");
+        assertNotNull(etag);
+        assertTrue(etag.toString().startsWith("\""));
+        assertTrue(etag.toString().endsWith("\""));
+
+        Object cacheControl = headers.getFirst("Cache-Control");
+        assertNotNull(cacheControl);
+        assertTrue(cacheControl.toString().contains("private"));
+        assertTrue(cacheControl.toString().contains("max-age=1"));
+
+        // Now make a second call. The value in the cache will have expired, so
+        // it should call the service again
+        Thread.sleep(1500L);
+        target.request().get();
+        assertEquals(200, response.getStatus());
+        book = response.readEntity(Book.class);
+        assertEquals(123L, book.getId());
+
+        cacheControlFeature.close();
+    }
+
+    @Test
+    public void testCachingExpiresUsingETag() throws Exception {
+
+        String endpointAddress =
+            "http://localhost:" + PORT + "/bookstore/books/response3/123";
+
+        // Add the CacheControlFeature to cache books returned by the service on the client side
+        CacheControlFeature cacheControlFeature = new CacheControlFeature();
+        cacheControlFeature.setCacheResponseInputStream(true);
+        Client client = ClientBuilder.newBuilder()
+            .register(cacheControlFeature)
+            .build();
+        WebTarget target = client.target(endpointAddress);
+
+        // First call
+        Response response = target.request().get();
+        assertEquals(200, response.getStatus());
+        Book book = response.readEntity(Book.class);
+        assertEquals(123L, book.getId());
+
+        MultivaluedMap<String, Object> headers = response.getMetadata();
+        assertFalse(headers.isEmpty());
+        Object etag = headers.getFirst("ETag");
+        assertNotNull(etag);
+        assertTrue(etag.toString().startsWith("\""));
+        assertTrue(etag.toString().endsWith("\""));
+
+        Object cacheControl = headers.getFirst("Cache-Control");
+        assertNotNull(cacheControl);
+        assertTrue(cacheControl.toString().contains("private"));
+        assertTrue(cacheControl.toString().contains("max-age=1"));
+
+        // Now make a second call. The value in the clients cache will have expired, so it should call
+        // out to the service, which will return 304, and the client will re-use the cached payload
+        Thread.sleep(1500L);
+        target.request().get();
+        assertEquals(200, response.getStatus());
+        book = response.readEntity(Book.class);
+        assertEquals(123L, book.getId());
+
+        cacheControlFeature.close();
     }