diff --git a/build.gradle b/build.gradle index a776fa2..d9e6691 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ jar { test { useJUnitPlatform() - systemProperty "kjb_safedb.mode", project.findProperty("kjb_safedb.mode") ?: "" + systemProperty "kjb_safedb.mode", System.getProperty("kjb_safedb.mode") if (project.hasProperty("safedb")) { systemProperty "kjb_safedb.mode", "real" diff --git a/src/main/java/com/eactive/ext/kjb/common/KjbEaiBatchException.java b/src/main/java/com/eactive/ext/kjb/common/KjbEaiBatchException.java new file mode 100644 index 0000000..a28d1c8 --- /dev/null +++ b/src/main/java/com/eactive/ext/kjb/common/KjbEaiBatchException.java @@ -0,0 +1,11 @@ +package com.eactive.ext.kjb.common; + +public class KjbEaiBatchException extends Exception { + public KjbEaiBatchException(String message) { + super(message); + } + + public KjbEaiBatchException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/eactive/ext/kjb/common/KjbProperty.java b/src/main/java/com/eactive/ext/kjb/common/KjbProperty.java index 167b3c2..498bc08 100644 --- a/src/main/java/com/eactive/ext/kjb/common/KjbProperty.java +++ b/src/main/java/com/eactive/ext/kjb/common/KjbProperty.java @@ -16,21 +16,35 @@ public class KjbProperty { private int eaiBatchConnectionTimeout = 5; @Min(1) @Max(30) - private int eaiBatchResponseTimeout = 10; + private int eaiBatchResponseTimeout = 5; + + @Min(1) @Max(30) + private int eaiBatchTimeout = 10; + + @NotEmpty + private String eaiBatchCharset = "euc-kr"; @NotEmpty(message = "kjb.ums.eai_batch.send_dir 는 필수값입니다.") @Pattern(regexp = "^(?:[a-zA-Z]:\\\\|\\\\|\\/)(?:[\\w\\-\\.]+[\\\\\\/])*[\\w\\-\\.]+$", - message = "kjb.ums.eai_batch.send_dir 은 절대 경로여야 합니다. 예: /Data/eapim/portal/sendmail/snd 또는 C:\\Data\\eapim\\portal\\sendmail\\snd") + message = "kjb.ums.eai_batch.send_dir 은 절대 경로여야 합니다. 예: /Data/eapim/portal/sendmail/snd 또는 c:\\kjb-logs\\sendmail\\snd") private String umsEaiBatchSendDir; @NotEmpty(message = "kjb.ums.eai_batch.backup_dir 는 필수값입니다.") @Pattern(regexp = "^(?:[a-zA-Z]:\\\\|\\\\|\\/)(?:[\\w\\-\\.]+[\\\\\\/])*[\\w\\-\\.]+$", - message = "kjb.ums.eai_batch.backup_dir 은 절대 경로여야 합니다. 예: /Data/eapim/portal/sendmail/bak 또는 C:\\Data\\eapim\\portal\\sendmail\\bak") + message = "kjb.ums.eai_batch.backup_dir 은 절대 경로여야 합니다. 예: /Data/eapim/portal/sendmail/bak 또는 c:\\kjb-logs\\sendmail\\bak") private String umsEaiBatchBackupDir; + @NotEmpty(message = "kjb.ums.eai_batch.error_dir 는 필수값입니다.") + @Pattern(regexp = "^(?:[a-zA-Z]:\\\\|\\\\|\\/)(?:[\\w\\-\\.]+[\\\\\\/])*[\\w\\-\\.]+$", + message = "kjb.ums.eai_batch.error_dir 은 절대 경로여야 합니다. 예: /Data/eapim/portal/sendmail/errpr 또는 c:\\kjb-logs\\sendmail\\error") + private String umsEaiBatchErrorDir; + @Pattern(regexp = "^[a-zA-Z0-9]{13}$", message = "kjb.ums.eai_batch.interface_id 는 12자리 영문대소문자 및 숫자 조합이어야 합니다.") private String umsEaiBatchInterfaceId; + @Min(1) @Max(365) + private int umsEaiBatchRetentionDate = 60; + @Pattern(regexp = "^(https?://[^\\s/$.?#][^\\s]*)|\\s*$", message = "kjb.ums.host_url 는 유효한 URL 형식이거나 공백이어야 합니다. 예: http://example.com/api") private String umsHostUrl; @@ -42,5 +56,8 @@ public class KjbProperty { private int umsConnectionTimeout = 5; @Min(1) @Max(30) - private int umsResponseTimeout = 10; + private int umsResponseTimeout = 5; + + @Min(1) @Max(30) + private int umsTimeout = 10; } diff --git a/src/main/java/com/eactive/ext/kjb/eai/EaiBatchInterface.java b/src/main/java/com/eactive/ext/kjb/eai/EaiBatchInterface.java new file mode 100644 index 0000000..6d9832e --- /dev/null +++ b/src/main/java/com/eactive/ext/kjb/eai/EaiBatchInterface.java @@ -0,0 +1,64 @@ +package com.eactive.ext.kjb.eai; + +import lombok.Builder; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.validator.constraints.NotEmpty; + +import javax.validation.constraints.Pattern; +import java.io.File; +import java.nio.file.Paths; + +@Data +@Builder +@Slf4j +public class EaiBatchInterface { + @Pattern(regexp = "^[a-zA-Z0-9]{13}$", message = "id는 12자리 영문대소문자 및 숫자 조합이어야 합니다.") + private String id; + + @NotEmpty + @Pattern(regexp = "^(?:[a-zA-Z]:\\\\|\\\\|\\/)(?:[\\w\\-\\.]+[\\\\\\/])*[\\w\\-\\.]+$", message = "sendDir은 절대경로로 지정되어야 합니다.") + private String sendDir; + + @NotEmpty + @Pattern(regexp = "^(?:[a-zA-Z]:\\\\|\\\\|\\/)(?:[\\w\\-\\.]+[\\\\\\/])*[\\w\\-\\.]+$", message = "backupDir은 절대경로로 지정되어야 합니다.") + private String backupDir; + + @NotEmpty + @Pattern(regexp = "^(?:[a-zA-Z]:\\\\|\\\\|\\/)(?:[\\w\\-\\.]+[\\\\\\/])*[\\w\\-\\.]+$", message = "errorDir은 절대경로로 지정되어야 합니다.") + private String errorDir; + + + public void moveError(String filename) { + move(filename, errorDir); + } + + public void moveBackup(String filename) { + move(filename, backupDir); + } + + private void move(String filename, String targetDir) { + File file = Paths.get(sendDir, filename).toFile(); + File targetDirFile = new File(targetDir); + File targetFile = new File(targetDir, file.getName()); + + log.debug("송신파일 이동 시작 - {} -> {}", filename, targetDir); + + if (!file.exists()) { + log.warn("송신 파일이 존재 하지 않습니다. ({})", file.getAbsolutePath()); + return; + } + + if (!targetDirFile.exists()) { + if (!targetDirFile.mkdirs()) { + log.warn("대상 디렉토리 생성 실패 ({})", file.getAbsolutePath()); + return; + } + } + + if (!file.renameTo(targetFile)) { + log.warn("송신 파일 이동 실패 - {}", targetFile.getAbsolutePath()); + return; + } + } +} diff --git a/src/main/java/com/eactive/ext/kjb/eai/EaiBatchMessage.java b/src/main/java/com/eactive/ext/kjb/eai/EaiBatchMessage.java index 7ce84d2..db6685a 100644 --- a/src/main/java/com/eactive/ext/kjb/eai/EaiBatchMessage.java +++ b/src/main/java/com/eactive/ext/kjb/eai/EaiBatchMessage.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; @Slf4j @@ -17,6 +18,9 @@ public class EaiBatchMessage { @Getter private String count = ""; + /** + * 요청시 사용 안함, 응답시 1: 성공, 2: 실패 + */ @Getter private String resultCode = ""; @@ -28,14 +32,17 @@ public class EaiBatchMessage { private boolean isReadOnly = false; + private String charset; + private EaiBatchMessage() {} - public static EaiBatchMessage createRequest(String interfaceId, String filename) { + public static EaiBatchMessage createRequest(String interfaceId, String filename, String charset) { EaiBatchMessage message = new EaiBatchMessage(); message.interfaceId = interfaceId; message.filename = filename; + message.charset = charset; return message; } @@ -46,16 +53,16 @@ public class EaiBatchMessage { message.isReadOnly = true; if (rawMessage.length() >= 40) { - message.interfaceId = rawMessage.substring(0, 20).trim(); - message.baseDate = rawMessage.substring(20, 28).trim(); - message.count = rawMessage.substring(28, 38).trim(); - message.resultCode = rawMessage.substring(38, 39).trim(); + message.interfaceId = rawMessage.substring(0, 19).trim(); + message.baseDate = rawMessage.substring(19, 27).trim(); + message.count = rawMessage.substring(27, 37).trim(); + message.resultCode = rawMessage.substring(37, 38).trim(); // filename 은 @@가 발견되면 이전 까지 trim / 발견되지 않으면 나머지 전체 그리고 trim - int endIdx = rawMessage.indexOf("@@", 39); + int endIdx = rawMessage.indexOf("@@", 38); if (endIdx == -1) { - message.filename = rawMessage.substring(39).trim(); + message.filename = rawMessage.substring(38).trim(); } else { - message.filename = rawMessage.substring(39, endIdx).trim(); + message.filename = rawMessage.substring(38, endIdx).trim(); } } @@ -74,16 +81,20 @@ public class EaiBatchMessage { return rawMessage; } else { ByteBuffer buffer = ByteBuffer.allocate(1024); - // 0~19 : 인터페이스ID (20) - buffer.put(fixedString(interfaceId, 20)); - // 19-8: 기준일자 (8) - buffer.put(fixedString(baseDate, 8)); - // 27-10 : 건수 (10) - buffer.put(fixedString(count, 10)); - // 37-1 : 결과코드 (1) - buffer.put(fixedString(resultCode, 1)); - // 38-100 : 파일명 (100) - buffer.put(fixedString(filename, 100)); + try { + // 인터페이스ID (19) + buffer.put(fixedString(interfaceId, 19)); + // 기준일자 (8) + buffer.put(fixedString(baseDate, 8)); + // 건수 (10) + buffer.put(fixedString(count, 10)); + // 결과코드 (1) + buffer.put(fixedString(resultCode, 1)); + // 파일명 (100) + buffer.put(fixedString(filename, 100)); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } // 종료 구분자 (2) buffer.put("@@".getBytes()); @@ -93,11 +104,11 @@ public class EaiBatchMessage { } } - private byte[] fixedString(String str, int length) { + private byte[] fixedString(String str, int length) throws UnsupportedEncodingException { if (str == null) { str = ""; } - byte[] strBytes = str.getBytes(); + byte[] strBytes = str.getBytes(this.charset); byte[] result = new byte[length]; int copyLength = Math.min(strBytes.length, length); diff --git a/src/main/java/com/eactive/ext/kjb/eai/KjbEaiBatchModule.java b/src/main/java/com/eactive/ext/kjb/eai/KjbEaiBatchModule.java index 39133f1..d1f7a2e 100644 --- a/src/main/java/com/eactive/ext/kjb/eai/KjbEaiBatchModule.java +++ b/src/main/java/com/eactive/ext/kjb/eai/KjbEaiBatchModule.java @@ -1,5 +1,6 @@ package com.eactive.ext.kjb.eai; +import com.eactive.ext.kjb.common.KjbEaiBatchException; import com.eactive.ext.kjb.common.KjbProperty; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -11,10 +12,13 @@ import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.net.URIBuilder; import org.apache.hc.core5.util.Timeout; +import javax.validation.Valid; import javax.validation.constraints.NotNull; -import java.io.IOException; +import java.io.File; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.util.concurrent.*; @Slf4j public class KjbEaiBatchModule { @@ -42,10 +46,16 @@ public class KjbEaiBatchModule { } } - public EaiBatchMessage call(String interfaceId, String filename) throws IOException { - EaiBatchMessage reqMessage = EaiBatchMessage.createRequest(interfaceId, filename); + public EaiBatchMessage call(@Valid EaiBatchInterface intf, String filename) throws KjbEaiBatchException { + EaiBatchMessage reqMessage = EaiBatchMessage.createRequest(intf.getId(), filename, property.getEaiBatchCharset()); log.debug("EAI 배치 호출: {}", reqMessage); + // 송신 파일 체크 + File sendFile = Paths.get(intf.getSendDir(), filename).toFile(); + if (!sendFile.exists() || !sendFile.isFile()) { + throw new KjbEaiBatchException("Not found send file - " + sendFile.toPath()); + } + if (this.httpClient != null) { URI uri = null; try { @@ -60,17 +70,37 @@ public class KjbEaiBatchModule { final HttpGet httpGet = new HttpGet(uri); httpGet.setConfig(requestConfig); - String message = httpClient.execute(httpGet, response -> EntityUtils.toString(response.getEntity(), "EUC-KR")); + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future future = executor.submit(() -> + httpClient.execute(httpGet, response -> EntityUtils.toString(response.getEntity(), "EUC-KR"))); - EaiBatchMessage resMessage = EaiBatchMessage.fromResponse(message); - log.debug("EAI 배치 응답: {}", resMessage); - return resMessage; + EaiBatchMessage resMessage = null; + try { + String message = future.get(property.getEaiBatchTimeout(), TimeUnit.SECONDS); + resMessage = EaiBatchMessage.fromResponse(message); + log.debug("EAI 배치 응답: {}", resMessage); + + return resMessage; + } catch (InterruptedException | ExecutionException | TimeoutException e) { + log.error("EAI Batch call exception", e); + throw new KjbEaiBatchException("EAI Batch call failed", e); + } finally { + executor.shutdown(); + + // EAI 송신 실패일 경우 에러 경로로 이동 + if (resMessage != null && "1".equals(resMessage.getResultCode())) { + intf.moveBackup(filename); + } else { + intf.moveError(filename); + } + } } else { log.info("EAI_BATCH_URL 이 설정되지 않아 실제 호출하지 않음. 요청 메시지: {}", reqMessage); // 정상응답 리턴 - EaiBatchMessage resMessage = EaiBatchMessage.fromResponse(String.format("%-20s%-8s%-10s%-1s%s@@", interfaceId, "", "0000000000", "1", "S:" + filename)); + EaiBatchMessage resMessage = EaiBatchMessage.fromResponse(String.format("%-19s%-8s%-10s%-1s%s@@", intf.getId(), "", "0000000000", "1", "S:" + filename)); log.debug("EAI 배치 응답(모의): {}", resMessage); + intf.moveBackup(filename); return resMessage; } } diff --git a/src/main/java/com/eactive/ext/kjb/ums/EmailJob.java b/src/main/java/com/eactive/ext/kjb/ums/EmailJob.java index 9f3cf8c..c7de34a 100644 --- a/src/main/java/com/eactive/ext/kjb/ums/EmailJob.java +++ b/src/main/java/com/eactive/ext/kjb/ums/EmailJob.java @@ -3,9 +3,13 @@ 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.eactive.ext.kjb.common.KjbEaiBatchException; import com.eactive.ext.kjb.common.KjbProperty; import com.eactive.ext.kjb.eai.EaiBatchMessage; +import com.eactive.ext.kjb.eai.EaiBatchInterface; import com.eactive.ext.kjb.eai.KjbEaiBatchModule; +import com.eactive.ext.kjb.safedb.KjbSafedbWrapper; +import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import lombok.extern.slf4j.Slf4j; @@ -28,6 +32,10 @@ public class EmailJob { private final KjbProperty prop; private final MessageRequest messageRequest; + private static final int READY = 1; // Temp 파일 생성 단계 + private static final int BEFORE_SEND = 2; + private static final int SEND = 3; + private final Path tempFilePath; private final Path eaiFilePath; private final Path backupFilePath; @@ -35,13 +43,15 @@ public class EmailJob { private final MessageRequestRepository messageRequestRepository; private final LocalDateTime now = LocalDateTime.now(); + private int eaiPhase = 0; + private EmailJob(KjbProperty prop, MessageRequest messageRequest, MessageRequestRepository messageRequestRepository) { this.messageRequest = messageRequest; this.prop = prop; - String filename = messageRequest.getServiceId() + "_" + DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(now); + String filename = messageRequest.getServiceId() + "_" + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(now); this.tempFilePath = Paths.get(prop.getUmsEaiBatchSendDir(), filename + ".tmp"); this.eaiFilePath = Paths.get(prop.getUmsEaiBatchSendDir(), filename); this.backupFilePath = Paths.get(prop.getUmsEaiBatchBackupDir(), filename); @@ -112,7 +122,7 @@ public class EmailJob { @Transactional - public void sendEmail() { + public void sendEmail() throws KjbEaiBatchException { if (messageRequestRepository != null) { PortalUser user = messageRequest.getUser(); if (user != null) { @@ -130,9 +140,11 @@ public class EmailJob { log.debug("발송 성공 처리"); doSuccess(); + } catch (KjbEaiBatchException e) { + doFail(e); } catch (Exception e) { - log.error("이메일 발송 실패", e); - doFail(); + log.error(e.getMessage(), e); + doFail(e); } finally { doDeleteEaiFile(); } @@ -142,13 +154,24 @@ public class EmailJob { // TODO: EAI 발송용 파일 삭제 } - private void doFail() { + private void doFail(Exception e) throws KjbEaiBatchException { // TODO: EAI 발송 실패 처리 + if (e instanceof KjbEaiBatchException) { + throw (KjbEaiBatchException) e; + } else { + throw new KjbEaiBatchException("이메일 발송 실패", e); + } } - private void eaiBatchCall() throws IOException { + private void eaiBatchCall() throws KjbEaiBatchException { KjbEaiBatchModule eaiBatchModule = new KjbEaiBatchModule(prop); - EaiBatchMessage result = eaiBatchModule.call(prop.getUmsEaiBatchInterfaceId(), eaiFilePath.getFileName().toString()); + EaiBatchInterface eaiBatchInterface = EaiBatchInterface.builder() + .id(prop.getUmsEaiBatchInterfaceId()) + .sendDir(prop.getUmsEaiBatchSendDir()) + .backupDir(prop.getUmsEaiBatchBackupDir()) + .errorDir(prop.getUmsEaiBatchErrorDir()) + .build(); + EaiBatchMessage result = eaiBatchModule.call(eaiBatchInterface, eaiFilePath.getFileName().toString()); if (!"1".equals(result.getResultCode())) { log.error("EAI Batch call failed: {}", result); @@ -159,19 +182,11 @@ public class EmailJob { } 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()); @@ -210,29 +225,48 @@ public class EmailJob { } catch (IOException e) { log.error("Cannot write JSON to file: {}", eaiFilePath.toString(), e); throw new RuntimeException(e); + } finally { + // 임시 파일이 남아 있다면 오류 상황이므로 에러 경로로 이동 + if (Files.exists(tempFilePath)) { + try { + Files.move(tempFilePath, Paths.get(prop.getUmsEaiBatchErrorDir(), tempFilePath.getFileName().toString())); + } catch (IOException e) { + log.warn("임시 파일 저장시 실패 하여 에러 경로로 옮기는 도중 에러 발생", e); + } + } } } public String generateJSON(boolean isPretty) { validateMessageRequest(messageRequest, true, true); + KjbSafedbWrapper safedb = KjbSafedbWrapper.getInstance(); 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("EMAIL", safedb.encryptNotRnnoString(messageRequest.getEmail())); jsonObject.addProperty("NAME", messageRequest.getUsername()); jsonObject.addProperty("ENCKEY", ""); // 보안메일용으로 기입 불필요 + Gson gson = new Gson(); + log.debug("Template string to json: {}", messageRequest.getMessage()); + JsonObject contentJSon = gson.fromJson(messageRequest.getMessage(), JsonObject.class); + contentJSon.entrySet().forEach(entry -> { + jsonObject.add(entry.getKey(), entry.getValue()); + }); - jsonObject.addProperty("SUBJECT", messageRequest.getSubject()); - jsonObject.addProperty("MESSAGE", messageRequest.getMessage()); +// jsonObject.addProperty("SUBJECT", messageRequest.getSubject()); +// jsonObject.addProperty("MESSAGE", messageRequest.getMessage()); + String jsonString; if (isPretty) { - return new GsonBuilder().setPrettyPrinting().create().toJson(jsonObject); + jsonString = new GsonBuilder().setPrettyPrinting().create().toJson(jsonObject); } else { - return jsonObject.toString(); + jsonString = jsonObject.toString(); } + + return jsonString; } } diff --git a/src/main/java/com/eactive/ext/kjb/ums/EmailSendModule.java b/src/main/java/com/eactive/ext/kjb/ums/KjbEmailSendModule.java similarity index 66% rename from src/main/java/com/eactive/ext/kjb/ums/EmailSendModule.java rename to src/main/java/com/eactive/ext/kjb/ums/KjbEmailSendModule.java index 4c40457..159f554 100644 --- a/src/main/java/com/eactive/ext/kjb/ums/EmailSendModule.java +++ b/src/main/java/com/eactive/ext/kjb/ums/KjbEmailSendModule.java @@ -3,6 +3,7 @@ package com.eactive.ext.kjb.ums; import com.eactive.apim.portal.template.entity.MessageCode; import com.eactive.apim.portal.template.entity.MessageRequest; import com.eactive.apim.portal.template.repository.MessageRequestRepository; +import com.eactive.ext.kjb.common.KjbEaiBatchException; import com.eactive.ext.kjb.common.KjbProperty; import com.eactive.ext.kjb.utils.ValidationUtil; import lombok.extern.slf4j.Slf4j; @@ -14,25 +15,36 @@ import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; @Slf4j -public class EmailSendModule { - private static EmailSendModule instance = null; +public class KjbEmailSendModule { + public final static int[] ALLOW_CHANNELS = { MessageCode.Channels.EMAIL.getValue() }; + + private static KjbEmailSendModule instance = null; private static KjbProperty prop; private final MessageRequestRepository repo; - public static synchronized EmailSendModule getInstance(KjbProperty property, - MessageRequestRepository messageRequestRepository) { + public static synchronized KjbEmailSendModule getInstance(KjbProperty property, + MessageRequestRepository messageRequestRepository) { ValidationUtil.validateOrThrow(property); if (instance == null) { - instance = new EmailSendModule(property, messageRequestRepository); + instance = new KjbEmailSendModule(property, messageRequestRepository); } return instance; } + public static boolean isAllowChannel(MessageRequest message) { + for (int channel : ALLOW_CHANNELS) { + if ((message.getMessageCode().getChannels() & channel) == channel) { + return true; + } + } + return false; + } + public static void environmentCheck() { if (StringUtils.isEmpty(prop.getEaiBatchUrl())) { @@ -91,8 +103,8 @@ public class EmailSendModule { - private EmailSendModule(KjbProperty property, - MessageRequestRepository repo) { + private KjbEmailSendModule(KjbProperty property, + MessageRequestRepository repo) { this.repo = repo; if (property != null && prop == null) { @@ -102,33 +114,28 @@ public class EmailSendModule { environmentCheck(); } - public CompletableFuture sendEmail(MessageRequest messageRequest, BiConsumer callback) { - return CompletableFuture - .supplyAsync(() -> { - String serviceId = "UNKNOWN"; + public void sendEmail(MessageRequest messageRequest) throws KjbEaiBatchException { + String serviceId = "UNKNOWN"; - serviceId = messageRequest.getMessageCode().getServiceId(); - messageRequest.setServiceId(serviceId); + serviceId = messageRequest.getMessageCode().getServiceId(); + messageRequest.setServiceId(serviceId); - if (StringUtils.isEmpty(serviceId)) { - throw new IllegalArgumentException("MessageRequest MessageCode serviceId is required"); - } + if (StringUtils.isEmpty(serviceId)) { + throw new IllegalArgumentException("MessageRequest MessageCode serviceId is required"); + } - if (MessageCode.Channels.EMAIL.getValue() != (messageRequest.getMessageCode().getChannels() & MessageCode.Channels.EMAIL.getValue())) { - log.error("지원하지 않는 발송 채널 - {}", messageRequest.getMessageCode()); - throw new IllegalArgumentException("지원하지 않는 발송 채널 - " + messageRequest.getMessageCode()); - } + if (MessageCode.Channels.EMAIL.getValue() != (messageRequest.getMessageCode().getChannels() & MessageCode.Channels.EMAIL.getValue())) { + log.error("지원하지 않는 발송 채널 - {}", messageRequest.getMessageCode()); + throw new IllegalArgumentException("지원하지 않는 발송 채널 - " + messageRequest.getMessageCode()); + } - if (repo != null) { - repo.save(messageRequest); - } + if (repo != null) { + repo.save(messageRequest); + } - EmailJob job = EmailJob.create(prop, messageRequest, repo); - job.sendEmail(); + EmailJob job = EmailJob.create(prop, messageRequest, repo); + job.sendEmail(); - log.debug("JSON : {}", job.generateJSON(true)); - return true; - }) - .whenComplete(callback); + log.debug("JSON : {}", job.generateJSON(true)); } } diff --git a/src/test/java/com/eactive/ext/kjb/ums/test/UmsTest.java b/src/test/java/com/eactive/ext/kjb/ums/test/UmsTest.java index 527b377..4f57a20 100644 --- a/src/test/java/com/eactive/ext/kjb/ums/test/UmsTest.java +++ b/src/test/java/com/eactive/ext/kjb/ums/test/UmsTest.java @@ -2,8 +2,9 @@ package com.eactive.ext.kjb.ums.test; import com.eactive.apim.portal.template.entity.MessageCode; import com.eactive.apim.portal.template.entity.MessageRequest; +import com.eactive.ext.kjb.common.KjbEaiBatchException; import com.eactive.ext.kjb.common.KjbProperty; -import com.eactive.ext.kjb.ums.EmailSendModule; +import com.eactive.ext.kjb.ums.KjbEmailSendModule; import com.eactive.ext.kjb.ums.KjbUmsService; import com.eactive.ext.kjb.utils.OsUtil; import lombok.extern.slf4j.Slf4j; @@ -65,31 +66,45 @@ public class UmsTest { "true".equalsIgnoreCase(System.getenv("KJB_EAPIM_TEST_ENABLED")), "OS 환경변수 내 KJB_EAPIM_TEST_ENABLED=TRUE 설정되어 있어야 동작함"); -// prop.setEaiBatchUrl("http://172.31.32.111:10230/BATAppWeb/EaiBatCall"); + prop.setEaiBatchUrl("http://172.31.32.111:10230/BATAppWeb/EaiBatCall"); prop.setEaiBatchUrl(""); prop.setUmsEaiBatchSendDir("c:\\kjb-logs\\sendmail\\snd"); prop.setUmsEaiBatchBackupDir("c:\\kjb-logs\\sendmail\\bak"); + prop.setUmsEaiBatchErrorDir("c:\\kjb-logs\\sendmail\\error"); prop.setUmsEaiBatchInterfaceId("UAGFF00001UIE"); - EmailSendModule service = EmailSendModule.getInstance(prop, null); + + System.getProperties().keySet().forEach(key -> { + log.info("{}: {}", key, System.getProperty((String) key)); + }); + + KjbEmailSendModule service = KjbEmailSendModule.getInstance(prop, null); MessageRequest messageRequest = new MessageRequest(); messageRequest.setId(UUID.randomUUID().toString()); messageRequest.setMessageCode(MessageCode.USER_VERIFICATION_EMAIL); messageRequest.setEmail("dearmai@dearmai.net"); messageRequest.setUsername("김광은"); messageRequest.setSubject("제목 - test"); - messageRequest.setMessage("내용 - test"); + messageRequest.setMessage("{\"ATHN_NO\": \"543216\"}"); + messageRequest.setServiceId("FM_APIM001"); + log.info("MessageRequest - {}", messageRequest); - CompletableFuture future = service.sendEmail(messageRequest, (result, ex) -> { - if (ex != null) { - log.error("failed", ex); - } else { - log.info("result: {}", result); - } - }); + try { + service.sendEmail(messageRequest); + } catch (KjbEaiBatchException e) { + throw new RuntimeException(e); + } - future.join(); +// CompletableFuture future = service.sendEmail(messageRequest, (result, ex) -> { +// if (ex != null) { +// log.error("failed", ex); +// } else { +// log.info("result: {}", result); +// } +// }); +// +// future.join(); log.info("done"); }