Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# REST API using Spring Boot

## task 5
## task 6
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ services:
- SPRING_PROFILES_ACTIVE=${PROFILE:-postgres}
depends_on:
- postgres
- redis

postgres:
image: postgres:15.0-alpine
Expand All @@ -23,6 +24,12 @@ services:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
container_name: redis
ports:
- "6379:6379"
restart: always

volumes:
pgdata:
Expand Down
13 changes: 12 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,19 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Кэширование -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<!-- Jackson Datatype JS310 (hỗ trợ Java 8 Date/Time trong JSON) -->
<!-- Jackson Datatype JS310 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/task/TaskApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class TaskApplication {

public static void main(String[] args) {
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/task/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package task.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
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.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.text.SimpleDateFormat;
import java.time.Duration;

@Configuration
@EnableCaching
public class RedisConfig {

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {

// Настраиваем ObjectMapper, чтобы поддерживал LocalDateTime
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule()); // поддержка LocalDateTime
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));


GenericJackson2JsonRedisSerializer serializer =
new GenericJackson2JsonRedisSerializer(objectMapper);

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))
.disableCachingNullValues();
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.build();
}
}
18 changes: 17 additions & 1 deletion src/main/java/task/service/impl/TaskServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import java.util.stream.Collectors;

import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

import task.model.Notification;
import task.model.Task;
Expand All @@ -19,22 +22,35 @@ public class TaskServiceImpl implements TaskService {
private final TaskRepository taskRepository;

@Override
@Cacheable(value = "tasks", key = "'all'")
public List<Task> getAllTasks() {
return taskRepository.findByIsDeleteFalse();
}
@Override
public List<Task> getUserTasks(Long userId) {
@Cacheable(value = "tasks", key = "'user:' + #userId")
public List<Task> getUserTasks(Long userId) {
return taskRepository.findByUserIdAndIsDeleteFalse(userId);
}
@Override
@Cacheable(value = "tasks", key = "'pending user:' + #userId")
public List<Task> getUserTasksPending(Long userId) {
return taskRepository.findByUserIdAndIsCompleteFalseAndIsDeleteFalse(userId);
}
@Override
@Caching(evict = {
@CacheEvict(value = "tasks", key = "'all'"),
@CacheEvict(value = "tasks", key = "'user:' + #task.userId"),
@CacheEvict(value = "tasks", key = "'pending user:' + #task.userId")
})
public Task createTask(Task task) {
return taskRepository.save(task);
}
@Override
@Caching(evict = {
@CacheEvict(value = "tasks", key = "'all'"),
@CacheEvict(value = "tasks", key = "'user:' + #task.userId"),
@CacheEvict(value = "tasks", key = "'pending user:' + #task.userId")
})
public void deleteTask(Long taskId) {
taskRepository.markAsDeleted(taskId);
}
Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/application-postgres.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@ spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration
spring.flyway.baseline-on-migrate=true

# Cache Redis
spring.cache.type=redis
spring.data.redis.host=redis
spring.data.redis.port=6379
spring.data.redis.timeout=60000