blob: 5fc4be6dd1338ad9ad993a7e5a2f38bb9885ff6e [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.jaxrs.client.cache;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collections;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.apache.cxf.transport.local.LocalConduit;
import org.apache.cxf.transport.local.LocalTransportFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class ClientCacheTest {
public static final String ADDRESS = "local://transport";
private static Server server;
@BeforeClass
public static void bind() throws Exception {
final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(TheServer.class);
sf.setResourceProvider(TheServer.class, new SingletonResourceProvider(new TheServer(), false));
sf.setTransportId(LocalTransportFactory.TRANSPORT_ID);
sf.setAddress(ADDRESS);
server = sf.create();
}
@AfterClass
public static void unbind() throws Exception {
server.stop();
server.destroy();
}
@Test
public void testGetTimeString() {
CacheControlFeature feature = new CacheControlFeature();
try {
final WebTarget base = ClientBuilder.newBuilder().register(feature).build().target(ADDRESS);
final Invocation.Builder cached = base.request("text/plain").header(HttpHeaders.CACHE_CONTROL, "public");
final Response r = cached.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
final String r1 = r.readEntity(String.class);
waitABit();
assertEquals(r1, cached.get().readEntity(String.class));
} finally {
feature.close();
}
}
@Test
public void testGetTimeStringUsingClientFactory() {
CacheControlFeature feature = new CacheControlFeature();
try {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress(ADDRESS);
bean.setProviders(Collections.singletonList(feature));
bean.setTransportId(LocalTransportFactory.TRANSPORT_ID);
final WebClient cached = bean.createWebClient()
.accept("text/plain")
.header(HttpHeaders.CACHE_CONTROL, "public");
final Response r = cached.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
final String r1 = r.readEntity(String.class);
waitABit();
assertEquals(r1, cached.get().readEntity(String.class));
} finally {
feature.close();
}
}
@Test
public void testGetTimeStringAsInputStream() throws Exception {
CacheControlFeature feature = new CacheControlFeature();
try {
final WebTarget base = ClientBuilder.newBuilder().register(feature).build().target(ADDRESS);
final Invocation.Builder cached = base.request("text/plain").header(HttpHeaders.CACHE_CONTROL, "public");
final Response r = cached.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
InputStream is = r.readEntity(InputStream.class);
final String r1 = IOUtils.readStringFromStream(is);
waitABit();
is = cached.get().readEntity(InputStream.class);
final String r2 = IOUtils.readStringFromStream(is);
assertEquals(r1, r2);
} finally {
feature.close();
}
}
@Test
public void testGetTimeStringAsInputStreamAndString() throws Exception {
CacheControlFeature feature = new CacheControlFeature();
try {
feature.setCacheResponseInputStream(true);
final WebTarget base = ClientBuilder.newBuilder().register(feature).build().target(ADDRESS);
final Invocation.Builder cached = base.request("text/plain").header(HttpHeaders.CACHE_CONTROL, "public");
final Response r = cached.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
InputStream is = r.readEntity(InputStream.class);
final String r1 = IOUtils.readStringFromStream(is);
waitABit();
// CassCastException would occur without a cached stream support
final String r2 = cached.get().readEntity(String.class);
assertEquals(r1, r2);
} finally {
feature.close();
}
}
@Test
public void testGetTimeStringAsStringAndInputStream() throws Exception {
CacheControlFeature feature = new CacheControlFeature();
try {
feature.setCacheResponseInputStream(true);
final WebTarget base = ClientBuilder.newBuilder().register(feature).build().target(ADDRESS);
final Invocation.Builder cached = base.request("text/plain").header(HttpHeaders.CACHE_CONTROL, "public");
final Response r = cached.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
final String r1 = r.readEntity(String.class);
waitABit();
// CassCastException would occur without a cached stream support
InputStream is = cached.get().readEntity(InputStream.class);
final String r2 = IOUtils.readStringFromStream(is);
assertEquals(r1, r2);
} finally {
feature.close();
}
}
@Test
public void testGetTimeStringAsStringAndInputStreamWithJAXRSClientFactoryBean() throws Exception {
CXFCacheControlFeature feature = new CXFCacheControlFeature(true);
try {
WebClient client = createClient(feature);
final Response r = client.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
final String r1 = r.readEntity(String.class);
waitABit();
InputStream is = client.get(InputStream.class);
final String r2 = IOUtils.readStringFromStream(is);
assertEquals(r1, r2);
} finally {
feature.close();
}
}
@Test
public void testGetJaxbBookCache() {
CacheControlFeature feature = new CacheControlFeature();
try {
final WebTarget base = ClientBuilder.newBuilder().register(feature).build().target(ADDRESS);
final Invocation.Builder cached =
setAsLocal(base.request("application/xml")).header(HttpHeaders.CACHE_CONTROL, "public");
final Response r = cached.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
final Book b1 = r.readEntity(Book.class);
assertEquals("JCache", b1.getName());
assertNotNull(b1.getId());
waitABit();
assertEquals(b1, cached.get().readEntity(Book.class));
} finally {
feature.close();
}
}
@Test
public void testGetJaxbBookCacheByValue() {
// org.apache.cxf.jaxrs.client.cache.CacheControlFeature.storeByValue
CacheControlFeature feature = new CacheControlFeature();
try {
final WebTarget base = ClientBuilder.newBuilder()
.property("org.apache.cxf.jaxrs.client.cache.CacheControlFeature.storeByValue", "true")
.register(feature).build().target(ADDRESS);
final Invocation.Builder cached =
setAsLocal(base.request("application/xml")).header(HttpHeaders.CACHE_CONTROL, "public");
final Response r = cached.get();
assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
final Book b1 = r.readEntity(Book.class);
assertEquals("JCache", b1.getName());
assertNotNull(b1.getId());
waitABit();
assertEquals(b1, cached.get().readEntity(Book.class));
} finally {
feature.close();
}
}
private static Invocation.Builder setAsLocal(final Invocation.Builder client) {
WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
return client;
}
private static void waitABit() {
try { // just to be sure
Thread.sleep(150);
} catch (final InterruptedException e) {
Thread.interrupted();
}
}
@Path("/")
public static class TheServer {
@GET
@Produces("text/plain")
public Response getString() {
return Response.ok(Long.toString(System.currentTimeMillis()))
.tag("123").cacheControl(CacheControl.valueOf("max-age=50000")).build();
}
@GET
@Produces("application/xml")
public Response getJaxbBook() {
Book b = new Book();
b.setId(System.currentTimeMillis());
b.setName("JCache");
return Response.ok(b).tag("123").cacheControl(CacheControl.valueOf("max-age=50000")).build();
}
}
@XmlRootElement
public static class Book implements Serializable {
private static final long serialVersionUID = 4924824780883333782L;
private String name;
private Long id;
public Book() {
}
public Book(String name, long id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int hashCode() {
return id.hashCode() + 37 * name.hashCode();
}
public boolean equals(Object o) {
if (o instanceof Book) {
Book other = (Book)o;
return other.id.equals(id) && other.name.equals(name);
}
return false;
}
}
private WebClient createClient(CXFCacheControlFeature feature) {
Bus bus = BusFactory.newInstance().createBus();
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setBus(bus);
sf.setResourceClasses(TheServer.class);
sf.setResourceProvider(TheServer.class, new SingletonResourceProvider(new TheServer(), false));
sf.setTransportId(LocalTransportFactory.TRANSPORT_ID);
sf.setAddress(ADDRESS);
sf.create();
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setBus(bus);
bean.setAddress(ADDRESS);
bean.setFeatures(Collections.singletonList(feature));
bean.setTransportId(LocalTransportFactory.TRANSPORT_ID);
return bean.createWebClient().accept("text/plain").header(HttpHeaders.CACHE_CONTROL, "public");
}
}