Polish cache sample

Update single cache sample with all supported cache providers. Add README
to shortly explain how to get started with them.

See gh-2633
This commit is contained in:
Stephane Nicoll
2015-05-29 15:33:00 +02:00
parent 23a278451a
commit eef027a4f0
16 changed files with 345 additions and 171 deletions

View File

@@ -16,20 +16,34 @@
package sample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import java.io.Serializable;
/**
* @author Eddú Meléndez
* @since 1.3.0
*/
@EnableCaching
@SpringBootApplication
public class SampleEhCacheCacheApplication {
@SuppressWarnings("serial")
public class Country implements Serializable {
public static void main(String[] args) {
SpringApplication.run(SampleEhCacheCacheApplication.class);
private final String code;
public Country(String code) {
this.code = code;
}
public String getCode() {
return code;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Country country = (Country) o;
return code.equals(country.code);
}
@Override
public int hashCode() {
return code.hashCode();
}
}

View File

@@ -16,23 +16,19 @@
package sample;
import org.springframework.cache.annotation.Cacheable;
import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheResult;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/**
* @author Eddú Meléndez
* @since 1.3.0
*/
@Component
public class CountryService {
@CacheDefaults(cacheName = "countries")
public class CountryRepository {
@Cacheable("countries")
public List<String> countries() {
System.out.println("Loading countries");
return Arrays.asList("Perú", "United States");
@CacheResult
public Country findByCode(String code) {
System.out.println("---> Loading country with code '" + code + "'");
return new Country(code);
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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 sample;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
@EnableCaching
@EnableScheduling
@SpringBootApplication
public class SampleCacheApplication {
private static final Logger logger = LoggerFactory.getLogger(SampleCacheApplication.class);
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(SampleCacheApplication.class)
.profiles("app")
.run(args);
}
@Component
static class CacheManagerCheck implements CommandLineRunner {
private final CacheManager cacheManager;
@Autowired
CacheManagerCheck(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public void run(String... strings) throws Exception {
logger.info("\n\n" + "=========================================================\n"
+ "Using cache manager: " + this.cacheManager.getClass().getName() + "\n"
+ "=========================================================\n\n");
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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 sample;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Profile("app")
class SampleClient {
private static final List<String> SAMPLE_COUNTRY_CODES = Arrays.asList("AF", "AX", "AL", "DZ", "AS",
"AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY",
"BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI",
"KH", "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK",
"CR", "CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER",
"EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI",
"GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU",
"IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI",
"KP", "KR", "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG",
"MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME",
"MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP",
"NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE",
"RO", "RU", "RW", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS",
"SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK", "SD", "SR", "SJ",
"SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM",
"TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF",
"EH", "YE", "ZM", "ZW");
private final CountryRepository countryService;
private final Random random;
@Autowired
public SampleClient(CountryRepository countryService) {
this.countryService = countryService;
this.random = new Random();
}
@Scheduled(fixedDelay = 500)
public void retrieveCountry() {
String randomCode = SAMPLE_COUNTRY_CODES.get(random.nextInt(SAMPLE_COUNTRY_CODES.size()));
System.out.println("Looking for country with code '" + randomCode + "'");
this.countryService.findByCode(randomCode);
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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 sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* @author Eddú Meléndez
* @since 1.3.0
*/
@Component
public class Startup implements CommandLineRunner {
@Autowired
private CountryService countryService;
@Override
public void run(String... args) throws Exception {
System.out.println("---- calling country service");
System.out.println(countryService.countries());
System.out.println("---- calling country service again from cache.");
System.out.println(countryService.countries());
}
}

View File

@@ -1 +0,0 @@
spring.cache.config=/cache/ehcache-override.xml

View File

@@ -0,0 +1,19 @@
#
# Infinispan configuration file location.
#
#spring.cache.infinispan.config=infinispan.xml
#
# JCache configuration (example with hazelcast).
#
#spring.cache.type=jcache
#spring.cache.jcache.config=hazelcast.xml
#
# Guava configuration
#
#spring.cache.guava.spec=maximumSize=200,expireAfterAccess=600s

View File

@@ -1,8 +0,0 @@
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect"
dynamicConfig="true">
<cache name="countries"
maxBytesLocalHeap="50m"
timeToLiveSeconds="100">
</cache>
</ehcache>

View File

@@ -1,8 +1,7 @@
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect"
dynamicConfig="true">
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<cache name="countries"
maxBytesLocalHeap="50m"
timeToLiveSeconds="100">
maxEntriesLocalHeap="200"
timeToLiveSeconds="600">
</cache>
</ehcache>

View File

@@ -0,0 +1,17 @@
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.4.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<map name="countries">
<time-to-live-seconds>600</time-to-live-seconds>
<max-size>200</max-size>
</map>
<cache name="countries">
<eviction size="200"/>
<statistics-enabled>true</statistics-enabled>
<management-enabled>true</management-enabled>
</cache>
</hazelcast>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns="urn:infinispan:config:7.2">
<cache-container default-cache="default">
<local-cache name="countries">
<eviction max-entries="200"/>
<expiration lifespan="600000"/>
</local-cache>
</cache-container>
</infinispan>

View File

@@ -16,48 +16,39 @@
package sample;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsNull.notNullValue;
/**
* @author Eddú Meléndez
* @since 1.3.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {SampleEhCacheCacheApplication.class})
public abstract class AbstractEhCacheCacheTests {
@SpringApplicationConfiguration(classes = {SampleCacheApplication.class})
public class SampleCacheApplicationTests {
@Autowired
private CacheManager cacheManager;
@Autowired
private EhCacheCacheManager ehCacheManager;
@After
public void tearDown() {
if (this.ehCacheManager != null) {
this.ehCacheManager.getCacheManager().shutdown();
}
}
private CountryRepository countryRepository;
@Test
public void testCacheManagerInstance() {
assertThat(this.cacheManager, instanceOf(EhCacheCacheManager.class));
}
@Test
public void testCacheManager() {
assertThat(this.cacheManager.getCacheNames(), contains("countries"));
public void validateCache() {
Cache countries = this.cacheManager.getCache("countries");
assertThat(countries, is(notNullValue()));
countries.clear(); // Simple test assuming the cache is empty
assertThat(countries.get("BE"), is(nullValue()));
Country be = this.countryRepository.findByCode("BE");
assertThat((Country) countries.get("BE").get(), is(be));
}
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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 sample;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Eddú Meléndez
* @since 1.3.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {SampleEhCacheCacheApplication.class})
@ActiveProfiles("override")
public class SampleEhCacheCacheApplicationOverrideTests extends AbstractEhCacheCacheTests {
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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 sample;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Eddú Meléndez
* @since 1.3.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {SampleEhCacheCacheApplication.class})
public class SampleEhCacheCacheApplicationTests extends AbstractEhCacheCacheTests {
}