JAVA-13870 Move spring-caching,spring-caching-2 to spring-boot-module… (#13457)
* JAVA-13870 Move spring-caching,spring-caching-2 to spring-boot-modules (conti-1) * JAVA-13870 Making spring boot as the parent for spring-caching and spring caching-2 --------- Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.caching.redis;
|
||||
|
||||
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair;
|
||||
|
||||
@Configuration
|
||||
public class CacheConfig {
|
||||
|
||||
@Bean
|
||||
public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() {
|
||||
return (builder) -> builder
|
||||
.withCacheConfiguration("itemCache",
|
||||
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)))
|
||||
.withCacheConfiguration("customerCache",
|
||||
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisCacheConfiguration cacheConfiguration() {
|
||||
return RedisCacheConfiguration.defaultCacheConfig()
|
||||
.entryTtl(Duration.ofMinutes(60))
|
||||
.disableCachingNullValues()
|
||||
.serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.caching.redis;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Item implements Serializable {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
|
||||
String description;
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.caching.redis;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
public class ItemController {
|
||||
|
||||
private final ItemService itemService;
|
||||
|
||||
@GetMapping("/item/{id}")
|
||||
public Item getItemById(@PathVariable String id) {
|
||||
return itemService.getItemForId(id);
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.caching.redis;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface ItemRepository extends CrudRepository<Item, String> {
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.caching.redis;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class ItemService {
|
||||
|
||||
private final ItemRepository itemRepository;
|
||||
|
||||
@Cacheable(value = "itemCache")
|
||||
public Item getItemForId(String id) {
|
||||
return itemRepository.findById(id)
|
||||
.orElseThrow(RuntimeException::new);
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.caching.redis;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableCaching
|
||||
public class RedisCacheApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(RedisCacheApplication.class, args);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.caching.ttl;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
public class CachingTTLApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CachingTTLApplication.class, args);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.caching.ttl.config;
|
||||
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class SpringCachingConfig {
|
||||
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
return new ConcurrentMapCacheManager("hotels");
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.caching.ttl.controller;
|
||||
|
||||
import com.baeldung.caching.ttl.service.HotelService;
|
||||
import com.baeldung.caching.ttl.model.Hotel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/hotel")
|
||||
public class HotelController {
|
||||
private final HotelService hotelService;
|
||||
|
||||
@Autowired
|
||||
public HotelController(HotelService hotelService) {
|
||||
this.hotelService = hotelService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public List<Hotel> getAllHotels() {
|
||||
return hotelService.getAllHotels();
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.caching.ttl.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ControllerAdvice
|
||||
public class ControllerAdvisor extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler(ElementNotFoundException.class)
|
||||
public ResponseEntity<Object> handleNodataFoundException(
|
||||
ElementNotFoundException ex) {
|
||||
|
||||
Map<String, Object> body = new LinkedHashMap<>();
|
||||
body.put("status", 404);
|
||||
body.put("error", "Not Found");
|
||||
body.put("message", ex.getMessage());
|
||||
|
||||
return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.caching.ttl.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
public class ElementNotFoundException extends RuntimeException {
|
||||
private static final long serialVersionUID = -5218143265247846948L;
|
||||
|
||||
public ElementNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.baeldung.caching.ttl.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
public class City implements Serializable {
|
||||
private static final long serialVersionUID = 3252591505029724236L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private double cityCentreLattitude;
|
||||
private double cityCentreLongitude;
|
||||
|
||||
public City() {}
|
||||
|
||||
public City(Long id, String name, double cityCentreLatitude, double cityCentreLongitude) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.cityCentreLattitude = cityCentreLatitude;
|
||||
this.cityCentreLongitude = cityCentreLongitude;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public double getCityCentreLatitude() {
|
||||
return cityCentreLattitude;
|
||||
}
|
||||
|
||||
public double getCityCentreLongitude() {
|
||||
return cityCentreLongitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
City city = (City) o;
|
||||
|
||||
if (Double.compare(city.cityCentreLattitude, cityCentreLattitude) != 0) return false;
|
||||
if (Double.compare(city.cityCentreLongitude, cityCentreLongitude) != 0) return false;
|
||||
if (!Objects.equals(id, city.id)) return false;
|
||||
return Objects.equals(name, city.name);
|
||||
}
|
||||
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package com.baeldung.caching.ttl.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
public class Hotel implements Serializable {
|
||||
private static final long serialVersionUID = 5560221391479816650L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
private Double rating;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
|
||||
private City city;
|
||||
|
||||
private String address;
|
||||
private double lattitude;
|
||||
private double longitude;
|
||||
private boolean deleted = false;
|
||||
|
||||
public Hotel() {}
|
||||
|
||||
public Hotel(
|
||||
Long id,
|
||||
String name,
|
||||
Double rating,
|
||||
City city,
|
||||
String address,
|
||||
double lattitude,
|
||||
double longitude,
|
||||
boolean deleted) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.rating = rating;
|
||||
this.city = city;
|
||||
this.address = address;
|
||||
this.lattitude = lattitude;
|
||||
this.longitude = longitude;
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Double getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(Double rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public City getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(City city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return lattitude;
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
this.lattitude = latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public void setDeleted(boolean deleted) {
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Hotel hotel = (Hotel) o;
|
||||
|
||||
if (Double.compare(hotel.lattitude, lattitude) != 0) return false;
|
||||
if (Double.compare(hotel.longitude, longitude) != 0) return false;
|
||||
if (deleted != hotel.deleted) return false;
|
||||
if (!Objects.equals(id, hotel.id)) return false;
|
||||
if (!Objects.equals(name, hotel.name)) return false;
|
||||
if (!Objects.equals(rating, hotel.rating)) return false;
|
||||
if (!Objects.equals(city, hotel.city)) return false;
|
||||
return Objects.equals(address, hotel.address);
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.caching.ttl.repository;
|
||||
|
||||
import com.baeldung.caching.ttl.model.City;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface CityRepository extends JpaRepository<City, Long> {}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.caching.ttl.repository;
|
||||
|
||||
import com.baeldung.caching.ttl.model.Hotel;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface HotelRepository extends JpaRepository<Hotel, Long> {
|
||||
|
||||
default List<Hotel> getAllHotels() {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return findAll();
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.caching.ttl.service;
|
||||
|
||||
import com.baeldung.caching.ttl.repository.HotelRepository;
|
||||
import com.baeldung.caching.ttl.model.Hotel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class HotelService {
|
||||
|
||||
private final HotelRepository hotelRepository;
|
||||
Logger logger = LoggerFactory.getLogger(HotelService.class);
|
||||
|
||||
HotelService(HotelRepository hotelRepository) {
|
||||
this.hotelRepository = hotelRepository;
|
||||
}
|
||||
|
||||
@Cacheable("hotels")
|
||||
public List<Hotel> getAllHotels() {
|
||||
return hotelRepository.getAllHotels();
|
||||
}
|
||||
|
||||
@CacheEvict(value = "hotels", allEntries = true)
|
||||
@Scheduled(fixedRateString = "${caching.spring.hotelListTTL}")
|
||||
public void emptyHotelsCache() {
|
||||
logger.info("emptying Hotels cache");
|
||||
}
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.caching.ttl.service;
|
||||
|
||||
import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
@Component
|
||||
public class SpringCacheCustomizer implements CacheManagerCustomizer<ConcurrentMapCacheManager> {
|
||||
|
||||
@Override
|
||||
public void customize(ConcurrentMapCacheManager cacheManager) {
|
||||
cacheManager.setCacheNames(asList("hotels"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
# Enabling H2 Console
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.path=/h2
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
#setting cache TTL
|
||||
caching.spring.hotelListTTL=43200
|
||||
# Connection details
|
||||
#spring.redis.host=localhost
|
||||
#spring.redis.port=6379
|
||||
@@ -0,0 +1,67 @@
|
||||
DROP TABLE IF EXISTS ITEM;
|
||||
create table ITEM
|
||||
(
|
||||
ID CHARACTER VARYING not null,
|
||||
DESCRIPTION CHARACTER VARYING,
|
||||
constraint ITEM_PK
|
||||
primary key (ID)
|
||||
);
|
||||
DROP TABLE IF EXISTS HOTEL;
|
||||
DROP TABLE IF EXISTS CITY;
|
||||
create table CITY
|
||||
(
|
||||
id bigint,
|
||||
name varchar,
|
||||
city_centre_lattitude double,
|
||||
city_centre_longitude double,
|
||||
constraint city_pk
|
||||
primary key (id)
|
||||
);
|
||||
create table hotel
|
||||
(
|
||||
id bigint auto_increment,
|
||||
name varchar,
|
||||
deleted boolean,
|
||||
rating double,
|
||||
city_id bigint,
|
||||
address varchar,
|
||||
lattitude varchar,
|
||||
longitude varchar,
|
||||
constraint hotel_pk
|
||||
primary key (id),
|
||||
constraint "hotel_CITY_null_fk"
|
||||
foreign key (city_id) references CITY (id)
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO ITEM VALUES('abc','ITEM1');
|
||||
|
||||
|
||||
INSERT INTO city(id, name, city_centre_lattitude, city_centre_longitude)
|
||||
VALUES (1, 'Amsterdam', 52.368780, 4.903303);
|
||||
INSERT INTO city(id, name, city_centre_lattitude, city_centre_longitude)
|
||||
VALUES (2, 'Manchester', 53.481062, -2.237706);
|
||||
|
||||
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('Monaghan Hotel', false, 9.2, 1, 'Weesperbuurt en Plantage', 52.364799, 4.908971);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('The Thornton Council Hotel', false, 6.3, 1, 'Waterlooplein', 52.3681563, 4.9010029);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('McZoe Trescothiks Hotel', false, 9.8, 1, 'Oude Stad, Harlem', 52.379577, 4.633547);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('Stay Schmtay Hotel', false, 8.7, 1, 'Jan van Galenstraat', 52.3756755, 4.8668628);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('Fitting Image Hotel', false, NULL, 1, 'Staatsliedenbuurt', 52.380936, 4.8708297);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('Raymond of Amsterdam Hotel', false, NULL, 1, '22 High Avenue', 52.3773989, 4.8846443);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('201 Deansgate Hotel', false, 7.3, 2, '201 Deansgate', 53.4788305, -2.2484721);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('Fountain Street Hotel', true, 3.0, 2, '35 Fountain Street', 53.4811298, -2.2402227);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('Sunlight House', false, 4.3, 2, 'Little Quay St', 53.4785129, -2.2505943);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('St Georges House', false, 9.6, 2, '56 Peter St', 53.477822, -2.2462002);
|
||||
INSERT INTO hotel(name, deleted, rating, city_id, address, lattitude, longitude)
|
||||
VALUES ('Marriot Bonvoy', false, 9.6, 1, 'Hans Zimmerstraat', 53.477872, -2.2462003);
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.baeldung.caching.redis;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import redis.embedded.RedisServer;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@Import({ CacheConfig.class, ItemService.class })
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ImportAutoConfiguration(classes = { CacheAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
@EnableCaching
|
||||
class ItemServiceCachingIntegrationTest {
|
||||
|
||||
private static final String AN_ID = "id-1";
|
||||
private static final String A_DESCRIPTION = "an item";
|
||||
|
||||
@MockBean
|
||||
private ItemRepository mockItemRepository;
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@Test
|
||||
void givenRedisCaching_whenFindItemById_thenItemReturnedFromCache() {
|
||||
Item anItem = new Item(AN_ID, A_DESCRIPTION);
|
||||
given(mockItemRepository.findById(AN_ID))
|
||||
.willReturn(Optional.of(anItem));
|
||||
|
||||
Item itemCacheMiss = itemService.getItemForId(AN_ID);
|
||||
Item itemCacheHit = itemService.getItemForId(AN_ID);
|
||||
|
||||
assertThat(itemCacheMiss).isEqualTo(anItem);
|
||||
assertThat(itemCacheHit).isEqualTo(anItem);
|
||||
|
||||
verify(mockItemRepository, times(1)).findById(AN_ID);
|
||||
assertThat(itemFromCache()).isEqualTo(anItem);
|
||||
}
|
||||
|
||||
private Object itemFromCache() {
|
||||
return cacheManager.getCache("itemCache").get(AN_ID).get();
|
||||
}
|
||||
|
||||
@TestConfiguration
|
||||
static class EmbeddedRedisConfiguration {
|
||||
|
||||
private final RedisServer redisServer;
|
||||
|
||||
public EmbeddedRedisConfiguration() {
|
||||
this.redisServer = new RedisServer();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void startRedis() {
|
||||
redisServer.start();
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void stopRedis() {
|
||||
this.redisServer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.caching.ttl;
|
||||
|
||||
import com.baeldung.caching.ttl.repository.HotelRepository;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
|
||||
@AutoConfigureMockMvc
|
||||
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:data.sql")
|
||||
@SlowTest
|
||||
class HotelControllerIntegrationTest {
|
||||
@Autowired private MockMvc mockMvc;
|
||||
@Autowired private HotelRepository repository;
|
||||
|
||||
@Test
|
||||
@DisplayName("When all hotels requested then request is successful")
|
||||
void whenAllHotelsRequested_thenRequestIsSuccessful() throws Exception {
|
||||
mockMvc
|
||||
.perform(get("/hotel"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("When all hotels are requested then they correct number of hotels is returned")
|
||||
void whenAllHotelsRequested_thenReturnAllHotels() throws Exception {
|
||||
mockMvc
|
||||
.perform(get("/hotel"))
|
||||
.andExpect(jsonPath("$", hasSize((int) repository.findAll().stream().count())));
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package com.baeldung.caching.ttl;
|
||||
|
||||
public @interface SlowTest {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
|
||||
# Enabling H2 Console
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.path=/h2
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=false
|
||||
caching.spring.hotelListTTL=43200
|
||||
# Connection details
|
||||
#spring.redis.host=localhost
|
||||
#spring.redis.port=6379
|
||||
server.port=8000
|
||||
Reference in New Issue
Block a user