From 64c6791cc32d5e044fa2433fc58d495a7f3d1238 Mon Sep 17 00:00:00 2001 From: bcjang Date: Thu, 13 Mar 2025 14:42:17 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=EB=9F=AC=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/scheduler/CommonScheduler.java | 23 + .../admin/scheduler/ScheduleRunner.java | 185 -------- .../admin/scheduler/ScheduleSetter.java | 2 +- .../caliverse/admin/scheduler/Scheduler.java | 6 +- .../admin/scheduler/SchedulerManager.java | 429 ++---------------- .../admin/scheduler/SchedulerService.java | 53 --- .../scheduler/batch/ScheduleRunnerBatch.java | 31 ++ .../service/LogCompressService.java | 2 +- .../service/impl/LogCompressServiceImpl.java | 4 +- .../config/MissedExecutionConfig.java | 18 - .../config/ScheduleExecutionConfig.java | 29 -- .../config/ScheduleSystemConfig.java | 24 - .../scheduler/{ => entity}/ScheduleType.java | 2 +- .../admin/scheduler/entity/SchedulerType.java | 12 + .../polling/ScheduleRunnerPolling.java | 182 ++++++++ .../service/LandOwnerChangesScheduler.java | 64 +++ .../scheduler/service/BlackListScheduler.java | 84 ---- .../scheduler/service/EventScheduler.java | 216 --------- .../scheduler/service/MailScheduler.java | 194 -------- .../scheduler/service/NoticeScheduler.java | 228 ---------- 20 files changed, 345 insertions(+), 1443 deletions(-) create mode 100644 src/main/java/com/caliverse/admin/scheduler/CommonScheduler.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/ScheduleRunner.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/SchedulerService.java create mode 100644 src/main/java/com/caliverse/admin/scheduler/batch/ScheduleRunnerBatch.java rename src/main/java/com/caliverse/admin/scheduler/{ => batch}/service/LogCompressService.java (58%) rename src/main/java/com/caliverse/admin/scheduler/{ => batch}/service/impl/LogCompressServiceImpl.java (95%) delete mode 100644 src/main/java/com/caliverse/admin/scheduler/config/MissedExecutionConfig.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/config/ScheduleExecutionConfig.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/config/ScheduleSystemConfig.java rename src/main/java/com/caliverse/admin/scheduler/{ => entity}/ScheduleType.java (77%) create mode 100644 src/main/java/com/caliverse/admin/scheduler/entity/SchedulerType.java create mode 100644 src/main/java/com/caliverse/admin/scheduler/polling/ScheduleRunnerPolling.java create mode 100644 src/main/java/com/caliverse/admin/scheduler/polling/service/LandOwnerChangesScheduler.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/service/BlackListScheduler.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/service/EventScheduler.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/service/MailScheduler.java delete mode 100644 src/main/java/com/caliverse/admin/scheduler/service/NoticeScheduler.java diff --git a/src/main/java/com/caliverse/admin/scheduler/CommonScheduler.java b/src/main/java/com/caliverse/admin/scheduler/CommonScheduler.java new file mode 100644 index 0000000..19b44d0 --- /dev/null +++ b/src/main/java/com/caliverse/admin/scheduler/CommonScheduler.java @@ -0,0 +1,23 @@ +package com.caliverse.admin.scheduler; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class CommonScheduler implements Scheduler { + + @Override + public void execute() { + try { + log.info("Start executing scheduler: {}", getSchedulerType()); + executeInternal(); + log.info("Finished executing scheduler: {}", getSchedulerType()); + } catch (Exception e) { + log.error("Error executing scheduler {}: {}", getSchedulerType(), e.getMessage(), e); + } + } + + /** + * 스케줄러 구현체에서 실제 작업을 수행하는 메소드 + */ + protected abstract void executeInternal(); +} diff --git a/src/main/java/com/caliverse/admin/scheduler/ScheduleRunner.java b/src/main/java/com/caliverse/admin/scheduler/ScheduleRunner.java deleted file mode 100644 index 5768a23..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/ScheduleRunner.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.caliverse.admin.scheduler; - -import com.caliverse.admin.domain.RabbitMq.MessageHandlerService; -import com.caliverse.admin.domain.entity.BlackList; -import com.caliverse.admin.domain.entity.Event; -import com.caliverse.admin.domain.entity.InGame; -import com.caliverse.admin.domain.entity.Mail; -import com.caliverse.admin.domain.service.*; -import com.caliverse.admin.global.common.utils.ExcelUtils; -import com.caliverse.admin.logs.logservice.indicators.*; -import com.caliverse.admin.redis.service.RedisUserInfoService; -import com.caliverse.admin.scheduler.service.BlackListScheduler; -import com.caliverse.admin.scheduler.service.EventScheduler; -import com.caliverse.admin.scheduler.service.MailScheduler; -import com.caliverse.admin.scheduler.service.NoticeScheduler; -import org.springframework.beans.factory.annotation.Autowired; -// import org.springframework.batch.core.JobParameters; -// import org.springframework.batch.core.JobParametersBuilder; -// import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - - -import com.caliverse.admin.global.common.constants.AdminConstants; -import com.caliverse.admin.logs.Indicatordomain.StartEndTime; -import com.caliverse.admin.logs.logservice.LogServiceHelper; - -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -@Component -@Slf4j -@EnableScheduling -public class ScheduleRunner { - @Autowired private IndicatorsAuService auService; - @Autowired private IndicatorsDauService dauService; - @Autowired private IndicatorsWauService wauService; - @Autowired private IndicatorsMauService mauService; - @Autowired private IndicatorsMcuService mcuService; - @Autowired private IndicatorsNruService statNruService; - - @Autowired private RedisUserInfoService userInfoService; - @Autowired private SchedulerManager schedulerManager; - @Autowired private DynamicScheduler dynamicScheduler; - @Autowired private MailService mailService; - @Autowired private NoticeService noticeService; - @Autowired private BlackListService blackListService; - @Autowired private EventService eventService; - @Autowired - private RedisUserInfoService redisUserInfoService; - @Autowired - private MessageHandlerService messageHandlerService; - @Autowired - private ExcelUtils excelUtils; - - /* - 매일 UTC 기준 00시 50분 00초에 실행, (한국 시간 9시 50분) 30분에 돌릴경우 데이터가 다 넘어 오지 않는 경우 있어서 수정처리 - 이게 가장 먼저 실행 되어야 한다. - 로그가 많을 경우 성능 이슈 있을 수 있음 - */ - @Scheduled(cron = "0 50 0 * * *") - public void auScheduler() { - //이걸 나중에 어떻게 활용할지 생각해보자. - log.info("run auScheduler"); - StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); - auService.collectActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); - log.info("end auScheduler"); - } - -// @Scheduled(cron = "00 55 0 * * *") // 매일 UTC 기준 00시 56분 00초에 실행 - @Scheduled(cron = "1 * * * * *") // 매일 UTC 기준 00시 56분 00초에 실행 - public void dauScheduler() { - log.info("run dauScheduler"); - StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); - dauService.collectDailyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); - log.info("end dauScheduler"); - } - - @Scheduled(cron = "00 56 0 * * *") // 매일 UTC 기준 00시 56분 00초에 실행 - public void wauScheduler() { - log.info("run wauScheduler"); - StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_WEEK_NUM); - wauService.collectWeeklyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); - log.info("end wauScheduler"); - } - - @Scheduled(cron = "00 57 0 * * *") // 매일 UTC 기준 00시 57분 00초에 실행 - public void mauScheduler() { - log.info("run mauScheduler"); - StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_MONTH_NUM); - mauService.collectMonthlyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); - log.info("end mauScheduler"); - } - - @Scheduled(cron = "00 58 0 * * *") // 매일 UTC 기준 00시 58분 00초에 실행 - public void mcuScheduler() { - log.info("run mcuScheduler"); - StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); - mcuService.collectMaxCountUser(startEndTime.getStartTime(), startEndTime.getEndTime()); - log.info("end mcuScheduler"); - } - - @Scheduled(cron = "00 59 0 * * *") // 매일 UTC 기준 00시 59분 00초에 실행 - public void nruScheduler() { - log.info("run mcuScheduler"); - //StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); - //statNruService.collectStatLogs(startEndTime.getStartTime(), startEndTime.getEndTime()); - log.info("end mcuScheduler"); - } - - @Scheduled(cron = "1 * * * * *") - public void noticeJob(){ - log.info("run noticeJob"); - List noticeList = noticeService.getScheduleNoticeList(); - noticeList.forEach(notice -> { - if (notice.getIsRepeat() && - notice.getRepeatType() == InGame.REPEATTYPE.COUNT && - notice.getSendCnt() >= notice.getRepeatCnt()) { - log.info("Skipping notice - already reached max count. NoticeId: {}", notice.getId()); - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FINISH); - return; - } - - NoticeScheduler task = NoticeScheduler.builder() - .notice(notice) - .noticeService(noticeService) - .redisUserInfoService(redisUserInfoService) - .messageHandlerService(messageHandlerService) - .build(); - schedulerManager.scheduleTask(task); - }); - log.info("end noticeJob"); - } - - @Scheduled(cron = "2 * * * * *") - public void mailJob(){ - log.info("run mailJob"); - List mailList = mailService.getScheduleMailList(); - mailList.stream() - .filter(mail -> mail.getSendStatus().equals(Mail.SENDSTATUS.WAIT)) - .forEach(mail -> { - MailScheduler task = MailScheduler.builder() - .mail(mail) - .mailService(mailService) - .redisUserInfoService(redisUserInfoService) - .messageHandlerService(messageHandlerService) - .excelUtils(excelUtils) - .build(); - schedulerManager.scheduleTask(task); - }); - log.info("end mailJob"); - } - - @Scheduled(cron = "3 * * * * *") - public void blackListJob(){ - log.info("run blackListJob"); - List blackList = blackListService.getScheduleBlackList(); - blackList.forEach(blockUser -> { - BlackListScheduler task = BlackListScheduler.builder() - .blackList(blockUser) - .blackListService(blackListService) - .build(); - schedulerManager.scheduleTask(task); - }); - log.info("end blackListJob"); - } - - @Scheduled(cron = "4 * * * * *") - public void eventJob(){ - log.info("run eventJob"); - List eventList = eventService.getScheduleMailList(); - eventList.forEach(event -> { - EventScheduler task = EventScheduler.builder() - .event(event) - .eventService(eventService) - .redisUserInfoService(redisUserInfoService) - .messageHandlerService(messageHandlerService) - .build(); - schedulerManager.scheduleTask(task); - }); - log.info("end eventJob"); - } -} diff --git a/src/main/java/com/caliverse/admin/scheduler/ScheduleSetter.java b/src/main/java/com/caliverse/admin/scheduler/ScheduleSetter.java index 317f40c..5e86464 100644 --- a/src/main/java/com/caliverse/admin/scheduler/ScheduleSetter.java +++ b/src/main/java/com/caliverse/admin/scheduler/ScheduleSetter.java @@ -3,7 +3,7 @@ package com.caliverse.admin.scheduler; import com.caliverse.admin.domain.service.CaliumService; import com.caliverse.admin.global.common.utils.CommonUtils; import com.caliverse.admin.logs.logservice.indicators.*; -import com.caliverse.admin.scheduler.service.LogCompressService; +import com.caliverse.admin.scheduler.batch.service.LogCompressService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; diff --git a/src/main/java/com/caliverse/admin/scheduler/Scheduler.java b/src/main/java/com/caliverse/admin/scheduler/Scheduler.java index e742460..840fa82 100644 --- a/src/main/java/com/caliverse/admin/scheduler/Scheduler.java +++ b/src/main/java/com/caliverse/admin/scheduler/Scheduler.java @@ -1,10 +1,8 @@ package com.caliverse.admin.scheduler; -import com.caliverse.admin.scheduler.config.ScheduleExecutionConfig; +import com.caliverse.admin.scheduler.entity.SchedulerType; public interface Scheduler { void execute(); - boolean isRepeatable(); - ScheduleType getScheduleType(); - ScheduleExecutionConfig getSchedulerConfig(); + SchedulerType getSchedulerType(); } diff --git a/src/main/java/com/caliverse/admin/scheduler/SchedulerManager.java b/src/main/java/com/caliverse/admin/scheduler/SchedulerManager.java index 310b7d7..c412351 100644 --- a/src/main/java/com/caliverse/admin/scheduler/SchedulerManager.java +++ b/src/main/java/com/caliverse/admin/scheduler/SchedulerManager.java @@ -1,433 +1,56 @@ package com.caliverse.admin.scheduler; -import com.caliverse.admin.scheduler.config.MissedExecutionConfig; -import com.caliverse.admin.scheduler.config.ScheduleExecutionConfig; -import com.caliverse.admin.scheduler.service.NoticeScheduler; -import jakarta.annotation.PreDestroy; -import lombok.*; +import com.caliverse.admin.scheduler.entity.SchedulerType; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.LocalTime; +import java.util.List; import java.util.Map; import java.util.concurrent.*; +import java.util.stream.Collectors; @Service @Slf4j -@RequiredArgsConstructor public class SchedulerManager { - private final ScheduledExecutorService scheduler; - - // 실행 중인 작업 추적을 위한 Map - private final Map scheduledTasks = new ConcurrentHashMap<>(); - // 재시도 설정 private static final int MAX_RETRY_COUNT = 3; private static final long RETRY_DELAY_MS = 1000; - @Data - @Builder - //스케줄 프로세스 관리 - private static class ScheduledTaskInfo { - private final Scheduler task; - private final ScheduledFuture future; - private final LocalDateTime startTime; - private int retryCount; - private ScheduleStatus status; + // 실행 중인 작업 추적을 위한 Map + private final Map schedulers = new ConcurrentHashMap<>(); - public static ScheduledTaskInfo of(Scheduler task, ScheduledFuture future) { - return ScheduledTaskInfo.builder() - .task(task) - .future(future) - .startTime(LocalDateTime.now()) - .retryCount(0) - .status(ScheduleStatus.SCHEDULED) - .build(); - } - } - - @Getter - @AllArgsConstructor - public enum ScheduleStatus { - SCHEDULED("예약됨"), - RUNNING("실행 중"), - COMPLETED("완료됨"), - FAILED("실패"), - CANCELLED("취소됨"); - - private final String description; - } - - //스케줄 실행 - public void scheduleTask(Scheduler task) { - String taskId = task.getSchedulerConfig().getTaskId(); - - // 이미 존재하는 작업 체크 - if (scheduledTasks.containsKey(taskId)) { - ScheduledTaskInfo existingTask = scheduledTasks.get(taskId); - if (shouldReplaceExisting(existingTask)) { - log.info("Replacing existing task: {}", taskId); - cancelTask(taskId); - } else { - log.warn("Task {} is already scheduled and running", taskId); - return; - } - } - - try { - //타입별 스케줄러 등록 - ScheduledFuture future = scheduleTaskByType(task); - if (future != null) { - ScheduledTaskInfo taskInfo = ScheduledTaskInfo.of(task, future); - scheduledTasks.put(taskId, taskInfo); - log.info("Successfully scheduled task: {}", taskId); - } - } catch (Exception e) { - log.error("Failed to schedule task: {}", taskId, e); - throw new SchedulerException("Failed to schedule task: " + taskId, e); - } - } - - //스케줄 상태 체크 - private boolean shouldReplaceExisting(ScheduledTaskInfo taskInfo) { - return taskInfo.getStatus() == ScheduleStatus.FAILED || - taskInfo.getStatus() == ScheduleStatus.COMPLETED || - taskInfo.getFuture().isDone(); - } - - //스케줄 타입 별 처리 - private ScheduledFuture scheduleTaskByType(Scheduler task) { - return switch (task.getScheduleType()) { - case IMMEDIATE -> scheduleImmediate(task); - case DELAYED -> scheduleDelayed(task); - case RECURRING -> scheduleRecurring(task); - case PERIODIC -> schedulePeriodic(task); - }; - } - - //즉시 실행 - private ScheduledFuture scheduleImmediate(Scheduler task) { - return (ScheduledFuture) scheduler.submit(() -> executeTaskWithRetry(task)); - } - - //지연 실행 - private ScheduledFuture scheduleDelayed(Scheduler task) { - ScheduleExecutionConfig config = task.getSchedulerConfig(); - long delay = calculateDelay(config.getStartTime()); - - if (delay < 0) { - log.error("Task {} scheduled for past time", config.getTaskId()); - return null; - } - - return scheduler.schedule( - () -> executeTaskWithRetry(task), - delay, - TimeUnit.MILLISECONDS - ); - } - - //반복 실행 - private ScheduledFuture scheduleRecurring(Scheduler task) { - ScheduleExecutionConfig config = task.getSchedulerConfig(); - long initialDelay = calculateDelay(config.getStartTime()); - - if (initialDelay < 0) { - Duration timeSinceStart = Duration.between(config.getStartTime(), LocalDateTime.now()); - - // 종료 시간 체크 - if (config.getEndTime() != null && LocalDateTime.now().isAfter(config.getEndTime())) { - log.warn("Task {} scheduled end time has passed", config.getTaskId()); - return null; - } - - // 다음 실행 시간 계산 - long interval = config.getInterval().toMillis(); - long missedExecutions = timeSinceStart.toMillis() / interval; - initialDelay = interval - (timeSinceStart.toMillis() % interval); - - log.info("Task {} was scheduled to start {} ago. Missed {} executions. " + - "Next execution in {} ms", - config.getTaskId(), - timeSinceStart, - missedExecutions, - initialDelay); - - if (shouldProcessMissedExecutions(task)) { - processMissedExecutions(task, (int) missedExecutions); - } - } - - return scheduler.scheduleAtFixedRate( - () -> { - String taskId = config.getTaskId(); - ScheduledTaskInfo taskInfo = scheduledTasks.get(taskId); - - try { - // NoticeSchedule 경우 추가 검증 - if (task instanceof NoticeScheduler noticeTask) { - if (noticeTask.hasReachedMaxExecutions()) { - cancelTask(taskId); - log.info("Cancelling notice task - reached max executions. TaskId: {}", taskId); - return; - } - - if (!noticeTask.isValidExecutionCount()) { - log.error("Invalid execution count detected. TaskId: {}", taskId); - cancelTask(taskId); - return; - } - } - - if (shouldStopRecurring(task)) { - cancelTask(taskId); - return; - } - - taskInfo.setStatus(ScheduleStatus.RUNNING); - task.execute(); - taskInfo.setStatus(ScheduleStatus.SCHEDULED); - - } catch (Exception e) { - handleTaskExecutionFailure(task, taskInfo, e); - } - }, - initialDelay, - config.getInterval().toMillis(), - TimeUnit.MILLISECONDS - ); - } - - //주기적 실행 - private ScheduledFuture schedulePeriodic(Scheduler task){ - ScheduleExecutionConfig config = task.getSchedulerConfig(); - LocalTime executionTime = config.getDailyExecutionTime(); - - if (executionTime == null) { - log.error("Daily execution time is not set for task: {}", config.getTaskId()); - return null; - } - - // 현재 시간 - LocalDateTime now = LocalDateTime.now(); - - // 시작일이 미래인 경우, 시작일의 지정 시간을 첫 실행 시간으로 설정 - // 시작일이 과거인 경우, 오늘 또는 다음 날의 지정 시간을 첫 실행 시간으로 설정 - LocalDateTime firstExecution = calculateFirstExecution(now, config.getStartTime(), executionTime); - - // 종료 시간 확인 - if (config.getEndTime() != null && firstExecution.isAfter(config.getEndTime())) { - log.warn("Task {} end time has already passed", config.getTaskId()); - return null; - } - - // 첫 실행까지의 지연 시간 계산 - long initialDelay = Duration.between(now, firstExecution).toMillis(); - - // 24시간을 밀리초로 변환 - long dailyInterval = Duration.ofDays(1).toMillis(); - - return scheduler.scheduleAtFixedRate( - () -> executeDaily(task), - initialDelay, - dailyInterval, - TimeUnit.MILLISECONDS - ); - } - - private LocalDateTime calculateFirstExecution( - LocalDateTime now, - LocalDateTime startTime, - LocalTime executionTime - ) { - LocalDateTime candidateTime = now.with(executionTime); - - // 시작 시간이 미래인 경우 - if (startTime.isAfter(now)) { - candidateTime = startTime.with(executionTime); - } - - // 만약 오늘의 실행 시간이 이미 지났다면 다음 날로 설정 - if (candidateTime.isBefore(now)) { - candidateTime = candidateTime.plusDays(1); - } - - return candidateTime; - } - - private void executeDaily(Scheduler task) { - String taskId = task.getSchedulerConfig().getTaskId(); - ScheduledTaskInfo taskInfo = scheduledTasks.get(taskId); - - try { - // 현재 시간이 종료 시간을 지났는지 확인 - if (shouldStopDaily(task)) { - cancelTask(taskId); - return; - } - - // 지정된 시간에만 실행 - LocalTime currentTime = LocalTime.now(); - LocalTime executionTime = task.getSchedulerConfig().getDailyExecutionTime(); - - if (currentTime.getHour() == executionTime.getHour() && - currentTime.getMinute() == executionTime.getMinute()) { - - taskInfo.setStatus(ScheduleStatus.RUNNING); - task.execute(); - taskInfo.setStatus(ScheduleStatus.SCHEDULED); - - log.info("Daily task {} executed at scheduled time: {}", - taskId, executionTime); - } - - } catch (Exception e) { - handleTaskExecutionFailure(task, taskInfo, e); - } - } - - //종료일자 체크 - private boolean shouldStopDaily(Scheduler task) { - ScheduleExecutionConfig config = task.getSchedulerConfig(); - if (config.getEndTime() == null) { - return false; - } - return LocalDateTime.now().isAfter(config.getEndTime()); - } - - private boolean shouldProcessMissedExecutions(Scheduler task) { - // 작업 유형에 따라 누락된 실행 처리 여부 결정 - return task.getSchedulerConfig().isProcessMissedExecutions(); - } - - private void processMissedExecutions(Scheduler task, int missedCount) { - // 누락된 실행 처리를 위한 설정 가져오기 - MissedExecutionConfig missedConfig = task.getSchedulerConfig().getMissedExecutionConfig(); - if (missedConfig == null) { - return; - } - - int executionsToProcess = Math.min( - missedCount, - missedConfig.getMaxMissedExecutionsToProcess() + public SchedulerManager(List schedulerList) { + schedulerList.forEach(scheduler -> + schedulers.put(scheduler.getSchedulerType(), scheduler) ); - if (executionsToProcess <= 0) { - return; - } - - CompletableFuture.runAsync(() -> { - try { - log.info("Processing {} missed executions for task {}", executionsToProcess, task.getSchedulerConfig().getTaskId()); - - for (int i = 0; i < executionsToProcess; i++) { - if (missedConfig.isSequentialProcessing()) { - task.execute(); - } else { - // 마지막 실행만 처리 - if (i == executionsToProcess - 1) { - task.execute(); - } - } - } - } catch (Exception e) { - log.error("Error processing missed executions for task {}", - task.getSchedulerConfig().getTaskId(), e); - } - }, scheduler); + log.info("Initialized {} schedulers: {}", + schedulerList.size(), + schedulerList.stream() + .map(Scheduler::getSchedulerType) + .collect(Collectors.toList())); } - private void executeTaskWithRetry(Scheduler task) { - String taskId = task.getSchedulerConfig().getTaskId(); - ScheduledTaskInfo taskInfo = scheduledTasks.get(taskId); - - try { - taskInfo.setStatus(ScheduleStatus.RUNNING); - task.execute(); - taskInfo.setStatus(ScheduleStatus.COMPLETED); - log.info("Task {} completed successfully", taskId); - - } catch (Exception e) { - handleTaskExecutionFailure(task, taskInfo, e); - } - } - - private void handleTaskExecutionFailure(Scheduler task, ScheduledTaskInfo taskInfo, Exception e) { - String taskId = task.getSchedulerConfig().getTaskId(); - taskInfo.setRetryCount(taskInfo.getRetryCount() + 1); - - if (taskInfo.getRetryCount() < MAX_RETRY_COUNT) { - log.warn("Task {} failed, attempting retry {}/{}", - taskId, taskInfo.getRetryCount(), MAX_RETRY_COUNT, e); - - scheduler.schedule( - () -> executeTaskWithRetry(task), - RETRY_DELAY_MS, - TimeUnit.MILLISECONDS - ); + public void executeScheduler(SchedulerType type) { + Scheduler scheduler = schedulers.get(type); + if (scheduler != null) { + scheduler.execute(); } else { - log.error("Task {} failed after {} retries", taskId, MAX_RETRY_COUNT, e); - taskInfo.setStatus(ScheduleStatus.FAILED); - cancelTask(taskId); + log.warn("No scheduler found for type: {}", type); } } - private boolean shouldStopRecurring(Scheduler task) { - ScheduleExecutionConfig config = task.getSchedulerConfig(); - - // 종료 시간 체크 - if (config.getEndTime() != null && LocalDateTime.now().isAfter(config.getEndTime())) { - return true; - } - - // 반복 횟수 체크 - if (config.getRepeatCount() != null) { - String taskId = config.getTaskId(); - ScheduledTaskInfo taskInfo = scheduledTasks.get(taskId); - return taskInfo.getRetryCount() >= config.getRepeatCount(); - } - - return false; + public void executeAllSchedulers() { + schedulers.values().forEach(Scheduler::execute); } - public void cancelTask(String taskId) { - ScheduledTaskInfo taskInfo = scheduledTasks.get(taskId); - if (taskInfo != null) { - taskInfo.getFuture().cancel(false); - taskInfo.setStatus(ScheduleStatus.CANCELLED); - scheduledTasks.remove(taskId); - log.info("Task {} cancelled and removed from scheduler", taskId); - } + public void addScheduler(Scheduler scheduler) { + schedulers.put(scheduler.getSchedulerType(), scheduler); + log.info("Added scheduler: {}", scheduler.getSchedulerType()); } - public void cancelAllTasks() { - scheduledTasks.keySet().forEach(this::cancelTask); - } - - private long calculateDelay(LocalDateTime startTime) { - return Duration.between(LocalDateTime.now(), startTime).toMillis(); - } - - @PreDestroy - public void shutdown() { - cancelAllTasks(); - scheduler.shutdown(); - try { - if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) { - scheduler.shutdownNow(); - } - } catch (InterruptedException e) { - scheduler.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - - // 스케줄러 관련 예외 클래스 - public static class SchedulerException extends RuntimeException { - public SchedulerException(String message, Throwable cause) { - super(message, cause); - } + public void removeScheduler(SchedulerType type) { + schedulers.remove(type); + log.info("Removed scheduler: {}", type); } } diff --git a/src/main/java/com/caliverse/admin/scheduler/SchedulerService.java b/src/main/java/com/caliverse/admin/scheduler/SchedulerService.java deleted file mode 100644 index b688e1e..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/SchedulerService.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.caliverse.admin.scheduler; - -import com.caliverse.admin.domain.entity.InGame; -import com.caliverse.admin.domain.entity.Mail; -import org.springframework.stereotype.Service; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ScheduledFuture; - -@Service -public class SchedulerService { - - private final Map> scheduledTasks = new ConcurrentHashMap<>(); - - private final Map mailTask = new ConcurrentHashMap<>(); - private final Map noticeTask = new ConcurrentHashMap<>(); - - public boolean isTaskExist(String key){ - return scheduledTasks.containsKey(key); - } - - public void addTask(String key, ScheduledFuture schdule){ - scheduledTasks.put(key, schdule); - } - - public void closeTask(String key) { - ScheduledFuture scheduledFuture = scheduledTasks.get(key); - if (scheduledFuture != null) { - scheduledFuture.cancel(true); - scheduledTasks.remove(key); - } - } - -// public boolean isTaskExist(String type, Long id) { -// switch (type) { -// case "mail" -> { -// return mailTask.containsKey(id); -// } -// case "notice" -> { -// return noticeTask.containsKey(id); -// } -// default -> { -// return false; -// } -// } -// } -// -// public void createTask(Mail mail) { -// mailTask.put(mail.getId(), mail); -// } - -} diff --git a/src/main/java/com/caliverse/admin/scheduler/batch/ScheduleRunnerBatch.java b/src/main/java/com/caliverse/admin/scheduler/batch/ScheduleRunnerBatch.java new file mode 100644 index 0000000..fcb8689 --- /dev/null +++ b/src/main/java/com/caliverse/admin/scheduler/batch/ScheduleRunnerBatch.java @@ -0,0 +1,31 @@ +package com.caliverse.admin.scheduler.batch; + +import com.caliverse.admin.domain.RabbitMq.MessageHandlerService; +import com.caliverse.admin.domain.service.BlackListService; +import com.caliverse.admin.domain.service.EventService; +import com.caliverse.admin.domain.service.MailService; +import com.caliverse.admin.domain.service.NoticeService; +import com.caliverse.admin.global.common.utils.ExcelUtils; +import com.caliverse.admin.logs.logservice.indicators.*; +import com.caliverse.admin.redis.service.RedisUserInfoService; +import com.caliverse.admin.scheduler.DynamicScheduler; +import com.caliverse.admin.scheduler.SchedulerManager; +import com.caliverse.admin.scheduler.entity.SchedulerType; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +@EnableScheduling +@RequiredArgsConstructor +public class ScheduleRunnerBatch { + + private final SchedulerManager schedulerManager; + + + +} diff --git a/src/main/java/com/caliverse/admin/scheduler/service/LogCompressService.java b/src/main/java/com/caliverse/admin/scheduler/batch/service/LogCompressService.java similarity index 58% rename from src/main/java/com/caliverse/admin/scheduler/service/LogCompressService.java rename to src/main/java/com/caliverse/admin/scheduler/batch/service/LogCompressService.java index cbfc3f9..a35dd95 100644 --- a/src/main/java/com/caliverse/admin/scheduler/service/LogCompressService.java +++ b/src/main/java/com/caliverse/admin/scheduler/batch/service/LogCompressService.java @@ -1,4 +1,4 @@ -package com.caliverse.admin.scheduler.service; +package com.caliverse.admin.scheduler.batch.service; public interface LogCompressService { void compressLastMonthLogs(); diff --git a/src/main/java/com/caliverse/admin/scheduler/service/impl/LogCompressServiceImpl.java b/src/main/java/com/caliverse/admin/scheduler/batch/service/impl/LogCompressServiceImpl.java similarity index 95% rename from src/main/java/com/caliverse/admin/scheduler/service/impl/LogCompressServiceImpl.java rename to src/main/java/com/caliverse/admin/scheduler/batch/service/impl/LogCompressServiceImpl.java index 1779acf..ef65961 100644 --- a/src/main/java/com/caliverse/admin/scheduler/service/impl/LogCompressServiceImpl.java +++ b/src/main/java/com/caliverse/admin/scheduler/batch/service/impl/LogCompressServiceImpl.java @@ -1,6 +1,6 @@ -package com.caliverse.admin.scheduler.service.impl; +package com.caliverse.admin.scheduler.batch.service.impl; -import com.caliverse.admin.scheduler.service.LogCompressService; +import com.caliverse.admin.scheduler.batch.service.LogCompressService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/caliverse/admin/scheduler/config/MissedExecutionConfig.java b/src/main/java/com/caliverse/admin/scheduler/config/MissedExecutionConfig.java deleted file mode 100644 index 5d35f95..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/config/MissedExecutionConfig.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.caliverse.admin.scheduler.config; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class MissedExecutionConfig { - @Builder.Default - private int maxMissedExecutionsToProcess = 1; // 기본값으로 최근 1회만 처리 - - @Builder.Default - private boolean sequentialProcessing = false; // 기본값으로 순차 처리하지 않음 -} \ No newline at end of file diff --git a/src/main/java/com/caliverse/admin/scheduler/config/ScheduleExecutionConfig.java b/src/main/java/com/caliverse/admin/scheduler/config/ScheduleExecutionConfig.java deleted file mode 100644 index b59d998..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/config/ScheduleExecutionConfig.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.caliverse.admin.scheduler.config; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.LocalTime; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ScheduleExecutionConfig { - private String taskId; - private LocalDateTime startTime; - private LocalDateTime endTime; - private Duration interval; - private Integer repeatCount; - private String cronExpression; - private LocalTime dailyExecutionTime; - - @Builder.Default - private boolean processMissedExecutions = false; - - private MissedExecutionConfig missedExecutionConfig; -} diff --git a/src/main/java/com/caliverse/admin/scheduler/config/ScheduleSystemConfig.java b/src/main/java/com/caliverse/admin/scheduler/config/ScheduleSystemConfig.java deleted file mode 100644 index 7f48317..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/config/ScheduleSystemConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.caliverse.admin.scheduler.config; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - -@Configuration -@Slf4j -public class ScheduleSystemConfig { - @Bean - public ScheduledExecutorService scheduledExecutorService() { - return Executors.newScheduledThreadPool( - Runtime.getRuntime().availableProcessors(), - r -> { - Thread thread = new Thread(r, "scheduler-"); - thread.setDaemon(true); - return thread; - } - ); - } -} diff --git a/src/main/java/com/caliverse/admin/scheduler/ScheduleType.java b/src/main/java/com/caliverse/admin/scheduler/entity/ScheduleType.java similarity index 77% rename from src/main/java/com/caliverse/admin/scheduler/ScheduleType.java rename to src/main/java/com/caliverse/admin/scheduler/entity/ScheduleType.java index de3dbed..84c974a 100644 --- a/src/main/java/com/caliverse/admin/scheduler/ScheduleType.java +++ b/src/main/java/com/caliverse/admin/scheduler/entity/ScheduleType.java @@ -1,4 +1,4 @@ -package com.caliverse.admin.scheduler; +package com.caliverse.admin.scheduler.entity; public enum ScheduleType { IMMEDIATE, //즉시 실행 diff --git a/src/main/java/com/caliverse/admin/scheduler/entity/SchedulerType.java b/src/main/java/com/caliverse/admin/scheduler/entity/SchedulerType.java new file mode 100644 index 0000000..e23b354 --- /dev/null +++ b/src/main/java/com/caliverse/admin/scheduler/entity/SchedulerType.java @@ -0,0 +1,12 @@ +package com.caliverse.admin.scheduler.entity; + +public enum SchedulerType { + MAIL, + NOTICE, + BLACKLIST, + EVENT, + LAND_AUCTION, + BATTLE_EVENT, + WEB3, + LAND_OWNER_CHANGES +} diff --git a/src/main/java/com/caliverse/admin/scheduler/polling/ScheduleRunnerPolling.java b/src/main/java/com/caliverse/admin/scheduler/polling/ScheduleRunnerPolling.java new file mode 100644 index 0000000..d1df3b7 --- /dev/null +++ b/src/main/java/com/caliverse/admin/scheduler/polling/ScheduleRunnerPolling.java @@ -0,0 +1,182 @@ +package com.caliverse.admin.scheduler.polling; + +import com.caliverse.admin.scheduler.SchedulerManager; +import com.caliverse.admin.scheduler.entity.SchedulerType; +import com.caliverse.admin.domain.RabbitMq.MessageHandlerService; +import com.caliverse.admin.domain.service.*; +import com.caliverse.admin.global.common.utils.ExcelUtils; +import com.caliverse.admin.logs.logservice.indicators.*; +import com.caliverse.admin.redis.service.RedisUserInfoService; +import com.caliverse.admin.scheduler.DynamicScheduler; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.batch.core.JobParameters; +// import org.springframework.batch.core.JobParametersBuilder; +// import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + + +import lombok.extern.slf4j.Slf4j; + +@Component +@Slf4j +@EnableScheduling +@RequiredArgsConstructor +public class ScheduleRunnerPolling { + @Autowired private IndicatorsAuService auService; + @Autowired private IndicatorsDauService dauService; + @Autowired private IndicatorsWauService wauService; + @Autowired private IndicatorsMauService mauService; + @Autowired private IndicatorsMcuService mcuService; + @Autowired private IndicatorsNruService statNruService; + + @Autowired private RedisUserInfoService userInfoService; + @Autowired private DynamicScheduler dynamicScheduler; + @Autowired private MailService mailService; + @Autowired private NoticeService noticeService; + @Autowired private BlackListService blackListService; + @Autowired private EventService eventService; + @Autowired + private RedisUserInfoService redisUserInfoService; + @Autowired + private MessageHandlerService messageHandlerService; + @Autowired + private ExcelUtils excelUtils; + + private final SchedulerManager schedulerManager; + + @Scheduled(cron = "7 * * * * *") + public void landOwnerChangesJob(){ + schedulerManager.executeScheduler(SchedulerType.LAND_OWNER_CHANGES); + } + + /* + 매일 UTC 기준 00시 50분 00초에 실행, (한국 시간 9시 50분) 30분에 돌릴경우 데이터가 다 넘어 오지 않는 경우 있어서 수정처리 + 이게 가장 먼저 실행 되어야 한다. + 로그가 많을 경우 성능 이슈 있을 수 있음 + */ +// @Scheduled(cron = "* * * * * *") +// public void auScheduler() { +// //이걸 나중에 어떻게 활용할지 생각해보자. +// log.info("run auScheduler"); +// StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); +// auService.collectActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); +// log.info("end auScheduler"); +// } + +//// @Scheduled(cron = "00 55 0 * * *") // 매일 UTC 기준 00시 56분 00초에 실행 +// @Scheduled(cron = "1 * * * * *") // 매일 UTC 기준 00시 56분 00초에 실행 +// public void dauScheduler() { +// log.info("run dauScheduler"); +// StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); +// dauService.collectDailyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); +// log.info("end dauScheduler"); +// } +// +// @Scheduled(cron = "00 56 0 * * *") // 매일 UTC 기준 00시 56분 00초에 실행 +// public void wauScheduler() { +// log.info("run wauScheduler"); +// StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_WEEK_NUM); +// wauService.collectWeeklyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); +// log.info("end wauScheduler"); +// } +// +// @Scheduled(cron = "00 57 0 * * *") // 매일 UTC 기준 00시 57분 00초에 실행 +// public void mauScheduler() { +// log.info("run mauScheduler"); +// StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_MONTH_NUM); +// mauService.collectMonthlyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime()); +// log.info("end mauScheduler"); +// } +// +// @Scheduled(cron = "00 58 0 * * *") // 매일 UTC 기준 00시 58분 00초에 실행 +// public void mcuScheduler() { +// log.info("run mcuScheduler"); +// StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); +// mcuService.collectMaxCountUser(startEndTime.getStartTime(), startEndTime.getEndTime()); +// log.info("end mcuScheduler"); +// } +// +// @Scheduled(cron = "00 59 0 * * *") // 매일 UTC 기준 00시 59분 00초에 실행 +// public void nruScheduler() { +// log.info("run mcuScheduler"); +// //StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM); +// //statNruService.collectStatLogs(startEndTime.getStartTime(), startEndTime.getEndTime()); +// log.info("end mcuScheduler"); +// } + +// @Scheduled(cron = "1 * * * * *") +// public void noticeJob(){ +// log.info("run noticeJob"); +// List noticeList = noticeService.getScheduleNoticeList(); +// noticeList.forEach(notice -> { +// if (notice.getIsRepeat() && +// notice.getRepeatType() == InGame.REPEATTYPE.COUNT && +// notice.getSendCnt() >= notice.getRepeatCnt()) { +// log.info("Skipping notice - already reached max count. NoticeId: {}", notice.getId()); +// noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FINISH); +// return; +// } +// +// NoticeScheduler task = NoticeScheduler.builder() +// .notice(notice) +// .noticeService(noticeService) +// .redisUserInfoService(redisUserInfoService) +// .messageHandlerService(messageHandlerService) +// .build(); +// schedulerManager.scheduleTask(task); +// }); +// log.info("end noticeJob"); +// } +// +// @Scheduled(cron = "2 * * * * *") +// public void mailJob(){ +// log.info("run mailJob"); +// List mailList = mailService.getScheduleMailList(); +// mailList.stream() +// .filter(mail -> mail.getSendStatus().equals(Mail.SENDSTATUS.WAIT)) +// .forEach(mail -> { +// MailScheduler task = MailScheduler.builder() +// .mail(mail) +// .mailService(mailService) +// .redisUserInfoService(redisUserInfoService) +// .messageHandlerService(messageHandlerService) +// .excelUtils(excelUtils) +// .build(); +// schedulerManager.scheduleTask(task); +// }); +// log.info("end mailJob"); +// } +// +// @Scheduled(cron = "3 * * * * *") +// public void blackListJob(){ +// log.info("run blackListJob"); +// List blackList = blackListService.getScheduleBlackList(); +// blackList.forEach(blockUser -> { +// BlackListScheduler task = BlackListScheduler.builder() +// .blackList(blockUser) +// .blackListService(blackListService) +// .build(); +// schedulerManager.scheduleTask(task); +// }); +// log.info("end blackListJob"); +// } +// +// @Scheduled(cron = "4 * * * * *") +// public void eventJob(){ +// log.info("run eventJob"); +// List eventList = eventService.getScheduleMailList(); +// eventList.forEach(event -> { +// EventScheduler task = EventScheduler.builder() +// .event(event) +// .eventService(eventService) +// .redisUserInfoService(redisUserInfoService) +// .messageHandlerService(messageHandlerService) +// .build(); +// schedulerManager.scheduleTask(task); +// }); +// log.info("end eventJob"); +// } +} diff --git a/src/main/java/com/caliverse/admin/scheduler/polling/service/LandOwnerChangesScheduler.java b/src/main/java/com/caliverse/admin/scheduler/polling/service/LandOwnerChangesScheduler.java new file mode 100644 index 0000000..035b669 --- /dev/null +++ b/src/main/java/com/caliverse/admin/scheduler/polling/service/LandOwnerChangesScheduler.java @@ -0,0 +1,64 @@ +package com.caliverse.admin.scheduler.polling.service; + +import com.caliverse.admin.scheduler.CommonScheduler; +import com.caliverse.admin.scheduler.entity.SchedulerType; +import com.caliverse.admin.domain.entity.LandOwnerChange; +import com.caliverse.admin.domain.request.LandRequest; +import com.caliverse.admin.domain.service.LandService; +import com.caliverse.admin.dynamodb.service.DynamodbLandService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +@Component +public class LandOwnerChangesScheduler extends CommonScheduler { + + private final LandService landService; + private final DynamodbLandService dynamodbLandService; + + public LandOwnerChangesScheduler(LandService landService, DynamodbLandService dynamodbLandService) { + this.landService = landService; + this.dynamodbLandService = dynamodbLandService; + } + + @Override + protected void executeInternal() { + List scheduleList = landService.getScheduleLandOwnerChangesList(); + + scheduleList.forEach(landOwnerChange -> { + LandOwnerChange.CHANGE_STATUS status = landOwnerChange.getStatus(); + LocalDateTime reserve_dt = landOwnerChange.getReservationDt(); + int landId = landOwnerChange.getLandId(); + String guid = landOwnerChange.getUserGuid(); + + LocalDateTime now = LocalDateTime.now(); + + if(status.equals(LandOwnerChange.CHANGE_STATUS.WAIT) && reserve_dt.isBefore(now)) { + LandRequest landRequest = LandRequest.builder() + .landId(landId) + .landName(landOwnerChange.getLandName()) + .buildingId(landOwnerChange.getBuildingId()) + .buildingName(landOwnerChange.getBuildingName()) + .userGuid(guid) + .userName(landOwnerChange.getUserName()) + .build(); + dynamodbLandService.ChangesLandOwner(landRequest); + + Map map = new HashMap<>(); + map.put("id", landOwnerChange.getId()); + map.put("status", LandOwnerChange.CHANGE_STATUS.FINISH); + landService.updateLandOwnedChangeStatus(map); + } + }); + } + + @Override + public SchedulerType getSchedulerType() { + return SchedulerType.LAND_OWNER_CHANGES; + } +} diff --git a/src/main/java/com/caliverse/admin/scheduler/service/BlackListScheduler.java b/src/main/java/com/caliverse/admin/scheduler/service/BlackListScheduler.java deleted file mode 100644 index 651ea38..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/service/BlackListScheduler.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.caliverse.admin.scheduler.service; - -import com.caliverse.admin.domain.entity.BlackList; -import com.caliverse.admin.domain.service.BlackListService; -import com.caliverse.admin.domain.service.UserGameSessionService; -import com.caliverse.admin.scheduler.ScheduleType; -import com.caliverse.admin.scheduler.Scheduler; -import com.caliverse.admin.scheduler.config.ScheduleExecutionConfig; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import java.time.LocalDateTime; - -@Slf4j -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class BlackListScheduler implements Scheduler { - private BlackList blackList; - private BlackListService blackListService; - private UserGameSessionService userGameSessionService; - - @Override - public void execute() { - try { - processBlackList(); - } catch (Exception e) { - log.error("BlackList execution failed for ID: {}", blackList.getId(), e); - blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.FAIL); - } - } - - @Override - public boolean isRepeatable() { - return false; - } - - @Override - public ScheduleType getScheduleType() { - return ScheduleType.DELAYED; - } - - @Override - public ScheduleExecutionConfig getSchedulerConfig() { - return ScheduleExecutionConfig.builder() - .taskId("blacklist-" + blackList.getId()) - .startTime(blackList.getStartDt()) - .endTime(blackList.getEndDt()) - .build(); - } - - private void processBlackList() { - LocalDateTime nowDate = LocalDateTime.now(); - LocalDateTime startTime = blackList.getStartDt(); - LocalDateTime endTime = blackList.getEndDt(); - - // 이미 지난시간이면 fail 처리 - if(nowDate.isAfter(endTime) && blackList.getStatus().equals(BlackList.STATUSTYPE.WAIT)) { - blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.FAIL); - log.error("blackListJob blackListSchedule timeOut : {}", blackList); - return; - } - - // 시작시간 지났으면 정지 처리 - if(!nowDate.isBefore(startTime) && blackList.getStatus().equals(BlackList.STATUSTYPE.WAIT)) { - // user kick 처리 - userGameSessionService.kickUserSession(blackList.getGuid()); - blackListService.updateScheduleBlockUser(blackList, BlackList.STATUSTYPE.INPROGRESS); - blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.INPROGRESS); - log.info("blackListJob blackListSchedule block start : {}", blackList); - } - - // 종료시간 지났으면 만료 처리 - if(!nowDate.isBefore(endTime) && blackList.getStatus().equals(BlackList.STATUSTYPE.INPROGRESS)) { - blackListService.updateScheduleBlockUser(blackList, BlackList.STATUSTYPE.EXPIRATION); - blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.EXPIRATION); - log.info("blackListJob blackListSchedule block end : {}", blackList); - } - } -} diff --git a/src/main/java/com/caliverse/admin/scheduler/service/EventScheduler.java b/src/main/java/com/caliverse/admin/scheduler/service/EventScheduler.java deleted file mode 100644 index c5d62a1..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/service/EventScheduler.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.caliverse.admin.scheduler.service; - -import com.caliverse.admin.domain.RabbitMq.MessageHandlerService; -import com.caliverse.admin.domain.RabbitMq.message.LanguageType; -import com.caliverse.admin.domain.RabbitMq.message.MailItem; -import com.caliverse.admin.domain.entity.*; -import com.caliverse.admin.domain.service.EventService; -import com.caliverse.admin.domain.service.HistoryService; -import com.caliverse.admin.dynamodb.entity.SystemMessage; -import com.caliverse.admin.redis.service.RedisUserInfoService; -import com.caliverse.admin.global.common.utils.CommonUtils; -import com.caliverse.admin.global.common.utils.JsonUtils; -import com.caliverse.admin.scheduler.config.ScheduleExecutionConfig; -import com.caliverse.admin.scheduler.ScheduleType; -import com.caliverse.admin.scheduler.Scheduler; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import lombok.*; -import lombok.extern.slf4j.Slf4j; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -@Slf4j -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class EventScheduler implements Scheduler { - private Event event; - private EventService eventService; - private RedisUserInfoService redisUserInfoService; - private MessageHandlerService messageHandlerService; - private HistoryService historyService; - - @Override - public void execute() { - try { - processEvent(); - } catch (Exception e) { - log.error("Event execution failed for event ID: {}", event.getId(), e); - eventService.updateEventStatus(event.getId(), Event.EVENTSTATUS.FAIL); - historyService.setScheduleLog(HISTORYTYPE.SCHEDULE_EVENT_FAIL, e.getMessage()); - } - } - - @Override - public boolean isRepeatable() { - return false; - } - - @Override - public ScheduleType getScheduleType() { - return ScheduleType.DELAYED; - } - - @Override - public ScheduleExecutionConfig getSchedulerConfig() { - return ScheduleExecutionConfig.builder() - .taskId("event-" + event.getId()) - .startTime(event.getStartDt()) - .endTime(event.getEndDt()) - .build(); - } - - private void processEvent() { - LocalDateTime nowDate = LocalDateTime.now(); - LocalDateTime startTime = event.getStartDt(); - LocalDateTime endTime = event.getEndDt(); - - // 이벤트가 이미 종료되었는지 체크 - if (nowDate.isAfter(endTime) && event.getStatus().equals(Event.EVENTSTATUS.WAIT)) { - eventService.updateEventStatus(event.getId(), Event.EVENTSTATUS.FAIL); - log.error("eventJob eventSchedule timeOut : {}", event); - return; - } - - // 시작 30분 전에 게임 DB에 insert - if (event.getStatus().equals(Event.EVENTSTATUS.WAIT) - && Duration.between(nowDate, startTime).abs().toMinutes() <= 30 - && !event.isAddFlag()) { - - systemMailInsert(); - eventService.updateEventStatus(event.getId(), Event.EVENTSTATUS.RUNNING); - log.info("eventJob eventSchedule dynamoDB Insert & Start: {}", event); - } - - // 종료 시간이 되면 이벤트 종료 - if (!nowDate.isBefore(endTime) && event.getStatus().equals(Event.EVENTSTATUS.RUNNING)) { - eventService.updateEventStatus(event.getId(), Event.EVENTSTATUS.FINISH); - log.info("eventJob eventSchedule block end : {}", event); - } - } - - private void systemMailInsert() { - try { - log.info("systemMailInsert Info: {}", event); - - // 메시지 처리 - List mailTitleMessages = new ArrayList<>(); - List mailTextMessages = new ArrayList<>(); - List mailSenderMessages = new ArrayList<>(); - List mailItems = new ArrayList<>(); - - processMessages(mailTitleMessages, mailTextMessages, mailSenderMessages); - processItems(mailItems); - - // JSON 변환 - ObjectMapper objectMapper = new ObjectMapper(); - ArrayNode mailTitleArray = convertToJsonArray(objectMapper, mailTitleMessages); - ArrayNode mailTextArray = convertToJsonArray(objectMapper, mailTextMessages); - ArrayNode mailSenderArray = convertToJsonArray(objectMapper, mailSenderMessages); - ArrayNode mailItemArray = convertToJsonArray(objectMapper, mailItems); - - // 시스템 메일 등록 - eventService.insertSystemMail( - event, - mailTitleArray, - mailTextArray, - mailSenderArray, - mailItemArray - ); - - } catch (Exception e) { - log.error("systemMailInsert Exception: {}", e.getMessage()); - eventService.updateEventStatus(event.getId(), Event.EVENTSTATUS.FAIL); - historyService.setScheduleLog(HISTORYTYPE.SCHEDULE_EVENT_FAIL, e.getMessage()); - throw new RuntimeException("Failed to insert system mail", e); - } - } - - private void processMessages( - List titleMessages, - List textMessages, - List senderMessages - ) { - List msgList = eventService.getMessageList(event.getId()); - - for (Message msg : msgList) { - LanguageConfig langConfig = getLanguageConfig(msg.getLanguage()); - - // Title message - titleMessages.add(SystemMessage.builder() - .languageType(langConfig.getLangType()) - .text(msg.getTitle()) - .build()); - - // Content message - textMessages.add(SystemMessage.builder() - .languageType(langConfig.getLangType()) - .text(msg.getContent()) - .build()); - - // Sender message - senderMessages.add(SystemMessage.builder() - .languageType(langConfig.getLangType()) - .text(langConfig.getSender()) - .build()); - } - } - - private void processItems(List mailItems) { - List itemList = eventService.getItemList(event.getId()); - - for (Item item : itemList) { - mailItems.add(MailItem.newBuilder() - .setItemId(CommonUtils.stringToInt(item.getItem())) - .setCount(item.getItemCnt()) - .build()); - } - } - - @Getter - @AllArgsConstructor - private static class LanguageConfig { - int langType; - String sender; - - static LanguageConfig from(String language) { - return switch (language) { - case "EN" -> new LanguageConfig( - LanguageType.LanguageType_en.getNumber(), - "CALIVERSE" - ); - case "JA" -> new LanguageConfig( - LanguageType.LanguageType_ja.getNumber(), - "カリバース" - ); - default -> new LanguageConfig( - LanguageType.LanguageType_ko.getNumber(), - "칼리버스" - ); - }; - } - } - - private LanguageConfig getLanguageConfig(String language) { - return LanguageConfig.from(language); - } - - private ArrayNode convertToJsonArray(ObjectMapper objectMapper, List items) { - ArrayNode arrayNode = objectMapper.createArrayNode(); - - items.forEach(item -> { - if (item instanceof SystemMessage) { - arrayNode.add(JsonUtils.createSystemMessage((SystemMessage) item)); - } else if (item instanceof MailItem) { - arrayNode.add(JsonUtils.createMAilItem((MailItem) item)); - } - }); - - return arrayNode; - } -} diff --git a/src/main/java/com/caliverse/admin/scheduler/service/MailScheduler.java b/src/main/java/com/caliverse/admin/scheduler/service/MailScheduler.java deleted file mode 100644 index b83487f..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/service/MailScheduler.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.caliverse.admin.scheduler.service; - -import com.caliverse.admin.domain.RabbitMq.MessageHandlerService; -import com.caliverse.admin.domain.RabbitMq.message.LanguageType; -import com.caliverse.admin.domain.RabbitMq.message.MailItem; -import com.caliverse.admin.domain.RabbitMq.message.OperationSystemMessage; -import com.caliverse.admin.domain.entity.*; -import com.caliverse.admin.domain.service.MailService; -import com.caliverse.admin.redis.service.RedisUserInfoService; -import com.caliverse.admin.domain.entity.redis.RedisLoginInfo; -import com.caliverse.admin.global.common.utils.CommonUtils; -import com.caliverse.admin.global.common.utils.ExcelUtils; -import com.caliverse.admin.scheduler.config.ScheduleExecutionConfig; -import com.caliverse.admin.scheduler.ScheduleType; -import com.caliverse.admin.scheduler.Scheduler; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeanUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -@Slf4j -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class MailScheduler implements Scheduler { - private Mail mail; - private MailService mailService; - private RedisUserInfoService redisUserInfoService; - private MessageHandlerService messageHandlerService; - private ExcelUtils excelUtils; - - @Override - public void execute() { - try { - processMail(); - } catch (Exception e) { - log.error("Mail execution failed for mail ID: {}", mail.getId(), e); - mailService.updateMailStatus(mail.getId(), Mail.SENDSTATUS.FAIL); - } - } - - @Override - public boolean isRepeatable() { - return false; - } - - @Override - public ScheduleType getScheduleType() { - return mail.getSendType() == Mail.SENDTYPE.DIRECT_SEND - ? ScheduleType.IMMEDIATE - : ScheduleType.DELAYED; - } - - @Override - public ScheduleExecutionConfig getSchedulerConfig() { - return ScheduleExecutionConfig.builder() - .taskId("mail-" + mail.getId()) - .startTime(mail.getSendDt()) - .build(); - } - - private void processMail() { - if (mail.getReceiveType().equals(Mail.RECEIVETYPE.SINGLE)) { - boolean isSend = mailSend(mail); - if (isSend) { - mailService.updateMailStatus(mail.getId(), Mail.SENDSTATUS.FINISH); - } - } else { - List excelList = excelUtils.getExcelListData(mail.getTarget()); - log.info("mailJob mailSchedule schedule run ExcelList : {}", excelList); - boolean isSend; - mailService.updateMailStatus(mail.getId(), Mail.SENDSTATUS.RUNNING); - - for (Excel excel : excelList) { - String guid = mailService.getGuid(excel.getUser(), excel.getType()); - Mail tempMail = copyMailWithNewTarget(mail, guid); - isSend = mailSend(tempMail); - - if (!isSend) { - log.error("mailJob mailSchedule Excel fail user : {}", excel.getUser()); - mailService.setScheduleLog(HISTORYTYPE.SCHEDULE_MAIL_FAIL, - "mail schedule id: " + mail.getId() + " Excel Send Fail User: " + excel.getUser()); - } else { - log.info("mailJob mailSchedule Excel send user : {}", excel.getUser()); - } - } - mailService.updateMailStatus(mail.getId(), Mail.SENDSTATUS.FINISH); - } - } - - private Mail copyMailWithNewTarget(Mail originalMail, String newTarget) { - Mail newMail = new Mail(); - BeanUtils.copyProperties(originalMail, newMail); - newMail.setTarget(newTarget); - return newMail; - } - - // 메일 전송 - private boolean mailSend(Mail mail) { - try { - RedisLoginInfo info = redisUserInfoService.getUserLoginSessionInfo(mail.getTarget()); - String serverName = Optional.ofNullable(info) - .map(RedisLoginInfo::getCurrentServer) - .orElseGet(() -> { - String firstChannel = redisUserInfoService.getFirstChannel(); - if (firstChannel == null) { - log.error("mailJob mailSend serverName is empty"); - mailService.updateMailStatus(mail.getId(), Mail.SENDSTATUS.FAIL); - mailService.setScheduleLog(HISTORYTYPE.MAIL_SEND_FAIL, "is null server name"); - return null; - } - return firstChannel; - }); - - if (serverName == null) { - return false; - } - - List msgList = mailService.getMailMessageList(mail.getId()); - List titleList = new ArrayList<>(); - List contentList = new ArrayList<>(); - List senderList = new ArrayList<>(); - - for (Message msg : msgList) { - LanguageType lang; - String sender; - - switch (msg.getLanguage()) { - case "EN" -> { - lang = LanguageType.LanguageType_en; - sender = "Administrator"; - } - case "JA" -> { - lang = LanguageType.LanguageType_ja; - sender = "アドミニストレーター"; - } - default -> { - lang = LanguageType.LanguageType_ko; - sender = "시스템 관리자"; - } - } - - titleList.add(createOperationSystemMessage(lang, msg.getTitle())); - contentList.add(createOperationSystemMessage(lang, msg.getContent())); - senderList.add(createOperationSystemMessage(lang, sender)); - } - - List itemList = mailService.getMailItemList(mail.getId()); - List mailItemList = itemList.stream() - .map(item -> MailItem.newBuilder() - .setItemId(CommonUtils.stringToInt(item.getItem())) - .setCount(item.getItemCnt()) - .build()) - .collect(Collectors.toList()); - - log.info("Send Mail Message : {}, target : {}, type :{}", - contentList, mail.getTarget(), mail.getMailType()); - - messageHandlerService.sendMailMessage( - serverName, - mail.getTarget(), - mail.getMailType().toString(), - titleList, - contentList, - mailItemList, - senderList - ); - - log.info("mailJob mailSend completed"); - return true; - - } catch (Exception e) { - log.error("mailSend Exception: {}", e.getMessage()); - mailService.updateMailStatus(mail.getId(), Mail.SENDSTATUS.FAIL); - mailService.setScheduleLog(HISTORYTYPE.MAIL_SEND_FAIL, e.getMessage()); - return false; - } - } - - private OperationSystemMessage createOperationSystemMessage(LanguageType lang, String text) { - return OperationSystemMessage.newBuilder() - .setLanguageType(lang) - .setText(CommonUtils.stringToByte(text)) - .build(); - } -} diff --git a/src/main/java/com/caliverse/admin/scheduler/service/NoticeScheduler.java b/src/main/java/com/caliverse/admin/scheduler/service/NoticeScheduler.java deleted file mode 100644 index 03b7112..0000000 --- a/src/main/java/com/caliverse/admin/scheduler/service/NoticeScheduler.java +++ /dev/null @@ -1,228 +0,0 @@ -package com.caliverse.admin.scheduler.service; - -import com.caliverse.admin.domain.RabbitMq.MessageHandlerService; -import com.caliverse.admin.domain.RabbitMq.message.LanguageType; -import com.caliverse.admin.domain.RabbitMq.message.OperationSystemMessage; -import com.caliverse.admin.domain.entity.HISTORYTYPE; -import com.caliverse.admin.domain.entity.InGame; -import com.caliverse.admin.domain.entity.Message; -import com.caliverse.admin.domain.service.NoticeService; -import com.caliverse.admin.redis.service.RedisUserInfoService; -import com.caliverse.admin.global.common.utils.CommonUtils; -import com.caliverse.admin.scheduler.config.ScheduleExecutionConfig; -import com.caliverse.admin.scheduler.ScheduleType; -import com.caliverse.admin.scheduler.Scheduler; -import jakarta.annotation.PostConstruct; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import java.time.Duration; -import java.time.LocalTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -@Slf4j -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class NoticeScheduler implements Scheduler { - private InGame notice; - private NoticeService noticeService; - private RedisUserInfoService redisUserInfoService; - private MessageHandlerService messageHandlerService; - - private final AtomicInteger currentExecutionCount = new AtomicInteger(0); // 현재 실행 횟수를 추적 - - @Override - public void execute() { - try { - // 실행 전 횟수 체크 - if (shouldStopExecution()) { - log.info("Notice execution stopped - Reached maximum count. NoticeId: {}, Current count: {}, Max count: {}", - notice.getId(), getCurrentCount(), getMaxCount()); - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FINISH); - return; - } - - // 실행 횟수 증가 및 검증 - int newCount = currentExecutionCount.incrementAndGet(); - if (newCount > getMaxCount()) { - log.warn("Notice execution exceeded max count. NoticeId: {}, Current count: {}, Max count: {}", - notice.getId(), newCount, getMaxCount()); - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FINISH); - return; - } - - boolean isSend = noticeSend(); - if (!isSend) { - // 전송 실패 시 카운트 롤백 - currentExecutionCount.decrementAndGet(); - return; - } - - if(notice.getSendStatus().equals(InGame.SENDSTATUS.WAIT)) { - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.RUNNING); - } - - // DB 업데이트 전 한번 더 체크 - if (newCount <= getMaxCount()) { - noticeService.updateNoticeCount(notice.getId()); - log.info("Notice execution successful. NoticeId: {}, Current count: {}, Max count: {}", - notice.getId(), newCount, getMaxCount()); - - // 최대 횟수 도달 시 상태 업데이트 - if (newCount >= getMaxCount()) { - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FINISH); - log.info("Notice completed all executions. NoticeId: {}", notice.getId()); - } - } - - } catch (Exception e) { - currentExecutionCount.decrementAndGet(); - log.error("Notice execution failed for notice ID: {}", notice.getId(), e); - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FAIL); - noticeService.setScheduleLog(HISTORYTYPE.SCHEDULE_NOTICE_FAIL, e.getMessage()); - } - } - - private boolean shouldStopExecution() { - if (!notice.getIsRepeat() || notice.getRepeatType() != InGame.REPEATTYPE.COUNT) { - return false; - } - return getCurrentCount() >= getMaxCount(); - } - - private int getCurrentCount() { - return currentExecutionCount.get(); - } - - private int getMaxCount() { - return notice.getRepeatCnt().intValue(); - } - - @Override - public boolean isRepeatable() { - return notice.getIsRepeat(); - } - - @Override - public ScheduleType getScheduleType() { - if (!notice.getIsRepeat()) { - return ScheduleType.DELAYED; - } - - return switch (notice.getRepeatType()) { - case COUNT, DATE -> ScheduleType.RECURRING; - case TIME -> ScheduleType.PERIODIC; - default -> ScheduleType.DELAYED; - }; - } - - @Override - public ScheduleExecutionConfig getSchedulerConfig() { - return ScheduleExecutionConfig.builder() - .taskId("notice-" + notice.getId()) - .startTime(notice.getSendDt()) - .endTime(notice.getEndDt()) - .interval(getRepeatInterval()) - .repeatCount(notice.getRepeatCnt().intValue()) - .build(); - } - - private Duration getRepeatInterval() { - if (!notice.getIsRepeat()) { - return null; - } - - return switch (notice.getRepeatType()) { - case COUNT -> Duration.ofSeconds(LocalTime.parse(notice.getRepeatDt()).toSecondOfDay()); - case DATE -> Duration.ofMillis(CommonUtils.intervalToMillis(notice.getRepeatDt())); - case TIME -> null; - }; - } - - @PostConstruct - private void initialize() { - // 기존 실행 횟수로 초기화 - currentExecutionCount.set(notice.getSendCnt().intValue()); - } - - // SchedulerManager에서 사용할 수 있도록 현재 실행 상태 제공 - public boolean hasReachedMaxExecutions() { - return getCurrentCount() >= getMaxCount(); - } - - // 실행 횟수 검증을 위한 메서드 - public boolean isValidExecutionCount() { - return getCurrentCount() <= getMaxCount(); - } - - private boolean noticeSend() { - try { - List serverList = redisUserInfoService.getAllServerList(); - if (serverList.isEmpty()) { - log.error("noticeJob noticeSend serverList is empty"); - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FAIL); - noticeService.setScheduleLog(HISTORYTYPE.NOTICE_SEND_FAIL, "is null server name"); - return false; - } - - List msgList = noticeService.getNoticeMessageList(notice.getId()); - List contentList = new ArrayList<>(); - List senderList = new ArrayList<>(); - - for (Message msg : Collections.unmodifiableList(msgList)) { - LanguageType lang; - String sender; - - switch (msg.getLanguage()) { - case "EN" -> { - lang = LanguageType.LanguageType_en; - sender = "Administrator"; - } - case "JA" -> { - lang = LanguageType.LanguageType_ja; - sender = "アドミニストレーター"; - } - default -> { - lang = LanguageType.LanguageType_ko; - sender = "시스템 관리자"; - } - } - - contentList.add(createOperationSystemMessage(lang, msg.getContent())); - senderList.add(createOperationSystemMessage(lang, sender)); - } - - log.info("Send Notice Message: {}, type: {}", contentList, notice.getMessageType()); - - messageHandlerService.sendNoticeMessage( - serverList, - notice.getMessageType().toString(), - contentList, - senderList - ); - - log.info("noticeJob noticeSend completed"); - return true; - - } catch (Exception e) { - log.error("noticeSend Exception: {}", e.getMessage()); - noticeService.updateNoticeStatus(notice.getId(), InGame.SENDSTATUS.FAIL); - noticeService.setScheduleLog(HISTORYTYPE.NOTICE_SEND_FAIL, e.getMessage()); - return false; - } - } - - private OperationSystemMessage createOperationSystemMessage(LanguageType lang, String text) { - return OperationSystemMessage.newBuilder() - .setLanguageType(lang) - .setText(CommonUtils.stringToByte(text)) - .build(); - } -}