diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..966ed1f
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,30 @@
+name: Java CI with Maven
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check Repository
+ uses: actions/checkout@v4
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Build with Maven
+ working-directory: user-service
+ run: mvn -B clean verify
+
+ - name: Upload test results
+ uses: actions/upload-artifact@v4
+ with:
+ name: test-results
+ path: user-service/target/surefire-reports/
diff --git a/docker-compose.yml b/docker-compose.yml
index 5c84ea7..ffff7c7 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -58,7 +58,6 @@ services:
interval: 10s
timeout: 10s
retries: 5
-
user-service:
image: user-service:latest
build:
@@ -78,6 +77,13 @@ services:
- KAFKA_BOOTSTRAP_SERVERS=kafka:9093
env_file:
- .env
-
+ redis:
+ image: redis:8.2.1
+ restart: on-failure
+ ports:
+ - "6379:6379"
+ volumes:
+ - redis_data:/data
volumes:
pgdata:
+ redis_data:
diff --git a/user-service/user-service-impl/pom.xml b/user-service/user-service-impl/pom.xml
index 0587f22..f3f2f20 100644
--- a/user-service/user-service-impl/pom.xml
+++ b/user-service/user-service-impl/pom.xml
@@ -97,6 +97,8 @@
spring-boot-starter-hateoas
+
+
org.springdoc
@@ -132,5 +134,18 @@
spring-kafka
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+ 3.5.6
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
-
+
\ No newline at end of file
diff --git a/user-service/user-service-impl/src/main/java/ru/project/iakov/userservice/configuration/ConfigRedis.java b/user-service/user-service-impl/src/main/java/ru/project/iakov/userservice/configuration/ConfigRedis.java
new file mode 100644
index 0000000..7220868
--- /dev/null
+++ b/user-service/user-service-impl/src/main/java/ru/project/iakov/userservice/configuration/ConfigRedis.java
@@ -0,0 +1,53 @@
+package ru.project.iakov.userservice.configuration;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import ru.project.iakov.userservice.domain.entity.User;
+
+import java.time.Duration;
+
+@EnableCaching
+@Configuration
+public class ConfigRedis {
+
+ @Bean
+ public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory,
+ ObjectMapper objectMapper) {
+ RedisTemplate redisTemplate = new RedisTemplate<>();
+ redisTemplate.setConnectionFactory(connectionFactory);
+
+ redisTemplate.setKeySerializer(new StringRedisSerializer());
+
+ var serializer = new Jackson2JsonRedisSerializer<>(objectMapper,User.class);
+ redisTemplate.setValueSerializer(serializer);
+
+ redisTemplate.afterPropertiesSet();
+ return redisTemplate;
+ }
+
+ @Bean
+ public CacheManager cacheManager(RedisConnectionFactory connectionFactory,
+ ObjectMapper objectMapper) {
+ var jsonSerializer = new Jackson2JsonRedisSerializer<>(objectMapper, User.class);
+
+ RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
+ .entryTtl(Duration.ofMinutes(1))
+ .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
+ .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer));
+
+ return RedisCacheManager.builder(connectionFactory)
+ .cacheDefaults(config)
+ .transactionAware()
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/user-service/user-service-impl/src/main/java/ru/project/iakov/userservice/service/impl/UserServiceImpl.java b/user-service/user-service-impl/src/main/java/ru/project/iakov/userservice/service/impl/UserServiceImpl.java
index 2e04e57..b7f156a 100644
--- a/user-service/user-service-impl/src/main/java/ru/project/iakov/userservice/service/impl/UserServiceImpl.java
+++ b/user-service/user-service-impl/src/main/java/ru/project/iakov/userservice/service/impl/UserServiceImpl.java
@@ -2,6 +2,8 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.project.iakov.userservice.domain.entity.User;
@@ -31,6 +33,10 @@ public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
private final KafkaSender kafkaSender;
+ @Cacheable(
+ value = "user",
+ key = "#id"
+ )
@Override
public UserResponse findById(UUID id) {
User user = userRepository.findById(id)
@@ -80,6 +86,10 @@ public UserResponse createUser(UserRequest userRequest) {
return userMapper.toResponse(savedUser);
}
+ @CacheEvict(
+ value = "user",
+ key = "#id"
+ )
@Override
@Transactional
public UserResponse updateUser(UUID id, UserRequest userRequest) {
@@ -105,6 +115,10 @@ public UserResponse updateUser(UUID id, UserRequest userRequest) {
return userMapper.toResponse(updatedUser);
}
+ @CacheEvict(
+ value = "user",
+ key = "#id"
+ )
@Override
@Transactional
public void deleteUser(UUID id) {
diff --git a/user-service/user-service-impl/src/main/resources/application.yml b/user-service/user-service-impl/src/main/resources/application.yml
index 5484fa9..d33ae88 100644
--- a/user-service/user-service-impl/src/main/resources/application.yml
+++ b/user-service/user-service-impl/src/main/resources/application.yml
@@ -12,6 +12,12 @@ spring:
properties:
hibernate:
format_sql: true
+ data:
+ redis:
+ host: ${SPRING_REDIS_HOST:localhost}
+ port: ${SPRING_REDIS_PORT:6379}
+ cache:
+ type: redis
liquibase:
change-log: classpath:db/changelog/db.changelog-master.yaml
jackson:
@@ -28,7 +34,6 @@ spring:
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
-
logging:
level:
ru.project.iakov.userservice.kafka: INFO