This is an automated email from the ASF dual-hosted git repository.
ffang pushed a commit to branch 3.3.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/3.3.x-fixes by this push:
new 0bf9f01 [CXF-8570]a test to demonstrate how to configure
JAXRSClientFactoryBean with org.apache.cxf.feature.Feature to enable Client
Cache
0bf9f01 is described below
commit 0bf9f01c94cf9a73525f24545473419ac3a03c38
Author: Freeman Fang <[email protected]>
AuthorDate: Thu Jul 29 11:54:16 2021 -0400
[CXF-8570]a test to demonstrate how to configure JAXRSClientFactoryBean
with org.apache.cxf.feature.Feature to enable Client Cache
(cherry picked from commit 15619e15e95a42164e146fad11a9fedf0d982a05)
(cherry picked from commit 2ef7652ea9374c85e12fea7d8beca8d114694f1a)
---
.../jaxrs/client/cache/CXFCacheControlFeature.java | 163 +++++++++++++++++++++
.../cxf/jaxrs/client/cache/ClientCacheTest.java | 38 +++++
2 files changed, 201 insertions(+)
diff --git
a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/cache/CXFCacheControlFeature.java
b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/cache/CXFCacheControlFeature.java
new file mode 100644
index 0000000..75cd17a
--- /dev/null
+++
b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/cache/CXFCacheControlFeature.java
@@ -0,0 +1,163 @@
+/**
+ * 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.Closeable;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.Factory;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.expiry.ExpiryPolicy;
+import javax.cache.integration.CacheLoader;
+import javax.cache.integration.CacheWriter;
+import javax.cache.spi.CachingProvider;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.feature.AbstractFeature;
+import org.apache.cxf.interceptor.InterceptorProvider;
+
+
+public class CXFCacheControlFeature extends AbstractFeature {
+
+ private static final String BUS_PROVIDERS =
"org.apache.cxf.jaxrs.bus.providers";
+ private CachingProvider provider;
+ private CacheManager manager;
+ private Cache<Key, Entry> cache;
+ private boolean cacheResponseInputStream;
+
+ public CXFCacheControlFeature(boolean cacheStream) {
+ this.cacheResponseInputStream = cacheStream;
+ }
+
+ public CXFCacheControlFeature() {
+ }
+
+ protected void initializeProvider(InterceptorProvider interceptorProvider,
Bus bus) {
+ if (bus != null) {
+ List<Object> providerList = new ArrayList<Object>();
+ providerList.add(this.createCacheControlClientReaderInterceptor());
+ providerList.add(this.createCacheControlClientRequestFilter());
+ bus.setProperty(BUS_PROVIDERS, providerList);
+ }
+ }
+
+
+ public CacheControlClientRequestFilter
createCacheControlClientRequestFilter() {
+ if (cache == null) {
+ cache = createCache(new HashMap<String, Object>());
+ }
+ return new CacheControlClientRequestFilter(cache);
+ }
+
+ public CacheControlClientReaderInterceptor
createCacheControlClientReaderInterceptor() {
+ if (cache == null) {
+ cache = createCache(new HashMap<String, Object>());
+ }
+ CacheControlClientReaderInterceptor reader = new
CacheControlClientReaderInterceptor(cache);
+ reader.setCacheResponseInputStream(cacheResponseInputStream);
+ return reader;
+ }
+
+ @PreDestroy // TODO: check it is called
+ public void close() {
+ for (final Closeable c : Arrays.asList(cache, manager, provider)) {
+ try {
+ if (c != null) {
+ c.close();
+ }
+ } catch (final Exception e) {
+ // no-op
+ }
+ }
+
+ }
+
+ private Cache<Key, Entry> createCache(final Map<String, Object>
properties) {
+ final Properties props = new Properties();
+ props.putAll(properties);
+
+ final String prefix = this.getClass().getName() + ".";
+ final String uri = props.getProperty(prefix + "config-uri");
+ final String name = props.getProperty(prefix + "name",
this.getClass().getName());
+
+ final ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
+
+ provider = Caching.getCachingProvider();
+ try {
+ manager = provider.getCacheManager(
+ uri == null ? provider.getDefaultURI() : new URI(uri),
+ contextClassLoader,
+ props);
+
+ final MutableConfiguration<Key, Entry> configuration = new
MutableConfiguration<Key, Entry>()
+
.setReadThrough("true".equalsIgnoreCase(props.getProperty(prefix +
"readThrough", "false")))
+
.setWriteThrough("true".equalsIgnoreCase(props.getProperty(prefix +
"writeThrough", "false")))
+ .setManagementEnabled(
+ "true".equalsIgnoreCase(props.getProperty(prefix +
"managementEnabled", "false")))
+ .setStatisticsEnabled(
+ "true".equalsIgnoreCase(props.getProperty(prefix +
"statisticsEnabled", "false")))
+
.setStoreByValue("true".equalsIgnoreCase(props.getProperty(prefix +
"storeByValue", "false")));
+
+ final String loader = props.getProperty(prefix + "loaderFactory");
+ if (loader != null) {
+ @SuppressWarnings("unchecked")
+ Factory<? extends CacheLoader<Key, Entry>> f =
newInstance(contextClassLoader, loader, Factory.class);
+ configuration.setCacheLoaderFactory(f);
+ }
+ final String writer = props.getProperty(prefix + "writerFactory");
+ if (writer != null) {
+ @SuppressWarnings("unchecked")
+ Factory<? extends CacheWriter<Key, Entry>> f =
newInstance(contextClassLoader, writer, Factory.class);
+ configuration.setCacheWriterFactory(f);
+ }
+ final String expiry = props.getProperty(prefix + "expiryFactory");
+ if (expiry != null) {
+ @SuppressWarnings("unchecked")
+ Factory<? extends ExpiryPolicy> f =
newInstance(contextClassLoader, expiry, Factory.class);
+ configuration.setExpiryPolicyFactory(f);
+ }
+
+ cache = manager.createCache(name, configuration);
+ return cache;
+ } catch (final URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T newInstance(final ClassLoader contextClassLoader,
final String clazz, final Class<T> cast) {
+ try {
+ return (T) contextClassLoader.loadClass(clazz).newInstance();
+ } catch (final Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+}
diff --git
a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/cache/ClientCacheTest.java
b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/cache/ClientCacheTest.java
index 6fe9f71..f784f5d 100644
---
a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/cache/ClientCacheTest.java
+++
b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/cache/ClientCacheTest.java
@@ -21,6 +21,7 @@ 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;
@@ -33,9 +34,12 @@ 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;
@@ -141,6 +145,23 @@ public class ClientCacheTest {
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() {
@@ -249,5 +270,22 @@ public class ClientCacheTest {
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");
+ }
}
\ No newline at end of file