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 7
## task 8
4 changes: 4 additions & 0 deletions src/main/java/task/TaskApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableCaching
@EnableRabbit
@EnableAsync
@EnableScheduling
public class TaskApplication {

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

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
public class AsyncConfig implements AsyncConfigurer {

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("AsyncTask-");
executor.initialize();
return executor;
}
}
15 changes: 14 additions & 1 deletion src/main/java/task/config/RabbitConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@ public class RabbitConfig {
public static final String TASK_EXCHANGE = "task_exchange";
public static final String TASK_ROUTING_KEY = "task.created";

// Новая очередь для просроченных задач
public static final String OVERDUE_TASK_QUEUE = "task_overdue_queue";
public static final String OVERDUE_TASK_ROUTING_KEY = "task.overdue";

@Bean
public Queue taskQueue() {
return QueueBuilder.durable(TASK_QUEUE).build();
}

// для просроченных задач
@Bean
public Queue overdueTaskQueue() {
return QueueBuilder.durable(OVERDUE_TASK_QUEUE).build();
}
@Bean
public TopicExchange taskExchange() {
return new TopicExchange(TASK_EXCHANGE);
Expand All @@ -28,6 +36,11 @@ public TopicExchange taskExchange() {
public Binding taskBinding(Queue taskQueue, TopicExchange taskExchange) {
return BindingBuilder.bind(taskQueue).to(taskExchange).with(TASK_ROUTING_KEY);
}
// для просроченных задач
@Bean
public Binding overdueTaskBinding(Queue overdueTaskQueue, TopicExchange taskExchange) {
return BindingBuilder.bind(overdueTaskQueue).to(taskExchange).with(OVERDUE_TASK_ROUTING_KEY);
}

@Bean
public Jackson2JsonMessageConverter messageConverter() {
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/task/listener/TaskOverdueListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package task.listener;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import task.config.RabbitConfig;
import task.model.Notification;
import task.model.Task;
import task.service.NotificationService;

@Component
@RequiredArgsConstructor
@Slf4j
public class TaskOverdueListener {

private final NotificationService notificationService;

@RabbitListener(queues = RabbitConfig.OVERDUE_TASK_QUEUE)
public void handleOverdueTask(Task task) {
log.warn("Получено событие просроченной задачи из RabbitMQ: #{}", task.getTaskId());

Notification notification = Notification.builder()
.text(" Задача просрочена: " + task.getTaskText())
.taskId(task.getTaskId())
.userId(task.getUserId())
.build();

notificationService.createNotification(notification);

log.info("Уведомление о просроченной задаче #{} создано", task.getTaskId());
}
}
47 changes: 47 additions & 0 deletions src/main/java/task/scheduler/TaskSchedulerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package task.scheduler;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import task.config.RabbitConfig;
import task.model.Task;
import task.repository.TaskRepository;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class TaskSchedulerService {

private final TaskRepository taskRepository;
private final RabbitTemplate rabbitTemplate;

@Scheduled(cron = "${task.check-rate}") // task.check-rate - время проверки просроченных задач задается в application-postgres.properties
@Async
public void checkOverdueTasks() {
log.info("Запуск проверки просроченных задач...");

List<Task> tasks = taskRepository.findByIsDeleteFalse();
LocalDateTime now = LocalDateTime.now();

tasks.stream()
.filter(task -> !task.getIsComplete()
&& task.getActionDate() != null
&& task.getActionDate().isBefore(now))
.forEach(task -> {
log.warn(" Обнаружена просроченная задача #{}: {}", task.getTaskId(), task.getTaskText());
rabbitTemplate.convertAndSend(
RabbitConfig.TASK_EXCHANGE,
RabbitConfig.OVERDUE_TASK_ROUTING_KEY,
task
);
});

log.info("Проверка просроченных задач завершена");
}
}
8 changes: 8 additions & 0 deletions src/main/resources/application-postgres.properties
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,11 @@ spring.rabbitmq.username=guest
spring.rabbitmq.password=guest


# ??????????? ?????
# ????????? ????????? ???????? ?????
# ?????? 4 ???? "0 0 */4 * * *" (00:00, 04:00, 08:00, 12:00, 16:00, 20:00)
# ?????? 2 ???? "0 0 */2 * * *"
# ?????? 5 ????? "0 */5 * * * *"
task.check-rate=0 */5 * * * *