diff --git a/src/main/java/ru/soune/nocopy/service/search/GlobalSearchAsyncProcessor.java b/src/main/java/ru/soune/nocopy/service/search/GlobalSearchAsyncProcessor.java index 03f5442..c155366 100644 --- a/src/main/java/ru/soune/nocopy/service/search/GlobalSearchAsyncProcessor.java +++ b/src/main/java/ru/soune/nocopy/service/search/GlobalSearchAsyncProcessor.java @@ -1,11 +1,9 @@ package ru.soune.nocopy.service.search; -import jakarta.mail.MessagingException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import ru.soune.nocopy.configuration.search.SearchProperties; import ru.soune.nocopy.dto.file.YandexSearchResponse; @@ -13,16 +11,8 @@ import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.entity.search.GlobalSearchResult; import ru.soune.nocopy.entity.search.GlobalSearchTask; import ru.soune.nocopy.entity.search.SearchStatus; -import ru.soune.nocopy.entity.tarif.TariffInfo; -import ru.soune.nocopy.entity.user.User; -import ru.soune.nocopy.exception.InsufficientTokensException; -import ru.soune.nocopy.exception.SearchFailedException; -import ru.soune.nocopy.exception.TariffNotFoundException; -import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.repository.GlobalSearchResultRepository; import ru.soune.nocopy.repository.GlobalSearchTaskRepository; -import ru.soune.nocopy.repository.UserRepository; -import ru.soune.nocopy.service.mail.EmailService; import ru.soune.nocopy.service.tariff.TariffConstants; import ru.soune.nocopy.service.tariff.TariffInfoService; import ru.soune.nocopy.service.violation.ViolationService; @@ -51,78 +41,20 @@ public class GlobalSearchAsyncProcessor { private final SearchProperties searchProperties; - private final UserRepository userRepository; - - private final EmailService emailService; - - private final FileEntityRepository fileEntityRepository; - -// @Async -// @Transactional -// public void processFilesAsync(String taskId, List filesToProcess, Long userId) { -// try { -// for (int i = 0; i < filesToProcess.size(); i++) { -// FileEntity file = filesToProcess.get(i); -// -// GlobalSearchResult result = processFile(file, taskId, userId); -// globalSearchResultRepository.save(result); -// -// if (result.getFileStatus().equals(SearchStatus.FAILED.name())) { -// break; -// } -// -// GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); -// task.setProcessedFiles(i + 1); -// task.setUpdatedAt(LocalDateTime.now()); -// globalSearchTaskRepository.save(task); -// } -// -// GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); -// task.setStatus(SearchStatus.COMPLETED.name()); -// task.setUpdatedAt(LocalDateTime.now()); -// globalSearchTaskRepository.save(task); -// -// } catch (Exception e) { -// log.error("Global search failed for task: {}", taskId, e); -// -// GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); -// task.setStatus(SearchStatus.FAILED.name()); -// task.setUpdatedAt(LocalDateTime.now()); -// globalSearchTaskRepository.save(task); -// } -// } - - @Async @Transactional public void processFilesAsync(String taskId, List filesToProcess, Long userId) { try { for (int i = 0; i < filesToProcess.size(); i++) { FileEntity file = filesToProcess.get(i); + tariffInfoService.writeOffTokens(userId, TariffConstants.TOKEN_VALUE_FOR_SEARCH); + GlobalSearchResult result = processFile(file, taskId, userId); + globalSearchResultRepository.save(result); - try { - GlobalSearchResult result = processFile(file.getId(), taskId, userId); - globalSearchResultRepository.save(result); - - if (result.getFileStatus().equals(SearchStatus.FAILED.name()) || - result.getFileStatus().equals(SearchStatus.TIMEOUT.name())) { - throw new SearchFailedException("File processing failed for file: " + file.getId()); - } - - GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); - task.setProcessedFiles(i + 1); - task.setUpdatedAt(LocalDateTime.now()); - globalSearchTaskRepository.save(task); - } catch (InsufficientTokensException e) { - log.error("Task {} failed due to insufficient tokens for user {}", taskId, userId, e); - - updateTaskStatus(taskId, SearchStatus.FAILED.name()); - - } catch (Exception e) { - log.error("Global search failed for task: {}", taskId, e); - - updateTaskStatus(taskId, SearchStatus.FAILED.name()); - } + GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); + task.setProcessedFiles(i + 1); + task.setUpdatedAt(LocalDateTime.now()); + globalSearchTaskRepository.save(task); } GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); @@ -130,55 +62,22 @@ public class GlobalSearchAsyncProcessor { task.setUpdatedAt(LocalDateTime.now()); globalSearchTaskRepository.save(task); - } catch (InsufficientTokensException e) { - log.error("Task {} failed due to insufficient tokens for user {}", taskId, userId, e); + } catch (Exception e) { + log.error("Global search failed for task: {}", taskId, e); GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); task.setStatus(SearchStatus.FAILED.name()); task.setUpdatedAt(LocalDateTime.now()); globalSearchTaskRepository.save(task); - } } - @Transactional(propagation = Propagation.REQUIRES_NEW) - public void updateTaskStatus(String taskId, String status) { - try { - GlobalSearchTask task = globalSearchTaskRepository.findById(taskId).orElseThrow(); - task.setStatus(status); - task.setUpdatedAt(LocalDateTime.now()); - globalSearchTaskRepository.save(task); - } catch (Exception e) { - log.error("Failed to update task status for task: {}", taskId, e); - } - } - - private GlobalSearchResult processFile(String fileId, String taskId, Long userId) throws MessagingException, - IOException, InsufficientTokensException { - FileEntity file = fileEntityRepository.findById(fileId).orElseThrow(); - + private GlobalSearchResult processFile(FileEntity file, String taskId, Long userId) { GlobalSearchResult result = new GlobalSearchResult(); result.setTaskId(taskId); result.setFileId(file.getId()); result.setFileName(file.getOriginalFileName()); - try { - tariffInfoService.writeOffTokens(userId, TariffConstants.TOKEN_VALUE_FOR_SEARCH); - } catch (TariffNotFoundException e) { - User user = userRepository.findById(file.getUserId()).orElseThrow(); - TariffInfo activeTariffInfo = user.getActiveTariffInfo(); - int currentTokens = activeTariffInfo.getTokens() + activeTariffInfo.getBoughtTokens(); - - log.info("Before sending email for user: {}", user.getEmail()); - emailService.sendTokensNotFoundEmail(user, currentTokens, TariffConstants.TOKEN_VALUE_FOR_SEARCH); - log.info("Email sent successfully to user: {}", user.getEmail()); - result.setFileStatus(SearchStatus.FAILED.name()); - - globalSearchResultRepository.save(result); - - throw new InsufficientTokensException("Insufficient tokens for user: " + userId); - } - result = globalSearchResultRepository.save(result); boolean useGoogle = searchProperties.getEngines().getOrDefault("google", diff --git a/src/main/java/ru/soune/nocopy/service/tariff/TariffInfoService.java b/src/main/java/ru/soune/nocopy/service/tariff/TariffInfoService.java index 426a6c6..d288b70 100644 --- a/src/main/java/ru/soune/nocopy/service/tariff/TariffInfoService.java +++ b/src/main/java/ru/soune/nocopy/service/tariff/TariffInfoService.java @@ -1,5 +1,6 @@ package ru.soune.nocopy.service.tariff; +import jakarta.mail.MessagingException; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,7 +14,9 @@ import ru.soune.nocopy.exception.TariffNotFoundException; import ru.soune.nocopy.repository.TariffInfoRepository; import ru.soune.nocopy.repository.TariffRepository; import ru.soune.nocopy.repository.UserRepository; +import ru.soune.nocopy.service.mail.EmailService; +import java.io.IOException; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -28,6 +31,8 @@ public class TariffInfoService { private UserRepository userRepository; + private EmailService emailService; + public TariffInfo createTariffInfo(LocalDateTime startTariff, LocalDateTime endTariff, TariffStatus tariffStatus, Integer tokens) { TariffInfo tariffInfo = new TariffInfo(); @@ -41,7 +46,7 @@ public class TariffInfoService { } @Transactional - public void writeOffTokens(long userId, Integer value) { + public void writeOffTokens(long userId, Integer value) throws MessagingException, IOException { User user = userRepository.findById(userId).orElseThrow(); TariffInfo activeTariffInfo; @@ -55,7 +60,7 @@ public class TariffInfoService { writeOffTokensForTariff(activeTariffInfo, value); } - public void writeOffTokensForTariff(TariffInfo activeTariffInfo, Integer value) { + public void writeOffTokensForTariff(TariffInfo activeTariffInfo, Integer value) throws MessagingException, IOException { Integer tokens = activeTariffInfo.getTokens(); Integer boughtTokens = activeTariffInfo.getBoughtTokens(); @@ -68,6 +73,11 @@ public class TariffInfoService { tariffInfoRepository.save(activeTariffInfo); } else { + int needTokens = boughtTokens - value; + User user = userRepository.findByPersonalTariffInfo(activeTariffInfo); + + emailService.sendTokensNotFoundEmail(user, tokens, Math.abs(needTokens)); + throw new TariffNotFoundException("User not have tokens for protect"); } }