This commit is contained in:
Rinjae
2025-10-16 11:53:45 +09:00
commit c204bbf106
9 changed files with 724 additions and 0 deletions
@@ -0,0 +1,225 @@
package com.eactive.ext.kjb.ums;
import com.eactive.apim.portal.portaluser.entity.PortalUser;
import com.eactive.apim.portal.template.entity.MessageRequest;
import com.eactive.apim.portal.template.repository.MessageRequestRepository;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.transaction.Transactional;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class EmailJob {
private final EmailProperty prop;
private final MessageRequest messageRequest;
private final Path tempFilePath;
private final Path eaiFilePath;
private final Path backupFilePath;
private final Path failedFilePath;
private MessageRequestRepository messageRequestRepository;
private final LocalDateTime now = LocalDateTime.now();
private EmailJob(EmailProperty prop, MessageRequest messageRequest, MessageRequestRepository messageRequestRepository) {
this.messageRequest = messageRequest;
this.prop = prop;
String filename = messageRequest.getServiceId() + "_" + DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(now);
this.tempFilePath = Paths.get(prop.getEaiBatchSendDir(), filename + ".tmp");
this.eaiFilePath = Paths.get(prop.getEaiBatchSendDir(), filename);
this.backupFilePath = Paths.get(prop.getEaiBatchBackupDir(), filename);
this.failedFilePath = Paths.get(prop.getEaiBatchBackupDir(), filename + ".failed");
this.messageRequestRepository = messageRequestRepository;
this.doCreateNewFile();
}
public static EmailJob create(EmailProperty prop, MessageRequest messageRequest, MessageRequestRepository repository) {
if (prop == null) {
throw new IllegalArgumentException("Property is null");
}
if (messageRequest == null) {
throw new IllegalArgumentException("MessageRequest is null");
}
validateMessageRequest(messageRequest, false, true);
if (messageRequest.getUser() != null) {
PortalUser user = messageRequest.getUser();
messageRequest.setUmsUid(UUIDBase62Util.uuidStringToBase62(user.getId()));
if (repository != null) {
repository.save(messageRequest);
}
}
return new EmailJob(prop, messageRequest, repository);
}
public static EmailValidationResult validateMessageRequest(MessageRequest messageRequest, boolean forSend, boolean isThrow) {
Map<String, String> errors = new HashMap<>();
if (StringUtils.isEmpty(messageRequest.getId())) {
errors.put("id", "ID is required");
}
if (StringUtils.isEmpty(messageRequest.getEmail())) {
errors.put("email", "Email is required");
}
if (StringUtils.isEmpty(messageRequest.getUsername())) {
errors.put("username", "Username is required");
}
if (forSend) {
// TODO: 발송용 체크
if (StringUtils.isEmpty(messageRequest.getServiceId())) {
errors.put("serviceId", "Service ID is required");
}
}
// 결과 리턴
if (!errors.isEmpty()) {
if (isThrow) {
throw new IllegalArgumentException("Invalid MessageRequest: " + errors);
} else {
return EmailValidationResult.failed(errors);
}
}
return EmailValidationResult.ok();
}
@Transactional
public void sendEmail() {
if (messageRequestRepository != null) {
PortalUser user = messageRequest.getUser();
if (user != null) {
messageRequest.setUmsUid(UUIDBase62Util.uuidStringToBase62(user.getId()));
}
messageRequestRepository.save(messageRequest);
}
try {
doSaveFile();
eaiBatchCall();
doSuccess();
} catch (Exception e) {
doFail();
} finally {
doDeleteEaiFile();
}
}
private void doDeleteEaiFile() {
// TODO: EAI 발송용 파일 삭제
}
private void doFail() {
// TODO: EAI 발송 실패 처리
}
private void eaiBatchCall() {
// TODO: EAI 배치 호출
}
private void doSuccess() {
// 백업 디렉토리로 복사
try {
Files.copy(eaiFilePath, backupFilePath);
log.debug("Copied EAI file to backup: {} -> {}", eaiFilePath.toString(), backupFilePath.toString());
} catch (IOException e) {
log.error("Cannot copy EAI file to backup: {} -> {}", eaiFilePath.toString(), backupFilePath.toString(), e);
}
}
public void doCreateNewFile() {
final String filename = "EMAIL_" + messageRequest.getId() + ".json";
if (eaiFilePath.toFile().exists()) {
log.error("Mail File exists for ID: {}", messageRequest.getId());
throw new IllegalStateException("Mail File exists for ID: " + messageRequest.getId());
}
File mailFile = tempFilePath.toFile();
try {
boolean created = mailFile.createNewFile();
if (!created) {
log.error("Cannot create mail file for ID: {}", messageRequest.getId());
throw new IllegalStateException("Cannot create mail file for ID: " + messageRequest.getId());
}
} catch (Exception ex) {
log.error("Cannot create mail file for ID: {}", messageRequest.getId(), ex);
throw new IllegalStateException("Cannot create mail file for ID: " + messageRequest.getId(), ex);
}
}
public void doSaveFile() {
String jsonContent = generateJSON(true);
log.debug("Generated JSON: \n{}", jsonContent);
// 저장은 임시 파일에 euc-kr 인코딩으로 저장
byte[] data = null;
try {
data = jsonContent.getBytes("euc-kr");
} catch (UnsupportedEncodingException e) {
log.error("Cannot encode(euc-kr) JSON: \n{}", jsonContent, e);
throw new RuntimeException(e);
}
try {
Files.write(tempFilePath, data);
Files.copy(tempFilePath, eaiFilePath);
Files.delete(tempFilePath);
log.debug("Wrote JSON to file: {}", eaiFilePath.toString());
} catch (IOException e) {
log.error("Cannot write JSON to file: {}", eaiFilePath.toString(), e);
throw new RuntimeException(e);
}
}
public String generateJSON(boolean isPretty) {
validateMessageRequest(messageRequest, true, true);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("MAKE_DATE", DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDateTime.now()));
jsonObject.addProperty("MAKE_SEQNO", "0001");
jsonObject.addProperty("CAMP_ID", messageRequest.getServiceId()); // 전자금융 고객이메일 발송 업무ID (SERVICE_ID)
jsonObject.addProperty("ID", messageRequest.getUmsUid()); // 고객 ID
jsonObject.addProperty("EMAIL", messageRequest.getEmail());
jsonObject.addProperty("NAME", messageRequest.getUsername());
jsonObject.addProperty("ENCKEY", ""); // 보안메일용으로 기입 불필요
jsonObject.addProperty("SUBJECT", messageRequest.getSubject());
jsonObject.addProperty("MESSAGE", messageRequest.getMessage());
if (isPretty) {
return new GsonBuilder().setPrettyPrinting().create().toJson(jsonObject);
} else {
return jsonObject.toString();
}
}
}