diff --git a/src/main/java/com/munjaon/server/queue/config/QueueHeaderConfig.java b/src/main/java/com/munjaon/server/queue/config/QueueHeaderConfig.java new file mode 100644 index 0000000..9ae006c --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/config/QueueHeaderConfig.java @@ -0,0 +1,14 @@ +package com.munjaon.server.queue.config; + +public final class QueueHeaderConfig { + /** Queue File Header Length - [Create Date:10 Byte, Push Count:10 Byte] */ + public static final int QUEUE_HEADER_LENGTH = 20; + /* 큐생성일 읽을 위치값 */ + public static final int CREATE_DATE_POSITION = 0; + /* 큐생성일 읽을 크기 */ + public static final int CREATE_DATE_LENGTH = 10; + /* 큐 쓰기 카운트 읽을 위치값 */ + public static final int PUSH_COUNT_POSITION = 10; + /* 큐 쓰기 카운트 읽을 크기 */ + public static final int PUSH_COUNT_LENGTH = 10; +} diff --git a/src/main/java/com/munjaon/server/queue/dto/LmsMessageDto.java b/src/main/java/com/munjaon/server/queue/dto/LmsMessageDto.java new file mode 100644 index 0000000..9ed0fc3 --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/dto/LmsMessageDto.java @@ -0,0 +1,12 @@ +package com.munjaon.server.queue.dto; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class LmsMessageDto extends BasicMessageDto { + private String userSubject = ""; +} diff --git a/src/main/java/com/munjaon/server/queue/dto/QueueInfo.java b/src/main/java/com/munjaon/server/queue/dto/QueueInfo.java new file mode 100644 index 0000000..5b0e1ed --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/dto/QueueInfo.java @@ -0,0 +1,16 @@ +package com.munjaon.server.queue.dto; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class QueueInfo { + private String queueName = ""; + private String queueFileName = ""; + private int queueDataLength = 0; + private String serviceType = ""; + private String readXMLFileName = ""; +} diff --git a/src/main/java/com/munjaon/server/queue/service/KakaoWriteQueue.java b/src/main/java/com/munjaon/server/queue/service/KakaoWriteQueue.java new file mode 100644 index 0000000..f527906 --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/service/KakaoWriteQueue.java @@ -0,0 +1,9 @@ +package com.munjaon.server.queue.service; + +import com.munjaon.server.queue.dto.KakaoMessageDto; + +public class KakaoWriteQueue extends WriteQueue { + public void pushBuffer(KakaoMessageDto data) throws Exception { + + } +} diff --git a/src/main/java/com/munjaon/server/queue/service/LmsWriteQueue.java b/src/main/java/com/munjaon/server/queue/service/LmsWriteQueue.java new file mode 100644 index 0000000..010c1f6 --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/service/LmsWriteQueue.java @@ -0,0 +1,9 @@ +package com.munjaon.server.queue.service; + +import com.munjaon.server.queue.dto.LmsMessageDto; + +public class LmsWriteQueue extends WriteQueue { + public void pushBuffer(LmsMessageDto data) throws Exception { + + } +} diff --git a/src/main/java/com/munjaon/server/queue/service/MmsWriteQueue.java b/src/main/java/com/munjaon/server/queue/service/MmsWriteQueue.java new file mode 100644 index 0000000..647f4ed --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/service/MmsWriteQueue.java @@ -0,0 +1,9 @@ +package com.munjaon.server.queue.service; + +import com.munjaon.server.queue.dto.MmsMessageDto; + +public class MmsWriteQueue extends WriteQueue { + public void pushBuffer(MmsMessageDto data) throws Exception { + + } +} diff --git a/src/main/java/com/munjaon/server/queue/service/SmsWriteQueue.java b/src/main/java/com/munjaon/server/queue/service/SmsWriteQueue.java new file mode 100644 index 0000000..c940623 --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/service/SmsWriteQueue.java @@ -0,0 +1,9 @@ +package com.munjaon.server.queue.service; + +import com.munjaon.server.queue.dto.BasicMessageDto; + +public class SmsWriteQueue extends WriteQueue { + public void pushBuffer(BasicMessageDto data) throws Exception { + + } +} diff --git a/src/main/java/com/munjaon/server/queue/service/WriteQueue.java b/src/main/java/com/munjaon/server/queue/service/WriteQueue.java new file mode 100644 index 0000000..4ea3002 --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/service/WriteQueue.java @@ -0,0 +1,131 @@ +package com.munjaon.server.queue.service; + +import com.munjaon.server.queue.config.QueueConstants; +import com.munjaon.server.queue.config.QueueHeaderConfig; +import com.munjaon.server.queue.dto.QueueInfo; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public abstract class WriteQueue { + /** Queue Header Size - [Create Date:10 Byte, Push Count:10 Byte] */ + protected static final int QUEUE_HEADER_LENGTH = 20; + /** Queue Create Date - [Format:YYYYMMDD] */ + protected String createDate = ""; + /** Queue Push Counter */ + protected int pushCounter = 0; + /** Queue Header Buffer */ + protected ByteBuffer headerBuffer = null; + /** Queue Information */ + protected QueueInfo queueInfo = null; + /** Queue File Channel */ + protected FileChannel channel = null; + /** Header 에서 사용하는 변수 */ + protected byte[] headerArray = null; + /** pushBuffer() 함수에서 사용하는 변수 */ + protected ByteBuffer dataBuffer = null; + + protected void initQueue() throws Exception { + this.headerBuffer = ByteBuffer.allocateDirect(QueueHeaderConfig.QUEUE_HEADER_LENGTH); + try{ + File file = new File(this.queueInfo.getQueueFileName()); + this.channel = new RandomAccessFile(file, "rw").getChannel(); + //this.lock = this.channel.lock(); + + if(file.length() == 0) { + // Push 및 Pop 카운트 초기화 + this.createDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + this.pushCounter = 0; + // 헤더 초기화 + writeHeader(); + }else{ + readHeader(); + } + }catch(Exception e){ + throw e; + } finally { + //lock.release(); + } + } + + public void readHeader() throws Exception { + try { + initHeaderBuffer(); + this.channel.position(0); + this.channel.read(this.headerBuffer); + this.headerArray = new byte[10]; + // 생성날짜 가져오기 - 생성날짜(10) / 읽은카운트(10) / 쓴카운트(10) + this.headerBuffer.position(0); + this.headerBuffer.get(this.headerArray); + this.createDate = (new String(this.headerArray)).trim(); + // 쓴 카운트 가져오기 + this.headerArray = new byte[10]; + this.headerBuffer.position(10); + this.headerBuffer.get(this.headerArray); + this.pushCounter = Integer.parseInt((new String(this.headerArray)).trim()); + } catch(Exception e) { + throw e; + } + } + + public void writeHeader() throws Exception { + try { + initHeaderBuffer(); + this.channel.position(0); + this.headerBuffer.put(this.createDate.getBytes()); + this.headerBuffer.position(10); + this.headerBuffer.put(Integer.toString(this.pushCounter).getBytes()); + this.headerBuffer.flip(); + this.channel.write(this.headerBuffer); + } catch(Exception e) { + throw e; + } + } + + public void initHeaderBuffer(){ + this.headerBuffer.clear(); + for(int loopCnt = 0; loopCnt < QueueHeaderConfig.QUEUE_HEADER_LENGTH; loopCnt++){ + this.headerBuffer.put(QueueConstants.SET_DEFAULT_BYTE); + } + this.headerBuffer.position(0); + } + + public void close() throws IOException { + try { + if(channel != null && channel.isOpen()) { + channel.close(); + } + } catch(IOException e) { + throw e; + } + } + + public void truncateQueue() throws Exception{ + try { + //this.lock = this.channel.lock(); + + if(channel != null && channel.isOpen()) { + // 헤더정보 읽기 + readHeader(); + String thisDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + // 날짜가 지난경우와 더이상 읽을 데이터가 없을 경우 큐를 초기화 + if((this.createDate.equals(thisDate) == false)){ + // 파일 내용을 모두 지운다. + channel.truncate(0); + // 헤더 정보를 초기화한다. + this.createDate = thisDate; + this.pushCounter = 0; + // 헤더에 초기데이터를 저장 + writeHeader(); + } + } + } catch(Exception e) { + throw e; + } + } +} diff --git a/src/main/java/com/munjaon/server/util/JobFileFactory.java b/src/main/java/com/munjaon/server/util/JobFileFactory.java new file mode 100644 index 0000000..320303c --- /dev/null +++ b/src/main/java/com/munjaon/server/util/JobFileFactory.java @@ -0,0 +1,474 @@ +package com.munjaon.server.util; + +import com.munjaon.server.util.dto.FileBaseDto; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public final class JobFileFactory { + public static final Long MAX_LIMIT_BYTES = 10485760L; + /** + * 파일 관련 : 파일 객체 반환 : 디렉토리 경로 포함 + * @param path + * @return + */ + public static File getFile(final String path) { + if (path == null) { + return null; + } + + return new File(path); + } + + /** + * 파일 관련 : 파일 객체 반환 : 경로, 파일명 + * @param path + * @param fileName + * @return + */ + public static File getFile(final String path, final String fileName) { + return getFile(path + File.separator + fileName); + } + + /** + * 파일관련 : 파일 존재 여부 + * @param file + * @return + */ + private static boolean exist(final File file) { + return file.exists(); + } + + /** + * 파일관련 : 파일 존재 여부 + * @param path + * @return + */ + public static boolean exist(final String path) { + if (path == null) { + return false; + } + log.info("path : {}", path); + return new File(path).exists(); + } + + /** + * 파일관련 : 파일 존재 여부 + * @param path + * @param fileName + * @return + */ + public static boolean exist(final String path, final String fileName) { + return exist(path + File.separator + fileName); + } + + /** + * 파일관련 : 디렉토리 여부 + * @param path + * @param fileName + * @return + */ + public static boolean isDirectory(final String path, final String fileName) { + return getFile(path, fileName).isDirectory(); + } + + /** + * 파일관련 : 디렉토리 여부 + * @param path + * @return + */ + public static boolean isDirectory(final String path) { + return getFile(path).isDirectory(); + } + + /** + * 파일관련 : 디렉토리 여부 + * @param file + * @return + */ + public static boolean isDirectory(final File file) { + return file.isDirectory(); + } + + /** + * 파일관련 : 파일 여부 + * @param path + * @param fileName + * @return + */ + public static boolean isFile(final String path, final String fileName) { + return getFile(path, fileName).isFile(); + } + + /** + * 파일관련 : 파일 여부 + * @param path + * @return + */ + public static boolean isFile(final String path) { + return getFile(path).isFile(); + } + + /** + * 파일관련 : 파일 여부 + * @param file + * @return + */ + public static boolean isFile(final File file) { + return file.isFile(); + } + + /** + * 파일관련 : 파일, 디렉토리 삭제 + * @param path + * @param fileName + * @return + */ + public static boolean deleteFile(final String path, final String fileName) { + return getFile(path, fileName).delete(); + } + + /** + * 파일관련 : 파일, 디렉토리 삭제 + * @param path + * @return + */ + public static boolean deleteFile(final String path) { + return getFile(path).delete(); + } + + /** + * 파일관련 : 파일, 디렉토리 삭제 + * @param file + * @return + */ + public static boolean deleteFile(final File file) { + return file.delete(); + } + + /** + * 파일관련 : 파일 크기 + * @param path + * @param fileName + * @return + */ + public static long fileSize(final String path, final String fileName) { + return getFile(path, fileName).length(); + } + + /** + * 파일관련 : 파일 크기 + * @param path + * @return + */ + public static long fileSize(final String path) { + return getFile(path).length(); + } + + /** + * 파일관련 : 파일 크기 + * @param file + * @return + */ + public static long fileSize(final File file) { + return file.length(); + } + + /** + * 파일관련 : 다중 디렉토리 생성 + * @param dirs + * @return + */ + public static boolean makeMultiDirectory(final String dirs) { + return getFile(dirs).mkdirs(); + } + + /** + * 파일관련 : 디렉토리 생성 + * @param dir + * @return + */ + public static boolean makeDirectory(final String dir) { + return getFile(dir).mkdir(); + } + + /** + * 파일관련 : 파일 확장자 추출 + * @param fileName + * @return + */ + public static String getExtension(final String fileName) { + if (fileName == null) { + return null; + } + if (fileName.lastIndexOf(".") >= 0) { + return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); + } + + return null; + } + + /** + * 파일관련 : 파일 확장자 추출 + * @param file + * @return + */ + public static String getExtension(final File file) { + return getExtension(file.getName()); + } + + /** + * 파일관련 : 파일 명 추출 + * @param fileName + * @return + */ + public static String getFileName(final String fileName) { + if (fileName == null) { + return null; + } + if (fileName.lastIndexOf(".") >= 0) { + return fileName.substring(0, fileName.lastIndexOf(".")); + } + + return fileName; + } + + /** + * 파일관련 : 파일 명 추출 + * @param file + * @return + */ + public static String getFileName(final File file) { + return getFileName(file.getName()); + } + + /** + * 파일관련 : 저장 파일 명 생성 + * @param fileName + * @return + */ + public static String getSaveFileName(final String fileName) { + if (fileName != null && fileName.lastIndexOf(".") >= 0) { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + SerialNoUtil.getMultiAlphabet(3) + SerialNoUtil.getMultiNumeric(3) + SerialNoUtil.getMultiAlphabet(3) + SerialNoUtil.getMultiNumeric(7) + "." + getExtension(fileName); + } + + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + SerialNoUtil.getMultiAlphabet(3) + SerialNoUtil.getMultiNumeric(3) + SerialNoUtil.getMultiAlphabet(3) + SerialNoUtil.getMultiNumeric(7); + } + + /** + * 파일관련 : 저장 파일 명 생성 + * @param file + * @return + */ + public static String getSaveFileName(final File file) { + return getSaveFileName(file.getName()); + } + + /** + * 파일관련 : 파일 복사 + * @param srcDir + * @param srcFileName + * @param destDir + * @return + * @throws IOException + */ + public static boolean transferFile(final String srcDir, final String srcFileName, final String destDir) throws IOException { + return transferFile(srcDir, srcFileName, destDir, srcFileName); + } + + /** + * 파일관련 : 파일 복사 + * @param srcDir + * @param srcFileName + * @param destDir + * @param destFileName + * @return + * @throws IOException + */ + public static boolean transferFile(final String srcDir, final String srcFileName, final String destDir, final String destFileName) throws IOException { + if (exist(srcDir + File.separator + srcFileName)) { + if (exist(destDir) == false) { + makeMultiDirectory(destDir); + } + + return transferFile(srcDir + File.separator + srcFileName, destDir + File.separator + destFileName); + } + + return false; + } + + /** + * 파일관련 : 파일 복사 + * @param srcPath + * @param destPath + * @return + * @throws IOException + */ + public static boolean transferFile(final String srcPath, final String destPath) throws IOException { + return transferFile(new File(srcPath), new File(destPath)); + } + + /** + * 파일관련 : 파일 복사 + * @param srcFile + * @param destFile + * @return + * @throws IOException + */ + public static boolean transferFile(final File srcFile, final File destFile) throws IOException { + log.info("srcFile : {}", srcFile); + log.info("destFile : {}", destFile); + FileInputStream fis = new FileInputStream(srcFile); + FileOutputStream fos = new FileOutputStream(destFile); + + FileChannel inputChannel = fis.getChannel(); + FileChannel outputChannel = fos.getChannel(); + + boolean transferStatus = false; + if (inputChannel.size() > 0) { + transferStatus = true; + inputChannel.transferTo(0, inputChannel.size(), outputChannel); + } + + fis.close(); + fos.close(); + + return transferStatus; + } + + public static String getJobDirectory(final String rootDirectory, final String orderNo, final String companyNo, final String date) { + return rootDirectory + File.separator + orderNo + File.separator + orderNo + "_" + companyNo + File.separator + date; + } + + /** + * 파일관련 : 다중 파일 업로드 + * @param path + * @param listMultipartFile + * @return + * @throws IOException + */ + public static List uploadMultiFile(final String path, final List listMultipartFile) throws IOException { + return uploadMultiFileEnableExtension(path, listMultipartFile, null); + } + + /** + * 파일관련 : 다중 파일 업로드 : 허용 확장자 + * @param path + * @param listMultipartFile + * @param listEnableExtension + * @return + * @throws IOException + */ + public static List uploadMultiFileEnableExtension(final String path, final List listMultipartFile, final String[] listEnableExtension) throws IOException { + if (listMultipartFile == null || listMultipartFile.size() == 0) { + return null; + } + + List listFile = null; + for (MultipartFile multipartFile : listMultipartFile) { + if (multipartFile.isEmpty()) { + continue; + } + + FileBaseDto fileBaseDto = uploadFileEnableExtension(path, multipartFile, listEnableExtension); + if (fileBaseDto != null) { + if (listFile == null) { + listFile = new ArrayList<>(); + } + listFile.add(fileBaseDto); + } + } + return listFile; + } + + /** + * 파일관련 : 파일 업로드 + * @param path + * @param multipartFile + * @return + * @throws IOException + */ + public static FileBaseDto uploadFile(final String path, final MultipartFile multipartFile) throws IOException { + return uploadFileEnableExtension(path, multipartFile, null); + } + + /** + * 파일관련 : 파일 업로드 : 허용 확장자 + * @param path + * @param multipartFile + * @param listEnableExtension + * @return + * @throws IOException + */ + public static FileBaseDto uploadFileEnableExtension(final String path, final MultipartFile multipartFile, final String[] listEnableExtension) throws IOException { + if (multipartFile == null || multipartFile.isEmpty()) { + return null; + } + if (exist(path) == false) { + makeMultiDirectory(path); + } + + boolean enableUpload = true; + if (listEnableExtension != null && listEnableExtension.length > 0) { + enableUpload = false; // 가능한 확장자를 만나면 다시 true + String extension = getExtension(multipartFile.getOriginalFilename()); + if (extension != null) { + for (String enableExtension : listEnableExtension) { + if (extension.equals(enableExtension)) { + enableUpload = true; + break; + } + } + } + } + + FileBaseDto fileBaseDto = null; + if (enableUpload) { + fileBaseDto = new FileBaseDto(); + fileBaseDto.setOriginFileName(multipartFile.getOriginalFilename()); + fileBaseDto.setSaveFileName(getSaveFileName(multipartFile.getOriginalFilename())); + fileBaseDto.setFileSize(multipartFile.getSize()); + + String uploadPath = path + File.separator + fileBaseDto.getSaveFileName(); + File uploadFile = new File(uploadPath); + multipartFile.transferTo(uploadFile); + } + + return fileBaseDto; + } + + public static Long uploadFileSize(final MultipartFile multipartFile) { + if (multipartFile == null || multipartFile.isEmpty()) { + return -1L; + } + + return multipartFile.getSize(); + } + /* */ + public static void main(String[] args) throws IOException { + System.out.println(); +// File file = new File("d:\\example\\image.jpg"); +// long bytes = file.length(); +// long kilobyte = bytes / 1024; +// long megabyte = kilobyte / 1024; +// System.out.println(bytes + " byte"); // 3980059 byte System.out.println(kilobyte + " kb"); // 3886 kb System.out.println(megabyte + " mb"); // 3 mb +// File file = new File("c:\\example\\new_directory\\test.txt"); +// boolean directoryCreated = file.mkdirs(); + System.out.println("ext : " + JobFileFactory.getExtension("test")); + System.out.println("name : " + JobFileFactory.getFileName("test")); + System.out.println("name : " + JobFileFactory.getSaveFileName("test.txt")); + System.out.println("exist : " + JobFileFactory.exist("C:\\uploads\\20231129\\30e718ce1445499a9ef1c4929310c87f.xlsx")); + System.out.println("Now : " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))); +// System.out.println("transfer : " + JobFileFactory.transferFile("C:\\Docs", "test.txt", "C:\\Docs", "test2.txt")); + } +} diff --git a/src/main/java/com/munjaon/server/util/SerialNoUtil.java b/src/main/java/com/munjaon/server/util/SerialNoUtil.java new file mode 100644 index 0000000..9f7717a --- /dev/null +++ b/src/main/java/com/munjaon/server/util/SerialNoUtil.java @@ -0,0 +1,43 @@ +package com.munjaon.server.util; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public final class SerialNoUtil { + public static String getSerialNo() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + getMultiAlphabet(3) + getMultiNumeric(3) + getMultiAlphabet(2) + getMultiNumeric(6); + } + + public static String getMultiAlphabet(final int count) { + if (count <= 0) { + return String.valueOf((char) ((Math.random() * 26) + 65)); + } + + StringBuilder retValue = new StringBuilder(); + for (int i = 0; i < count; i++) { + retValue.append((char) ((Math.random() * 26) + 65)); + } + + return retValue.toString(); + } + + public static String getMultiNumeric(final int count) { + if (count <= 0) { + return String.valueOf((int) (Math.random() * 10)); + } + + StringBuilder retValue = new StringBuilder(); + for (int i = 0; i < count; i++) { + retValue.append((int) (Math.random() * 10)); + } + + return retValue.toString(); + } + + public static String getNumber(String str) { + if (str == null) { + return null; + } + return str.replaceAll("[^0-9]",""); + } +} diff --git a/src/main/java/com/munjaon/server/util/dto/FileBaseDto.java b/src/main/java/com/munjaon/server/util/dto/FileBaseDto.java new file mode 100644 index 0000000..e0a384c --- /dev/null +++ b/src/main/java/com/munjaon/server/util/dto/FileBaseDto.java @@ -0,0 +1,15 @@ +package com.munjaon.server.util.dto; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class FileBaseDto { + protected String originFileName; // 원본 파일명 + protected String saveFileName; // 저장 파일명 + protected long fileSize; // 파일 크기 + protected String createdDt; +}