job = getJob(jobName);
return Assert.ifEmpty(job.get(key), () -> getDefault(key));
@@ -112,12 +147,28 @@ public class JobConf extends AbstractComponent {
return String.join(File.separator, str);
}
+ /**지정한 이름의 작업이 파일을 읽거나 쓰기 위한 최상위 디렉토리의 경로를 반환한다.
+ * @param jobName 작업 이름
+ * @param dir 디렉토리 종류
+ * - receive - 수신 파일 디렉토리
+ * - send - 전송 파일 디렉토리
+ *
+ * @return 파일을 읽거나 쓰기 위한 최상위 디렉토리
+ */
public String getDir(String jobName, String dir) {
String org = getJob(jobName).get("dirCode");
String code = getDirCode(org);
return path(getDir(dir), code);
}
+ /**지정한 이름의 작업이 작업 중 사용하는 디렉토리의 경로를 반환한다.
+ * @param jobName 작업 이름
+ * @param dir 디렉토리 종류
+ * - receive - 수신 파일 작업 디렉토리
+ * - send - 전송 파일 작업 디렉토리
+ *
+ * @return 작업 중 사용하는 디렉토리의 경로
+ */
public String getWorkingDir(String jobName, String dir) {
String org = getJob(jobName).get("dirCode");
String code = getDirCode(org);
@@ -127,6 +178,10 @@ public class JobConf extends AbstractComponent {
*/
}
+ /**지정한 이름의 작업이 성공한 파일을 위치할 디렉토리 경로를 반환한다.
+ * @param jobName 작업 이름
+ * @return 작업이 성공한 파일을 위치할 디렉토리 경로
+ */
public String getSuccessDir(String jobName) {
String org = getJob(jobName).get("dirCode");
String code = getDirCode(org);
@@ -136,6 +191,10 @@ public class JobConf extends AbstractComponent {
*/
}
+ /**지정한 이름의 작업이 실패한 파일을 위치할 디렉토리 경로를 반환한다.
+ * @param jobName 작업 이름
+ * @return 작업이 실패한 파일을 위치할 디렉토리 경로
+ */
public String getFailDir(String jobName) {
String org = getJob(jobName).get("dirCode");
String code = getDirCode(org);
diff --git a/src/main/java/cokr/xit/interfaces/filejob/package-info.java b/src/main/java/cokr/xit/interfaces/filejob/package-info.java
index ac406c7..0c1e682 100644
--- a/src/main/java/cokr/xit/interfaces/filejob/package-info.java
+++ b/src/main/java/cokr/xit/interfaces/filejob/package-info.java
@@ -1,3 +1,4 @@
-/**파일의 수신과 전송을 위한 작업의 설정을 지원하는 클래스를 정의한다.
+/**파일의 수신과 전송을 위한 작업을 지원하는 service와 bean 클래스를 정의한다.
+ * 파일 작업을 정의하는 클래스들은 작업에 필요한 정보를 {@link JobConf conf/file-job.conf}에 정의해야 한다.
*/
package cokr.xit.interfaces.filejob;
\ No newline at end of file
diff --git a/src/main/java/cokr/xit/interfaces/filejob/service/bean/FileJobBean.java b/src/main/java/cokr/xit/interfaces/filejob/service/bean/FileJobBean.java
index c7a4024..c72bfeb 100644
--- a/src/main/java/cokr/xit/interfaces/filejob/service/bean/FileJobBean.java
+++ b/src/main/java/cokr/xit/interfaces/filejob/service/bean/FileJobBean.java
@@ -4,16 +4,16 @@ import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
import cokr.xit.foundation.AbstractComponent;
import cokr.xit.interfaces.filejob.JobConf;
-/**파일 작업을 수행하는 클래스가 상속하는 베이스 클래스
+/**파일 작업을 수행하는 Bean이 상속하는 베이스 클래스
* @author mjkhan
*/
public abstract class FileJobBean extends AbstractComponent {
@@ -142,6 +142,12 @@ public abstract class FileJobBean extends AbstractComponent {
this.cause = rootCause(cause);
return setSuccess(this.cause == null);
}
+
+ public static List getPaths(List fileStatus) {
+ return !isEmpty(fileStatus) ?
+ fileStatus.stream().map(FileStatus::getPath).toList() :
+ Collections.emptyList();
+ }
}
/**수신 파일의 최상위 디렉토리 경로를 반환한다.
@@ -201,7 +207,7 @@ public abstract class FileJobBean extends AbstractComponent {
*/
protected List getFilePaths(String dir, Predicate filter) {
try (Stream walk = Files.list(Paths.get(dir))) {
- return walk.filter(ifEmpty(filter, path -> true)).collect(Collectors.toList());
+ return walk.filter(ifEmpty(filter, path -> true)).toList();
} catch (Exception e) {
throw runtimeException(e);
}
@@ -237,15 +243,19 @@ public abstract class FileJobBean extends AbstractComponent {
}
/**수신 디렉토리의 파일들을 작업 디렉토리로 이동하고, 경로를 반환한다.
+ * @param filter 작업 대상 파일에 적용할 필터. 지정하지 않으면 모든 파일을 이동한다.
* @return 수신 작업 디렉토리의 파일 경로 목록
*/
- protected List getReceivedFilePaths() {
+ protected List getReceivedFilePaths(Predicate filter) {
String receiveDir = receiveDir(),
workingDir = receiveWorkingDir();
+ Predicate test = ifEmpty(filter, Files::isRegularFile);
+
+ List paths = getFilePaths(receiveDir, test);
+ if (paths.isEmpty()) return Collections.emptyList();
- List paths = getFilePaths(receiveDir, Files::isRegularFile);
move(paths, workingDir);
- return getFilePaths(workingDir, null);
+ return getFilePaths(workingDir, test);
}
}
\ No newline at end of file
diff --git a/src/main/resources/conf/file-job.conf b/src/main/resources/conf/file-job.conf
new file mode 100644
index 0000000..e35b69c
--- /dev/null
+++ b/src/main/resources/conf/file-job.conf
@@ -0,0 +1,51 @@
+{
+ "dirs": {
+ "receive": "C:\\workspace\\ESB_AGENT\\RCV", /* 수신 파일 최상위 디렉토리 */
+ "send": "C:\\workspace\\ESB_AGENT\\SND", /* 전송 파일 최상위 디렉토리 */
+
+ "working": "C:\\workspace\\xit\\filesite\\work", /* 파일 작업 최상위 디렉토리 */
+ "success": "C:\\workspace\\xit\\filesite\\success", /* 작업 완료한 파일의 최상위 디렉토리 */
+ "fail": "C:\\workspace\\xit\\filesite\\fail" /* 작업 실패한 파일의 최상위 디렉토리 */
+ },
+
+ "dirCodes": {
+ "smg": "CG131000000768", /* 국민신문고 기관코드 */
+ "epost": "CG144523401150" /* epost 기관코드 */
+ },
+
+ "defaults": {
+ "charset": "euc-kr",
+ "fetchSize": 100
+ },
+
+ "jobs": [
+ { /* 국민신문고 수신 */
+ "name": "smg-in",
+ "dirCode": "smg", /* <-- dirCodes */
+ "infoType": "100",
+ "alert": "http://localhost:8080/xit-filegate/api/smg/petition/receive.do" /* 업무 통보 url */
+ },
+ { /* 국민신문고 전송 */
+ "name": "smg-out",
+ "dirCode": "smg", /* <-- dirCodes */
+ "alert": "http://localhost:8080/xit-filegate/api/smg/petition/reply.do" /* 업무 통보 url */
+ },
+
+ { /* epost 전자우편 신청 전송 */
+ "name": "epost-send-request",
+ "dirCode": "epost", /* <-- dirCodes */
+
+ "conOrg": "YICT", /* 외부기관 구분코드 */
+ "rceptId": "40219", /* 접수우체국 국기호 */
+ "attachmentDir": "", /* 원본 첨부파일 디렉토리 경로 */
+
+ "txtFilename": "POSDF5$send_{yyyyMMddHHmmssSSS}.txt",
+ "zipFilename": "POSDF5${conKey}.zip"
+ },
+
+ { /* epost 전자우편 신청 수신 결과 */
+ "name": "epost-receive-result",
+ "dirCode": "epost" /* <-- dirCodes */
+ }
+ ]
+}
\ No newline at end of file