refactor code for customer repository and update embedded redis repository

This commit is contained in:
saikat 2024-03-01 13:08:58 +05:30
parent ff0db905bc
commit 5b7a864ef2
7 changed files with 48 additions and 107 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>spring-caching-2</artifactId> <artifactId>spring-caching-2</artifactId>
<version>0.1-SNAPSHOT</version> <version>0.1-SNAPSHOT</version>
@ -51,7 +51,7 @@
<version>${caffeine.version}</version> <version>${caffeine.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.ozimov</groupId> <groupId>com.github.codemonstur</groupId>
<artifactId>embedded-redis</artifactId> <artifactId>embedded-redis</artifactId>
<version>${embedded.redis.version}</version> <version>${embedded.redis.version}</version>
<exclusions> <exclusions>
@ -65,7 +65,7 @@
</dependencies> </dependencies>
<properties> <properties>
<embedded.redis.version>0.7.3</embedded.redis.version> <embedded.redis.version>1.4.0</embedded.redis.version>
<caffeine.version>3.1.8</caffeine.version> <caffeine.version>3.1.8</caffeine.version>
</properties> </properties>

View File

@ -1,7 +1,6 @@
package com.baeldung.caching.multicache; package com.baeldung.caching.multicache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.AnnotationCacheOperationSource; import org.springframework.cache.annotation.AnnotationCacheOperationSource;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
@ -37,7 +36,7 @@ public class CacheConfig {
@Bean @Bean
public CaffeineCache caffeineCacheConfig() { public CaffeineCache caffeineCacheConfig() {
return new CaffeineCache("customerCache", Caffeine.newBuilder() return new CaffeineCache("customerCache", Caffeine.newBuilder()
.expireAfterWrite(Duration.ofSeconds(3)) .expireAfterWrite(Duration.ofSeconds(1))
.initialCapacity(1) .initialCapacity(1)
.maximumSize(2000) .maximumSize(2000)
.build()); .build());

View File

@ -1,22 +0,0 @@
package com.baeldung.caching.multicache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@GetMapping("/customer/{id}")
public Customer getCustomer(@PathVariable String id) {
return customerService.getCustomer(id);
}
}

View File

@ -1,44 +1,7 @@
package com.baeldung.caching.multicache; package com.baeldung.caching.multicache;
import org.springframework.stereotype.Service; import org.springframework.data.repository.CrudRepository;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
@Service public interface CustomerRepository extends CrudRepository<Customer, String> {
public class CustomerRepository {
private final Map<String, Customer> customerMap = new HashMap<>();
public Customer getCustomerById(String id) {
return customerMap.get(id);
}
@PostConstruct
private void setupCustomerRepo() {
Customer product1 = getCustomer("100001", "name1", "name1@mail.com");
customerMap.put("100001", product1);
Customer product2 = getCustomer("100002", "name2", "name2@mail.com");
customerMap.put("100002", product2);
Customer product3 = getCustomer("100003", "name3", "name3@mail.com");
customerMap.put("100003", product3);
Customer product4 = getCustomer("100004", "name4", "name4@mail.com");
customerMap.put("100004", product4);
Customer product5 = getCustomer("100005", "name5", "name5@mail.com");
customerMap.put("100005", product5);
}
private static Customer getCustomer(String id, String name, String email) {
Customer customer = new Customer();
customer.setId(id);
customer.setName(name);
customer.setEmail(email);
return customer;
}
} }

View File

@ -20,6 +20,7 @@ public class CustomerService {
@Cacheable(cacheNames = "customerCache", cacheManager = "redisCacheManager") @Cacheable(cacheNames = "customerCache", cacheManager = "redisCacheManager")
}) })
public Customer getCustomer(String id) { public Customer getCustomer(String id) {
return customerRepository.getCustomerById(id); return customerRepository.findById(id)
.orElseThrow(RuntimeException::new);
} }
} }

View File

@ -17,6 +17,8 @@ import redis.embedded.RedisServer;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -43,56 +45,53 @@ class CustomerServiceCachingIntegrationTest {
private CacheManager caffeineCacheManager; private CacheManager caffeineCacheManager;
@Test @Test
void givenCustomerIsPresentInDb_whenFindCustomerById_thenCustomerReturnedFromDb_And_Cached() { void givenCustomerIsPresentInDB_whenGetCustomerById_thenCustomerReturnedFromDBAndCached() {
Customer customer = new Customer("100", "test", "test@mail.com"); String CUSTOMER_ID = "100";
given(customerRepository.getCustomerById("100")) Customer customer = new Customer(CUSTOMER_ID, "test", "test@mail.com");
.willReturn(customer);
Customer customerCacheMiss = customerService.getCustomer("100"); given(customerRepository.findById(CUSTOMER_ID))
.willReturn(Optional.of(customer));
Customer customerCacheMiss = customerService.getCustomer(CUSTOMER_ID);
assertThat(customerCacheMiss).isEqualTo(customer); assertThat(customerCacheMiss).isEqualTo(customer);
verify(customerRepository, times(1)).getCustomerById("100"); verify(customerRepository, times(1)).findById(CUSTOMER_ID);
assertThat(customerFromRedisCache("100")).isEqualTo(customer); assertThat(customerFromRedisCache(CUSTOMER_ID)).isEqualTo(customer);
assertThat(customerFromCaffeineCache("100")).isEqualTo(customer); assertThat(customerFromCaffeineCache(CUSTOMER_ID)).isEqualTo(customer);
} }
@Test @Test
void givenCustomerIsPresentInDb_whenFindCustomerById_CalledTwice_thenCustomerReturnedFromDb_And_Cached() { void givenCustomerIsPresentInDB_whenGetCustomerByIdIsCalledTwice_thenCustomerReturnedFromDBAndCached() {
Customer customer = new Customer("101", "test", "test@mail.com"); String CUSTOMER_ID = "101";
given(customerRepository.getCustomerById("101")) Customer customer = new Customer(CUSTOMER_ID, "test", "test@mail.com");
.willReturn(customer); given(customerRepository.findById(CUSTOMER_ID)).willReturn(Optional.of(customer));
Customer customerCacheMiss = customerService.getCustomer("101"); Customer customerCacheMiss = customerService.getCustomer(CUSTOMER_ID);
Customer customerCacheHit = customerService.getCustomer("101"); Customer customerCacheHit = customerService.getCustomer(CUSTOMER_ID);
assertThat(customerCacheMiss).isEqualTo(customer); assertThat(customerCacheMiss).isEqualTo(customer);
assertThat(customerCacheHit).isEqualTo(customer); assertThat(customerCacheHit).isEqualTo(customer);
verify(customerRepository, times(1)).findById(CUSTOMER_ID);
verify(customerRepository, times(1)).getCustomerById("101"); assertThat(customerFromRedisCache(CUSTOMER_ID)).isEqualTo(customer);
assertThat(customerFromRedisCache("101")).isEqualTo(customer); assertThat(customerFromCaffeineCache(CUSTOMER_ID)).isEqualTo(customer);
assertThat(customerFromCaffeineCache("101")).isEqualTo(customer);
} }
@Test @Test
void givenCustomerIsPresentInDb_whenFindCustomerById_CalledThrice_thenCustomerReturnedFromDBFirst_ThenFromCache() throws InterruptedException { void givenCustomerIsPresentInDB_whenGetCustomerByIdIsCalledThrice_thenCustomerReturnedFromDBAndCached() throws InterruptedException {
Customer customer = new Customer("102", "test", "test@mail.com"); String CUSTOMER_ID = "102";
given(customerRepository.getCustomerById("102")) Customer customer = new Customer(CUSTOMER_ID, "test", "test@mail.com");
.willReturn(customer); given(customerRepository.findById(CUSTOMER_ID))
.willReturn(Optional.of(customer));
Customer customerCacheMiss = customerService.getCustomer("102"); Customer customerCacheMiss = customerService.getCustomer(CUSTOMER_ID);
Customer customerCacheHit = customerService.getCustomer("102"); TimeUnit.SECONDS.sleep(2);
Customer customerCacheHit = customerService.getCustomer(CUSTOMER_ID);
TimeUnit.SECONDS.sleep(4); verify(customerRepository, times(1)).findById(CUSTOMER_ID);
assertThat(customerFromCaffeineCache("102")).isEqualTo(null);
Customer customerCacheHitAgain = customerService.getCustomer("102");
verify(customerRepository, times(1)).getCustomerById("102");
assertThat(customerCacheMiss).isEqualTo(customer); assertThat(customerCacheMiss).isEqualTo(customer);
assertThat(customerCacheHit).isEqualTo(customer); assertThat(customerCacheHit).isEqualTo(customer);
assertThat(customerCacheHitAgain).isEqualTo(customer); assertThat(customerFromRedisCache(CUSTOMER_ID)).isEqualTo(customer);
assertThat(customerFromRedisCache("102")).isEqualTo(customer); assertThat(customerFromCaffeineCache(CUSTOMER_ID)).isEqualTo(customer);
assertThat(customerFromCaffeineCache("102")).isEqualTo(customer);
} }
private Object customerFromRedisCache(String key) { private Object customerFromRedisCache(String key) {
@ -110,17 +109,17 @@ class CustomerServiceCachingIntegrationTest {
private final RedisServer redisServer; private final RedisServer redisServer;
public EmbeddedRedisConfiguration() { public EmbeddedRedisConfiguration() throws IOException {
this.redisServer = new RedisServer(); this.redisServer = new RedisServer();
} }
@PostConstruct @PostConstruct
public void startRedis() { public void startRedis() throws IOException {
redisServer.start(); redisServer.start();
} }
@PreDestroy @PreDestroy
public void stopRedis() { public void stopRedis() throws IOException {
this.redisServer.stop(); this.redisServer.stop();
} }
} }

View File

@ -16,6 +16,7 @@ import redis.embedded.RedisServer;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.Optional; import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -66,17 +67,17 @@ class ItemServiceCachingIntegrationTest {
private final RedisServer redisServer; private final RedisServer redisServer;
public EmbeddedRedisConfiguration() { public EmbeddedRedisConfiguration() throws IOException {
this.redisServer = new RedisServer(); this.redisServer = new RedisServer();
} }
@PostConstruct @PostConstruct
public void startRedis() { public void startRedis() throws IOException {
redisServer.start(); redisServer.start();
} }
@PreDestroy @PreDestroy
public void stopRedis() { public void stopRedis() throws IOException {
this.redisServer.stop(); this.redisServer.stop();
} }
} }