diff --git a/E-Stores-API/pom.xml b/E-Stores-API/pom.xml
index ce38a4a..4cb163e 100644
--- a/E-Stores-API/pom.xml
+++ b/E-Stores-API/pom.xml
@@ -93,9 +93,16 @@
- com.google.guava
- guava
- 32.1.2-jre
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+ org.ehcache
+ ehcache
+
+
+ javax.cache
+ cache-api
diff --git a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheBeanConfig.java b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheBeanConfig.java
new file mode 100644
index 0000000..c0cc594
--- /dev/null
+++ b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheBeanConfig.java
@@ -0,0 +1,32 @@
+package com.devb.estores.cache;
+
+import com.devb.estores.model.User;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.time.Duration;
+
+@Configuration
+public class CacheBeanConfig {
+
+ private CacheConfigurer configure(String cacheName, Class keyType, Class valueType, int heap, int offHeap, Duration ttl) {
+ return CacheConfigurer.builder()
+ .cacheName(cacheName)
+ .keyType(keyType)
+ .valueType(valueType)
+ .heap(heap)
+ .offHeap(offHeap)
+ .ttl(ttl)
+ .build();
+ }
+
+ @Bean
+ CacheConfigurer OtpCache() {
+ return this.configure(CacheName.OTP_CACHE, String.class, Integer.class, 10000, 1, Duration.ofMinutes(5));
+ }
+
+ @Bean
+ CacheConfigurer userCache() {
+ return this.configure(CacheName.USER_CACHE, String.class, User.class, 20000, 10, Duration.ofDays(1));
+ }
+}
diff --git a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheBeansConfig.java b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheBeansConfig.java
deleted file mode 100644
index e29787d..0000000
--- a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheBeansConfig.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.devb.estores.cache;
-
-import com.devb.estores.dto.Attempt;
-import com.devb.estores.dto.OtpModel;
-import com.devb.estores.model.User;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.time.Duration;
-
-@Configuration
-public class CacheBeansConfig {
-
- @Bean
- CacheStore otpCache(){
- return new CacheStore<>(Duration.ofMinutes(5));
- }
-
- @Bean
- CacheStore userCacheStore(){
- return new CacheStore<>(Duration.ofMinutes(10));
- }
-
- @Bean
- CacheStore attemptCacheStore(){
- return new CacheStore<>(Duration.ofMinutes(1));
- }
-}
diff --git a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheConfigurer.java b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheConfigurer.java
new file mode 100644
index 0000000..94a0402
--- /dev/null
+++ b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheConfigurer.java
@@ -0,0 +1,43 @@
+package com.devb.estores.cache;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.ehcache.config.CacheConfiguration;
+import org.ehcache.config.builders.CacheConfigurationBuilder;
+import org.ehcache.config.builders.ExpiryPolicyBuilder;
+import org.ehcache.config.builders.ResourcePoolsBuilder;
+import org.ehcache.config.units.EntryUnit;
+import org.ehcache.config.units.MemoryUnit;
+import org.ehcache.jsr107.Eh107Configuration;
+
+import javax.cache.configuration.Configuration;
+import java.time.Duration;
+
+@Getter
+@Builder
+@Slf4j
+public class CacheConfigurer {
+ private String cacheName;
+ private Class keyType;
+ private Class valueType;
+ private int heap;
+ private int offHeap;
+ private Duration ttl;
+
+ public Configuration getEhCacheConfiguration() {
+ log.info("Configuring Cache with name: {}, heap: {}, offHeap: {}, TTL: {}", this.cacheName, this.heap, this.offHeap, this.ttl.toMinutes() + " Minutes");
+ ResourcePoolsBuilder resourcePoolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder()
+ .heap(this.heap, EntryUnit.ENTRIES).offheap(this.offHeap > 0 ? this.offHeap : 10, MemoryUnit.MB);
+
+ CacheConfiguration cacheConfiguration = CacheConfigurationBuilder
+ .newCacheConfigurationBuilder(
+ this.keyType,
+ this.valueType,
+ resourcePoolsBuilder)
+ .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(this.ttl))
+ .build();
+
+ return Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration);
+ }
+}
diff --git a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheInitializer.java b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheInitializer.java
new file mode 100644
index 0000000..82c4262
--- /dev/null
+++ b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheInitializer.java
@@ -0,0 +1,31 @@
+package com.devb.estores.cache;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.jcache.JCacheCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.spi.CachingProvider;
+import java.util.List;
+
+@Configuration
+@EnableCaching
+@Slf4j
+public class CacheInitializer {
+
+ @Bean
+ JCacheCacheManager cacheManager(List> cacheConfigurers) {
+ log.info("Configuring CacheManger, {} cache configurations found", cacheConfigurers.size());
+ CachingProvider provider = Caching.getCachingProvider();
+ CacheManager manager = provider.getCacheManager();
+
+ cacheConfigurers.forEach(cacheConfigurer -> {
+ manager.createCache(cacheConfigurer.getCacheName(), cacheConfigurer.getEhCacheConfiguration());
+ });
+
+ return new JCacheCacheManager(manager);
+ }
+}
diff --git a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheName.java b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheName.java
new file mode 100644
index 0000000..8a0cd55
--- /dev/null
+++ b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheName.java
@@ -0,0 +1,6 @@
+package com.devb.estores.cache;
+
+public class CacheName {
+ public static final String OTP_CACHE = "otp-cache";
+ public static final String USER_CACHE = "user-cache";
+}
diff --git a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheService.java b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheService.java
new file mode 100644
index 0000000..cc02d23
--- /dev/null
+++ b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheService.java
@@ -0,0 +1,45 @@
+package com.devb.estores.cache;
+
+import lombok.AllArgsConstructor;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class CacheService {
+
+ private final CacheManager cacheManager;
+
+ public boolean doEntry(String cacheName, K key, V value) {
+ Cache cache = cacheManager.getCache(cacheName);
+ if(cache != null) {
+ cache.put(key, value);
+ return true;
+ } else return false;
+ }
+
+ public V getEntry(String cacheName, K key, Class type) {
+ Cache cache = cacheManager.getCache(cacheName);
+ if(cache != null)
+ return cache.get(key, type);
+ else return null;
+ }
+
+ public boolean evictEntry(String cacheName, K key) {
+ Cache cache = cacheManager.getCache(cacheName);
+ if(cache != null) {
+ cache.evict(key);
+ return true;
+ } else return false;
+ }
+
+ public boolean clearCache(String cacheName) {
+ Cache cache = cacheManager.getCache(cacheName);
+ if (cache != null) {
+ cache.clear();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheStore.java b/E-Stores-API/src/main/java/com/devb/estores/cache/CacheStore.java
deleted file mode 100644
index 27a823c..0000000
--- a/E-Stores-API/src/main/java/com/devb/estores/cache/CacheStore.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.devb.estores.cache;
-
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import lombok.extern.slf4j.Slf4j;
-
-import java.time.Duration;
-
-@Slf4j
-public class CacheStore {
-
- private final Cache cache;
-
- public CacheStore(Duration expiry) {
- this.cache = CacheBuilder.newBuilder()
- .expireAfterWrite(expiry)
- .concurrencyLevel(Runtime.getRuntime().availableProcessors()).build();
- }
-
- public T get(String key){
- return cache.getIfPresent(key);
- }
-
- public void add(String key, T value){
- cache.put(key, value);
- }
-
- public void remove(String key){
- cache.invalidate(key);
- }
-}
diff --git a/E-Stores-API/src/main/java/com/devb/estores/model/User.java b/E-Stores-API/src/main/java/com/devb/estores/model/User.java
index 70b9ce2..3494ab0 100644
--- a/E-Stores-API/src/main/java/com/devb/estores/model/User.java
+++ b/E-Stores-API/src/main/java/com/devb/estores/model/User.java
@@ -6,6 +6,7 @@
import lombok.*;
import org.hibernate.annotations.GenericGenerator;
+import java.io.Serializable;
import java.util.List;
@Entity
@@ -17,7 +18,7 @@
@AllArgsConstructor
@NoArgsConstructor
@ToString
-public class User {
+public class User implements Serializable {
@Id
@GeneratedValue(generator = "custom")
@GenericGenerator(name = "custom", type = IdGenerator.class)
diff --git a/E-Stores-API/src/main/java/com/devb/estores/serviceimpl/AuthServiceImpl.java b/E-Stores-API/src/main/java/com/devb/estores/serviceimpl/AuthServiceImpl.java
index e52dc09..0e725b1 100644
--- a/E-Stores-API/src/main/java/com/devb/estores/serviceimpl/AuthServiceImpl.java
+++ b/E-Stores-API/src/main/java/com/devb/estores/serviceimpl/AuthServiceImpl.java
@@ -1,6 +1,7 @@
package com.devb.estores.serviceimpl;
-import com.devb.estores.cache.CacheStore;
+import com.devb.estores.cache.CacheName;
+import com.devb.estores.cache.CacheService;
import com.devb.estores.config.AppEnv;
import com.devb.estores.dto.MessageData;
import com.devb.estores.dto.OtpModel;
@@ -41,13 +42,12 @@ public class AuthServiceImpl implements AuthService {
private final UserRepo userRepo;
private final PasswordEncoder passwordEncoder;
private final MailService mailService;
- private final CacheStore otpCache;
- private final CacheStore userCacheStore;
private final JwtService jwtService;
private final AuthenticationManager authenticationManager;
private final CookieManager cookieManager;
private final Random random;
private final AppEnv appEnv;
+ private final CacheService cacheService;
public static final String FAILED_REFRESH = "Failed to refresh login";
public static final String FAILED_OTP_VERIFICATION = "Failed to verify OTP";
@@ -61,16 +61,14 @@ public String registerUser(UserRequest userRequest, UserRole role) {
User user = mapToUserEntity(userRequest, role);
// caching user data
- userCacheStore.add(user.getEmail(), user);
+ cacheService.doEntry(CacheName.USER_CACHE, user.getEmail(), user);
- // Generate the OTP and provide the ID of the OTP as a path variable to the confirmation link.
- OtpModel otp = OtpModel.builder()
- .otp(random.nextInt(100000, 999999))
- .email(user.getEmail()).build();
- otpCache.add(otp.getEmail(), otp);
+ // Generating OTP and caching to otp-cache
+ int otp = random.nextInt(100000, 999999);
+ cacheService.doEntry(CacheName.OTP_CACHE, user.getEmail(), otp);
try {
- sendOTPToMailId(user, otp.getOtp());
+ sendOTPToMailId(user, otp);
return "Verify Email using the OTP sent to " + user.getEmail();
} catch (MessagingException e) {
throw new EmailNotFoundException("Failed to verify the email ID");
@@ -79,17 +77,19 @@ public String registerUser(UserRequest userRequest, UserRole role) {
@Override
public UserResponse verifyUserEmail(OtpModel otpModel) {
- OtpModel otp = otpCache.get(otpModel.getEmail());
- User user = userCacheStore.get(otpModel.getEmail());
+ Integer otp = cacheService.getEntry(CacheName.OTP_CACHE, otpModel.getEmail(), Integer.class);
+ User user = cacheService.getEntry(CacheName.USER_CACHE, otpModel.getEmail(), User.class);
if (otp == null) throw new OtpExpiredException(FAILED_OTP_VERIFICATION);
if (user == null) throw new RegistrationSessionExpiredException(FAILED_OTP_VERIFICATION);
- if (otp.getOtp() != otpModel.getOtp()) throw new IncorrectOTPException(FAILED_OTP_VERIFICATION);
+ if (otp != otpModel.getOtp()) throw new IncorrectOTPException(FAILED_OTP_VERIFICATION);
user.setEmailVerified(true);
user = userRepo.save(user);
- otpCache.remove(otpModel.getEmail());
+ cacheService.evictEntry(CacheName.USER_CACHE, user.getEmail());
+ cacheService.evictEntry(CacheName.OTP_CACHE, user.getEmail());
+
try {
sendConfirmationMail(user);
return mapToUserResponse(user);