feat : xml파일 백업 완료

todo : 디비 맵핑 후 폴링
master
Kurt92 6 months ago
parent ddda6b4ca9
commit 610f1d9fb5

@ -2,10 +2,14 @@ package com.worker.scheduler.smg;
import com.worker.dto.SinmungoDto;
import com.worker.entity.*;
import com.worker.util.fileReader.XmlParserInterface;
import com.worker.util.fileReader.XmlReader;
import com.worker.util.fileReader.impl.SinmungoXmlParser;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -14,6 +18,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@ -22,6 +27,8 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
@Slf4j
public class SinmungoInOutScheduler {
private final Environment env;
private final CpMainRepository cpMainRepository;
private final CpSetinfoRepository cpSetinfoRepository;
@ -32,19 +39,21 @@ public class SinmungoInOutScheduler {
@Transactional
public void sinmungoInOutScheduler() throws IOException {
//setinfo 테이블에서 esb에이전트 정보 조회
System.out.println(env.getProperty("esb.info.xmlDir.codeName"));
Optional<CpSetinfo> esbXmlDir = cpSetinfoRepository.findById(
CpSetinfoId.builder()
.codeName("국민신문고")
.groupCode("정보")
.detailCode("test")
.codeName(env.getProperty("esb.info.xmlDir.code"))
.groupCode(env.getProperty("esb.info.xmlDir.groupCode"))
.detailCode(env.getProperty("esb.info.xmlDir.detailCode"))
.build()
);
Optional<CpSetinfo> esbBackupDir = cpSetinfoRepository.findById(
CpSetinfoId.builder()
.codeName("SERVER_INFO")
.groupCode("DIRECTORY")
.detailCode("IMAGEtest")
.codeName(env.getProperty("esb.info.backupDir.codeName"))
.groupCode(env.getProperty("esb.info.backupDir.groupCode"))
.detailCode(env.getProperty("esb.info.backupDir.detailCode"))
.build()
);
@ -54,11 +63,12 @@ public class SinmungoInOutScheduler {
// 백업 디렉토리
Path localImgPath = Paths.get(esbBackupDir.get().getStrValue1()); //img
// StrValue2에 신문고xml 백업하는 디렉토리 넣으면 될듯.
Path localXmlPath = Paths.get(esbBackupDir.get().getStrValue2()); //sinmungo path 는 하드코딩 되어있었음
//파일읽기
List<SinmungoDto.ParseResult> parseResult = xmlReader.findXml(esbXmlDir.get().getStrValue4());
log.info(parseResult.toString());
XmlParserInterface<SinmungoDto.ParseResult> parser = new SinmungoXmlParser();
List<SinmungoDto.ParseResult> parseResult = xmlReader.readXmlFiles(esbXmlDir.get().getStrValue4(), parser);
// cpMain만 추출
List<CpMain> cpMainList = parseResult.stream()
@ -70,7 +80,8 @@ public class SinmungoInOutScheduler {
// 파일백업으로 이동
// xml은 HP_ROOT/PROGRAM/BATCH/sinmungo 로 백업?
// xml안에 있던 이미지 바이너리는 HP_ROOT/DATA/IMAGE/${담당자번호?}/2025 로 백업?
Files.move(esbRcvPath, localXmlPath, StandardCopyOption.REPLACE_EXISTING);
// esb에이전트 xml 파일 백업
xmlReader.xmlFileBackup(esbRcvPath, localXmlPath);
List<SinmungoDto.ImgParser> imgParsers = parseResult.stream()
.flatMap(result -> result.getImgParsers().stream())
.collect(Collectors.toList());
@ -84,6 +95,13 @@ public class SinmungoInOutScheduler {
}
// esb 에이전트 답변 보내기
public void sinmungoAnswerSendScheduler() {
}
}

@ -0,0 +1,9 @@
package com.worker.util.fileReader;
import java.io.File;
public interface XmlParserInterface<T> {
T parse(File file) throws Exception;
}

@ -16,92 +16,59 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.stream.Stream;
@Component
@Slf4j
public class XmlReader {
public List<SinmungoDto.ParseResult> findXml(String dirPath) {
public <T> List<T> readXmlFiles(String dirPath, XmlParserInterface<T> parser) {
File dir = new File(dirPath);
List<SinmungoDto.ParseResult> result = new ArrayList<>();
File[] files = dir.listFiles((d, name) -> name.endsWith(".xml"));
List<T> result = new ArrayList<>();
if (!dir.exists() || !dir.isDirectory()) {
log.info(" 디렉토리 경로 없음: " + dirPath);
return null;
}
File[] xmlFiles = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".xml"));
if (xmlFiles == null || xmlFiles.length == 0) {
log.info(" XML 파일 없음: " + dirPath);
return null;
if (files != null) {
for (File file : files) {
try {
// XmlParser를 통해 호출 리스트에 add
result.add(parser.parse(file));
} catch (Exception e) {
System.err.println("파싱 실패: " + file.getName());
e.printStackTrace();
}
}
}
for (File xmlFile : xmlFiles) {
log.info(" 파일 파싱 중: " + xmlFile.getName());
result.add(parseXml(xmlFile));
}
log.info(result.toString());
return result;
}
private SinmungoDto.ParseResult parseXml(File xmlFile) {
public void xmlFileBackup(Path esbRcvPath, Path localXmlPath) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlFile);
doc.getDocumentElement().normalize();
List<SinmungoDto.ImgParser> imgBinary = new ArrayList<>();
Element root = doc.getDocumentElement();
NodeList apndfilinfoList = root.getElementsByTagName("apndfilinfo");
if (apndfilinfoList.getLength() > 0) {
Element apndfilinfo = (Element) apndfilinfoList.item(0);
for (int i = 1; i <= 4; i++) {
String fileTag = "peti_file_path" + i + "_v";
String dataTag = "apndfilcont" + i;
String fileName = getTagValue(fileTag, apndfilinfo);
String base64Data = getTagValue(dataTag, apndfilinfo);
if (fileName != null && base64Data != null && !base64Data.isEmpty()) {
byte[] decoded = Base64.getDecoder().decode(base64Data);
if (!Files.exists(localXmlPath)) {
Files.createDirectories(localXmlPath); // 백업 디렉토리가 없으면 생성
}
imgBinary.add(SinmungoDto.ImgParser.builder()
.fileName(fileName)
.imageBytes(decoded)
.build());
try (Stream<Path> files = Files.list(esbRcvPath)) {
for (Path file : files.toList()) {
if (Files.isRegularFile(file)) {
Path target = localXmlPath.resolve(file.getFileName());
Files.move(file, target, StandardCopyOption.REPLACE_EXISTING);
log.info("파일 이동: {} → {}", file, target);
}
}
}
return SinmungoDto.ParseResult.builder()
.cpMain(
CpMain.builder()
.mmSgnm(getTagValue("peter_name_v", root))
.mmSgtel(getTagValue("duty_id_v", root))
.mmCarno(getTagValue("carno", root))
.mmSgcont(getTagValue("text", root))
.build()
)
.imgParsers(imgBinary)
.build();
} catch (Exception e) {
System.out.println("파싱 실패: " + xmlFile.getName());
e.printStackTrace();
return null;
} catch (IOException e) {
log.error("XML 백업 중 예외 발생 (from: {}, to: {}):", esbRcvPath, localXmlPath, e);
throw new RuntimeException("백업 실패", e); // 또는 상황에 맞는 예외처리
}
}
public void imgLocalSave(Path localImgPath, List<SinmungoDto.ImgParser> imgParsers) {
for (SinmungoDto.ImgParser img : imgParsers) {
if (img.getFileName() != null && img.getImageBytes() != null) {
@ -117,12 +84,4 @@ public class XmlReader {
}
}
private String getTagValue(String tag, Element element) {
NodeList nodeList = element.getElementsByTagName(tag);
if (nodeList != null && nodeList.getLength() > 0) {
Node node = nodeList.item(0);
return node != null ? node.getTextContent() : "";
}
return "";
}
}

@ -0,0 +1,4 @@
package com.worker.util.fileReader.impl;
public class EpostXmlParser {
}

@ -0,0 +1,68 @@
package com.worker.util.fileReader.impl;
import com.worker.dto.SinmungoDto;
import com.worker.entity.CpMain;
import com.worker.util.fileReader.XmlParserInterface;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
@Component
public class SinmungoXmlParser implements XmlParserInterface<SinmungoDto.ParseResult> {
@Override
public SinmungoDto.ParseResult parse(File file) throws Exception {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
Element root = doc.getDocumentElement();
return SinmungoDto.ParseResult.builder()
.cpMain(CpMain.builder()
.mmSgnm(getTagValue("peter_name_v", root))
.mmSgtel(getTagValue("duty_id_v", root))
.mmCarno(getTagValue("carno", root))
.build())
// getImg 매서드로 바이너리 객체화
.imgParsers(getImg(root))
.build();
}
private List<SinmungoDto.ImgParser> getImg(Element root) {
List<SinmungoDto.ImgParser> imgBinary = new ArrayList<>();
NodeList apndfilinfoList = root.getElementsByTagName("apndfilinfo");
if (apndfilinfoList.getLength() > 0) {
Element apndfilinfo = (Element) apndfilinfoList.item(0);
for (int i = 1; i <= 4; i++) {
String fileTag = "peti_file_path" + i + "_v";
String dataTag = "apndfilcont" + i;
String fileName = getTagValue(fileTag, apndfilinfo);
String base64Data = getTagValue(dataTag, apndfilinfo);
if (fileName != null && base64Data != null && !base64Data.isEmpty()) {
byte[] decoded = Base64.getDecoder().decode(base64Data);
imgBinary.add(SinmungoDto.ImgParser.builder()
.fileName(fileName)
.imageBytes(decoded)
.build());
}
}
}
return imgBinary;
}
private String getTagValue(String tag, Element element) {
NodeList nodeList = element.getElementsByTagName(tag);
return nodeList.getLength() > 0 ? nodeList.item(0).getTextContent() : "";
}
}

@ -17,7 +17,16 @@ spring:
format_sql: true
dialect: org.hibernate.dialect.MySQLDialect
esb:
info:
xmlDir:
codeName: 국민신문고
groupCode: 정보
detailCode: test
backupDir:
codeName: SERVER_INFO
groupCode: DIRECTORY
detailCode: IMAGEtest
logging:
level:

@ -18,7 +18,16 @@ spring:
format_sql: true
dialect: org.hibernate.dialect.MySQLDialect
esb:
info:
xmlDir:
codeName: 국민신문고
groupCode: 정보
detailCode: 1
backupDir:
codeName: SERVER_INFO
groupCode: DIRECTORY
detailCode: IMAGE
logging:

Loading…
Cancel
Save