diff --git a/src/main/java/com/munjaon/server/config/RunnerConfiguration.java b/src/main/java/com/munjaon/server/config/RunnerConfiguration.java index ab11b46..359f8af 100644 --- a/src/main/java/com/munjaon/server/config/RunnerConfiguration.java +++ b/src/main/java/com/munjaon/server/config/RunnerConfiguration.java @@ -6,7 +6,6 @@ import com.munjaon.server.server.service.*; import com.munjaon.server.util.ServiceUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.configuration2.ex.ConfigurationException; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -24,16 +23,16 @@ public class RunnerConfiguration { System.setProperty("PROPS", serverConfig.getServerProperyFile()); System.setProperty("ROOTPATH", serverConfig.getServerRootPath()); PropertyLoader.load(); + + /* Serial queue 초기화 */ + SerialQueuePool queueInstance = SerialQueuePool.getInstance(); try { - String[] array = serverConfig.getStringArray("test.list"); - if (array != null && array.length > 0) { - for (String s : array) { - System.out.println("List : " + s); - } - } - } catch (ConfigurationException e) { - throw new RuntimeException(e); + SerialQueue serialQueue = new SerialQueue(); + queueInstance.setSerialQueue(serialQueue); + } catch (Exception e) { + e.printStackTrace(); } + return args -> System.out.println("Runner Bean #1 : " + serverConfig.getServerProperyFile()); } @@ -180,8 +179,8 @@ public class RunnerConfiguration { String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); - CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); - collectServerService.start(); + CollectServer collectServer = new CollectServer(serviceName, serviceType, port); + collectServer.start(); } catch (Exception e) { throw new RuntimeException(e); } @@ -196,8 +195,8 @@ public class RunnerConfiguration { String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); - CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); - collectServerService.start(); + CollectServer collectServer = new CollectServer(serviceName, serviceType, port); + collectServer.start(); } catch (Exception e) { throw new RuntimeException(e); } @@ -212,8 +211,8 @@ public class RunnerConfiguration { String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); - CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); - collectServerService.start(); + CollectServer collectServer = new CollectServer(serviceName, serviceType, port); + collectServer.start(); } catch (Exception e) { throw new RuntimeException(e); } @@ -228,8 +227,8 @@ public class RunnerConfiguration { String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); - CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); - collectServerService.start(); + CollectServer collectServer = new CollectServer(serviceName, serviceType, port); + collectServer.start(); } catch (Exception e) { throw new RuntimeException(e); } @@ -244,8 +243,8 @@ public class RunnerConfiguration { String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); - CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); - collectServerService.start(); + CollectServer collectServer = new CollectServer(serviceName, serviceType, port); + collectServer.start(); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/com/munjaon/server/queue/enums/QueueTypeWorker.java b/src/main/java/com/munjaon/server/queue/enums/QueueTypeWorker.java index a93a13f..b28ab76 100644 --- a/src/main/java/com/munjaon/server/queue/enums/QueueTypeWorker.java +++ b/src/main/java/com/munjaon/server/queue/enums/QueueTypeWorker.java @@ -6,6 +6,7 @@ import com.munjaon.server.queue.service.*; import lombok.Getter; import java.util.EnumSet; +import java.util.List; @Getter public enum QueueTypeWorker { @@ -46,6 +47,12 @@ public enum QueueTypeWorker { return smsQueueService.saveMessageToTable(data); } + @Override + public int saveMessageForList(List list) { + SmsQueueService smsQueueService = (SmsQueueService) QueueService.SMS_QUEUE_SERVICE.getService(); + return smsQueueService.saveMessageForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { SmsQueueService smsQueueService = (SmsQueueService) QueueService.SMS_QUEUE_SERVICE.getService(); @@ -107,6 +114,12 @@ public enum QueueTypeWorker { return lmsQueueService.saveMessageToTable(data); } + @Override + public int saveMessageForList(List list) { + LmsQueueService lmsQueueService = (LmsQueueService) QueueService.LMS_QUEUE_SERVICE.getService(); + return lmsQueueService.saveMessageForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { LmsQueueService lmsQueueService = (LmsQueueService) QueueService.LMS_QUEUE_SERVICE.getService(); @@ -168,6 +181,12 @@ public enum QueueTypeWorker { return mmsQueueService.saveMessageToTable(data); } + @Override + public int saveMessageForList(List list) { + MmsQueueService mmsQueueService = (MmsQueueService) QueueService.MMS_QUEUE_SERVICE.getService(); + return mmsQueueService.saveMessageForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { MmsQueueService mmsQueueService = (MmsQueueService) QueueService.MMS_QUEUE_SERVICE.getService(); @@ -229,6 +248,12 @@ public enum QueueTypeWorker { return kakaoAlarmQueueService.saveMessageToTable(data); } + @Override + public int saveMessageForList(List list) { + KakaoAlarmQueueService kakaoAlarmQueueService = (KakaoAlarmQueueService) QueueService.KAT_QUEUE_SERVICE.getService(); + return kakaoAlarmQueueService.saveMessageForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { KakaoAlarmQueueService kakaoAlarmQueueService = (KakaoAlarmQueueService) QueueService.KAT_QUEUE_SERVICE.getService(); @@ -290,6 +315,12 @@ public enum QueueTypeWorker { return kakaoFriendQueueService.saveMessageToTable(data); } + @Override + public int saveMessageForList(List list) { + KakaoFriendQueueService kakaoFriendQueueService = (KakaoFriendQueueService) QueueService.KFT_QUEUE_SERVICE.getService(); + return kakaoFriendQueueService.saveMessageForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { KakaoFriendQueueService kakaoFriendQueueService = (KakaoFriendQueueService) QueueService.KFT_QUEUE_SERVICE.getService(); @@ -337,6 +368,7 @@ public enum QueueTypeWorker { public abstract void addQueue(WriteQueue queue); public abstract void pushQueue(BasicMessageDto data); public abstract int saveMessageToTable(BasicMessageDto data); + public abstract int saveMessageForList(List list); public abstract void memoryEnQueue(BasicMessageDto data); public abstract BasicMessageDto memoryDeQueue(); diff --git a/src/main/java/com/munjaon/server/queue/mapper/KatMapper.java b/src/main/java/com/munjaon/server/queue/mapper/KatMapper.java index 553b365..60af4e1 100644 --- a/src/main/java/com/munjaon/server/queue/mapper/KatMapper.java +++ b/src/main/java/com/munjaon/server/queue/mapper/KatMapper.java @@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper; import com.munjaon.server.queue.dto.BasicMessageDto; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface KatMapper { int insert(BasicMessageDto messageDto); + int insertForList(List list); + int insertGroupForList(List list); } diff --git a/src/main/java/com/munjaon/server/queue/mapper/KftMapper.java b/src/main/java/com/munjaon/server/queue/mapper/KftMapper.java index 19d108a..7a416d4 100644 --- a/src/main/java/com/munjaon/server/queue/mapper/KftMapper.java +++ b/src/main/java/com/munjaon/server/queue/mapper/KftMapper.java @@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper; import com.munjaon.server.queue.dto.BasicMessageDto; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface KftMapper { int insert(BasicMessageDto messageDto); + int insertForList(List list); + int insertGroupForList(List list); } diff --git a/src/main/java/com/munjaon/server/queue/mapper/LmsMapper.java b/src/main/java/com/munjaon/server/queue/mapper/LmsMapper.java index 2be78e8..7ff91c6 100644 --- a/src/main/java/com/munjaon/server/queue/mapper/LmsMapper.java +++ b/src/main/java/com/munjaon/server/queue/mapper/LmsMapper.java @@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper; import com.munjaon.server.queue.dto.BasicMessageDto; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface LmsMapper { int insert(BasicMessageDto messageDto); + int insertForList(List list); + int insertGroupForList(List list); } diff --git a/src/main/java/com/munjaon/server/queue/mapper/MmsMapper.java b/src/main/java/com/munjaon/server/queue/mapper/MmsMapper.java index 6b7ba0e..57a138c 100644 --- a/src/main/java/com/munjaon/server/queue/mapper/MmsMapper.java +++ b/src/main/java/com/munjaon/server/queue/mapper/MmsMapper.java @@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper; import com.munjaon.server.queue.dto.BasicMessageDto; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface MmsMapper { int insert(BasicMessageDto messageDto); + int insertForList(List list); + int insertGroupForList(List list); } diff --git a/src/main/java/com/munjaon/server/queue/mapper/SmsMapper.java b/src/main/java/com/munjaon/server/queue/mapper/SmsMapper.java index 7ea05f0..ac9ab7c 100644 --- a/src/main/java/com/munjaon/server/queue/mapper/SmsMapper.java +++ b/src/main/java/com/munjaon/server/queue/mapper/SmsMapper.java @@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper; import com.munjaon.server.queue.dto.BasicMessageDto; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface SmsMapper { int insert(BasicMessageDto messageDto); + int insertForList(List list); + int insertGroupForList(List list); } diff --git a/src/main/java/com/munjaon/server/queue/pool/ReportQueue.java b/src/main/java/com/munjaon/server/queue/pool/ReportQueue.java index 74dce05..ea126f2 100644 --- a/src/main/java/com/munjaon/server/queue/pool/ReportQueue.java +++ b/src/main/java/com/munjaon/server/queue/pool/ReportQueue.java @@ -89,27 +89,28 @@ public class ReportQueue { } public boolean isTruncateQueue(int maxWriteCount) { - boolean truncate = false; synchronized (lockObject) { if (this.writeCounter >= maxWriteCount) { if (this.writeCounter == this.readCounter) { - truncate = true; + return true; } + return false; } + return false; } - - return truncate; } public boolean isWriteLimit(int maxWriteCount) { - boolean isLimit = false; synchronized (lockObject) { if (this.writeCounter >= maxWriteCount) { - isLimit = true; + return true; } + return false; } + } - return isLimit; + public boolean isRemainReport() { + return this.writeCounter > this.readCounter; } public void truncateQueue() throws Exception { @@ -124,26 +125,24 @@ public class ReportQueue { } private void readHeader() throws Exception { - synchronized (lockObject) { - initHeadBuffer(); - this.channel.position(0); - this.channel.read(this.headBuffer); - this.byteArray = new byte[ReportConfig.USER_ID_LENGTH]; - // USER_ID - this.headBuffer.position(ReportConfig.USER_ID_POSITION); - this.headBuffer.get(this.byteArray); - this.userId = (new String(this.byteArray)).trim(); - // 쓰기 카운트 가져오기 - this.byteArray = new byte[ReportConfig.WRITE_COUNT_LENGTH]; - this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION); - this.headBuffer.get(this.byteArray); - this.writeCounter = Integer.parseInt((new String(this.byteArray)).trim()); - // 읽기 카운트 가져오기 - this.byteArray = new byte[ReportConfig.READ_COUNT_LENGTH]; - this.headBuffer.position(ReportConfig.READ_COUNT_POSITION); - this.headBuffer.get(this.byteArray); - this.readCounter = Integer.parseInt((new String(this.byteArray)).trim()); - } + initHeadBuffer(); + this.channel.position(0); + this.channel.read(this.headBuffer); + this.byteArray = new byte[ReportConfig.USER_ID_LENGTH]; + // USER_ID + this.headBuffer.position(ReportConfig.USER_ID_POSITION); + this.headBuffer.get(this.byteArray); + this.userId = (new String(this.byteArray)).trim(); + // 쓰기 카운트 가져오기 + this.byteArray = new byte[ReportConfig.WRITE_COUNT_LENGTH]; + this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION); + this.headBuffer.get(this.byteArray); + this.writeCounter = Integer.parseInt((new String(this.byteArray)).trim()); + // 읽기 카운트 가져오기 + this.byteArray = new byte[ReportConfig.READ_COUNT_LENGTH]; + this.headBuffer.position(ReportConfig.READ_COUNT_POSITION); + this.headBuffer.get(this.byteArray); + this.readCounter = Integer.parseInt((new String(this.byteArray)).trim()); } public void addReadCounter() throws Exception { @@ -151,30 +150,20 @@ public class ReportQueue { /* 읽기 카운트 증가 */ this.readCounter = this.readCounter + 1; - initHeadBuffer(); - this.channel.position(ReportConfig.USER_ID_POSITION); - this.headBuffer.put(this.userId.getBytes()); - this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION); - this.headBuffer.put(Integer.toString(this.writeCounter).getBytes()); - this.headBuffer.position(ReportConfig.READ_COUNT_POSITION); - this.headBuffer.put(Integer.toString(this.readCounter).getBytes()); - this.headBuffer.flip(); - this.channel.write(this.headBuffer); + writeHeader(); } } private void writeHeader() throws Exception { - synchronized (lockObject) { - initHeadBuffer(); - this.channel.position(ReportConfig.USER_ID_POSITION); - this.headBuffer.put(this.userId.getBytes()); - this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION); - this.headBuffer.put(Integer.toString(this.writeCounter).getBytes()); - this.headBuffer.position(ReportConfig.READ_COUNT_POSITION); - this.headBuffer.put(Integer.toString(this.readCounter).getBytes()); - this.headBuffer.flip(); - this.channel.write(this.headBuffer); - } + initHeadBuffer(); + this.channel.position(ReportConfig.USER_ID_POSITION); + this.headBuffer.put(this.userId.getBytes()); + this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION); + this.headBuffer.put(Integer.toString(this.writeCounter).getBytes()); + this.headBuffer.position(ReportConfig.READ_COUNT_POSITION); + this.headBuffer.put(Integer.toString(this.readCounter).getBytes()); + this.headBuffer.flip(); + this.channel.write(this.headBuffer); } private void initHeadBuffer() { diff --git a/src/main/java/com/munjaon/server/queue/pool/SerialQueue.java b/src/main/java/com/munjaon/server/queue/pool/SerialQueue.java new file mode 100644 index 0000000..cd2e80c --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/pool/SerialQueue.java @@ -0,0 +1,125 @@ +package com.munjaon.server.queue.pool; + +import com.munjaon.server.queue.config.QueueConstants; +import com.munjaon.server.util.FileUtil; +import lombok.Getter; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +public class SerialQueue { + /** Queue Header Buffer */ + private ByteBuffer dataBuffer = null; + /** Header 에서 사용하는 변수 */ + private byte[] dataArray = null; + /* 채번 큐 크기 */ + private final int SERIAL_QUEUE_SIZE = 14; + /* 큐경로 */ + @Getter + private String queuePath; + @Getter + private final String queueName = "SERIAL_QUEUE.queue"; + @Getter + private Long serialNo = 0L; + /** Queue File Channel */ + private FileChannel channel = null; + + public SerialQueue() throws Exception { + initQueue(); + } + + private void initQueuePath() { + /* 1. 큐경로 */ + this.queuePath = System.getProperty("ROOTPATH") + File.separator + "queue" + File.separator + "SERIAL_QUEUE"; + /* 2. 경로 체크 및 생성 */ + FileUtil.mkdirs(this.queuePath); + } + + private void initQueue() throws Exception { + this.dataBuffer = ByteBuffer.allocateDirect(SERIAL_QUEUE_SIZE); + try{ + /* 1. 큐경로 초기화 */ + initQueuePath(); + File file = new File(this.queuePath + File.separator + queueName); + this.channel = new RandomAccessFile(file, "rw").getChannel(); + + if (file.length() == 0) { + serialNo = 0L; + // 헤더 초기화 + writeData(); + } else { + readData(); + } +// backupQueue(); + } catch(Exception e) { + throw e; + } finally { + //lock.release(); + } + } + + private void readData() throws Exception { + try { + initDataBuffer(); + this.channel.position(0); + this.channel.read(this.dataBuffer); + + this.dataArray = new byte[SERIAL_QUEUE_SIZE]; + this.dataBuffer.position(0); + this.dataBuffer.get(this.dataArray); + String no = QueueConstants.getString(this.dataArray); + serialNo = Long.parseLong(no); + System.out.println("SERIAL QUEUE NO: " + serialNo); + } catch(Exception e) { + throw e; + } + } + + public String getSerialNumber() throws Exception { + this.serialNo = this.serialNo + 1; + writeData(); + + return String.valueOf(this.serialNo); + } + + private void writeData() throws Exception { + try { + initDataBuffer(); + this.channel.position(0); + this.dataBuffer.put(String.valueOf(serialNo).getBytes()); + this.dataBuffer.flip(); + this.channel.write(this.dataBuffer); + } catch(Exception e) { + throw e; + } + } + + private void initDataBuffer(){ + this.dataBuffer.clear(); + for(int loopCnt = 0; loopCnt < SERIAL_QUEUE_SIZE; loopCnt++){ + this.dataBuffer.put(QueueConstants.SET_DEFAULT_BYTE); + } + this.dataBuffer.position(0); + } + + public void close() throws IOException { + try { + if (isOpen()) { + channel.close(); + } + } catch(IOException e) { + throw e; + } + } + + public boolean isOpen() { + if (this.channel == null) { + return false; + } + + return this.channel.isOpen(); + } +} diff --git a/src/main/java/com/munjaon/server/queue/pool/SerialQueuePool.java b/src/main/java/com/munjaon/server/queue/pool/SerialQueuePool.java new file mode 100644 index 0000000..6e02cf9 --- /dev/null +++ b/src/main/java/com/munjaon/server/queue/pool/SerialQueuePool.java @@ -0,0 +1,54 @@ +package com.munjaon.server.queue.pool; + +public class SerialQueuePool { + /** Lock Object */ + protected final Object lockMonitor = new Object(); + /* Serial Queue */ + private SerialQueue serialQueue; + + private static SerialQueuePool queueInstance; + + private SerialQueuePool() {} + + public synchronized static SerialQueuePool getInstance() { + if (queueInstance == null) { + queueInstance = new SerialQueuePool(); + } + + return queueInstance; + } + + public String getSerialNumber() throws Exception { + synchronized (lockMonitor) { + if (serialQueue == null || serialQueue.isOpen() == false) { + try { + lockMonitor.wait(); + } catch(InterruptedException e) { + // 아무 처리도 하지 않는다. + } + } + + return serialQueue.getSerialNumber(); + } + } + + public void setSerialQueue(SerialQueue serialQueue) { + synchronized(lockMonitor){ + if (serialQueue != null){ + this.serialQueue = serialQueue; + lockMonitor.notifyAll(); + } + } + } + + public boolean isReady() { + synchronized (lockMonitor) { + if (serialQueue != null && serialQueue.isOpen()) { + return true; + } else { + return false; + } + } + } + +} diff --git a/src/main/java/com/munjaon/server/queue/service/KakaoAlarmQueueService.java b/src/main/java/com/munjaon/server/queue/service/KakaoAlarmQueueService.java index 37da67f..b6aebaf 100644 --- a/src/main/java/com/munjaon/server/queue/service/KakaoAlarmQueueService.java +++ b/src/main/java/com/munjaon/server/queue/service/KakaoAlarmQueueService.java @@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; @Slf4j @Service @@ -63,6 +66,13 @@ public class KakaoAlarmQueueService implements QueueAction { return katMapper.insert(data); } + @Override + @Transactional + public int saveMessageForList(List list) { + katMapper.insertGroupForList(list); + return katMapper.insertForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { memoryQueue.memoryEnQueue(data); diff --git a/src/main/java/com/munjaon/server/queue/service/KakaoFriendQueueService.java b/src/main/java/com/munjaon/server/queue/service/KakaoFriendQueueService.java index 02ac70d..7c033bd 100644 --- a/src/main/java/com/munjaon/server/queue/service/KakaoFriendQueueService.java +++ b/src/main/java/com/munjaon/server/queue/service/KakaoFriendQueueService.java @@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; @Slf4j @Service @@ -63,6 +66,13 @@ public class KakaoFriendQueueService implements QueueAction { return kftMapper.insert(data); } + @Override + @Transactional + public int saveMessageForList(List list) { + kftMapper.insertGroupForList(list); + return kftMapper.insertForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { memoryQueue.memoryEnQueue(data); diff --git a/src/main/java/com/munjaon/server/queue/service/LmsQueueService.java b/src/main/java/com/munjaon/server/queue/service/LmsQueueService.java index ed90b3e..fb2d81c 100644 --- a/src/main/java/com/munjaon/server/queue/service/LmsQueueService.java +++ b/src/main/java/com/munjaon/server/queue/service/LmsQueueService.java @@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; @Slf4j @Service @@ -63,6 +66,13 @@ public class LmsQueueService implements QueueAction { return lmsMapper.insert(data); } + @Override + @Transactional + public int saveMessageForList(List list) { + lmsMapper.insertGroupForList(list); + return lmsMapper.insertForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { memoryQueue.memoryEnQueue(data); diff --git a/src/main/java/com/munjaon/server/queue/service/MmsQueueService.java b/src/main/java/com/munjaon/server/queue/service/MmsQueueService.java index c3492a0..7de6956 100644 --- a/src/main/java/com/munjaon/server/queue/service/MmsQueueService.java +++ b/src/main/java/com/munjaon/server/queue/service/MmsQueueService.java @@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; @Slf4j @Service @@ -63,6 +66,13 @@ public class MmsQueueService implements QueueAction { return mmsMapper.insert(data); } + @Override + @Transactional + public int saveMessageForList(List list) { + mmsMapper.insertGroupForList(list); + return mmsMapper.insertForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { memoryQueue.memoryEnQueue(data); diff --git a/src/main/java/com/munjaon/server/queue/service/QueueAction.java b/src/main/java/com/munjaon/server/queue/service/QueueAction.java index 2f33c1a..7a8c583 100644 --- a/src/main/java/com/munjaon/server/queue/service/QueueAction.java +++ b/src/main/java/com/munjaon/server/queue/service/QueueAction.java @@ -3,6 +3,8 @@ package com.munjaon.server.queue.service; import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.pool.WriteQueue; +import java.util.List; + public interface QueueAction { int getQueueSize(); boolean isExistQueue(String name); @@ -10,6 +12,7 @@ public interface QueueAction { void addQueue(WriteQueue queue); void pushQueue(BasicMessageDto data); int saveMessageToTable(BasicMessageDto data); + int saveMessageForList(List list); void memoryEnQueue(BasicMessageDto data); BasicMessageDto memoryDeQueue(); diff --git a/src/main/java/com/munjaon/server/queue/service/SmsQueueService.java b/src/main/java/com/munjaon/server/queue/service/SmsQueueService.java index 7bd41d7..c11b138 100644 --- a/src/main/java/com/munjaon/server/queue/service/SmsQueueService.java +++ b/src/main/java/com/munjaon/server/queue/service/SmsQueueService.java @@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; @Slf4j @Service @@ -54,6 +57,7 @@ public class SmsQueueService implements QueueAction { } @Override + @Transactional public int saveMessageToTable(BasicMessageDto data) { String serialNo = serialNoService.getSerialNo(); String groupSerialNo = serialNo.replace("MSGID", "MGRP"); @@ -63,6 +67,13 @@ public class SmsQueueService implements QueueAction { return smsMapper.insert(data); } + @Override + @Transactional + public int saveMessageForList(List list) { + smsMapper.insertGroupForList(list); + return smsMapper.insertForList(list); + } + @Override public void memoryEnQueue(BasicMessageDto data) { memoryQueue.memoryEnQueue(data); diff --git a/src/main/java/com/munjaon/server/scheduler/service/CacheScheduleService.java b/src/main/java/com/munjaon/server/scheduler/service/CacheScheduleService.java index ea6f97d..b065dfc 100644 --- a/src/main/java/com/munjaon/server/scheduler/service/CacheScheduleService.java +++ b/src/main/java/com/munjaon/server/scheduler/service/CacheScheduleService.java @@ -4,6 +4,7 @@ import com.munjaon.server.cache.service.MemberService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Slf4j @@ -19,7 +20,7 @@ public class CacheScheduleService { /* 사용자 설정 테이블 마지막 업데이트 시간 */ private String config_last_modified_time = null; -// @Scheduled(cron="0/5 * * * * *") + @Scheduled(cron="0/5 * * * * *") public void doService() throws Exception { doMemberService(); } diff --git a/src/main/java/com/munjaon/server/server/config/ServerConfig.java b/src/main/java/com/munjaon/server/server/config/ServerConfig.java index 3789ddd..4e92afd 100644 --- a/src/main/java/com/munjaon/server/server/config/ServerConfig.java +++ b/src/main/java/com/munjaon/server/server/config/ServerConfig.java @@ -4,10 +4,16 @@ public final class ServerConfig { /* 서버 타임아웃 체크 시간 */ public static final int CYCLE_SOCKET_TIMEOUT = 3000; /* 서버 연결후 로그인 만료 시간 */ - public static final int LIMIT_BIND_TIMEOUT = 5000; + public static final int LIMIT_BIND_TIMEOUT = 3000; /* Session Check 만료 시간 */ public static final int LIMIT_LINK_CHECK_TIMEOUT = 10000; /* 서버 프로퍼티 reload interval 시간 */ public static final Long INTERVAL_PROPERTY_RELOAD_TIME = 3000L; + /* 사용자 정보 조회 체크 시간 */ + public static final long USER_STATUS_CYCLE_TIME = 60000; + /* Deliver Thread 실행 시간 */ + public static final long DELIVER_EXEC_CYCLE_TIME = 5000; + /* Report Thread 실행 시간 */ + public static final long REPORT_EXEC_CYCLE_TIME = 5000; } diff --git a/src/main/java/com/munjaon/server/server/dto/ConnectUserDto.java b/src/main/java/com/munjaon/server/server/dto/ConnectUserDto.java index 006f065..ecdc302 100644 --- a/src/main/java/com/munjaon/server/server/dto/ConnectUserDto.java +++ b/src/main/java/com/munjaon/server/server/dto/ConnectUserDto.java @@ -24,7 +24,10 @@ public class ConnectUserDto { private String remoteIP; /* 요금제(선불 : P / 후불 : A) */ private final String feeType = "A"; - private int command; //요청 command + /* 요청 command */ + private int command; + /* 요청을 처리중인지 여부 */ + private boolean isRunningMode; private MemberDto memberDto; diff --git a/src/main/java/com/munjaon/server/server/dto/ReportUserDto.java b/src/main/java/com/munjaon/server/server/dto/ReportUserDto.java index 1badf5e..c3a09eb 100644 --- a/src/main/java/com/munjaon/server/server/dto/ReportUserDto.java +++ b/src/main/java/com/munjaon/server/server/dto/ReportUserDto.java @@ -21,6 +21,9 @@ public class ReportUserDto { private ReportQueue reportQueue; //ReportQueue private MemberDto memberDto; //사용자 정보 private int command; //요청 command + private int maxWriteCount; //요청 command + /* 요청을 처리중인지 여부 */ + private boolean isRunningMode; public int isAlive() { if (isLogin) { diff --git a/src/main/java/com/munjaon/server/server/sample/Main.java b/src/main/java/com/munjaon/server/server/sample/Main.java index a055629..83a9a95 100644 --- a/src/main/java/com/munjaon/server/server/sample/Main.java +++ b/src/main/java/com/munjaon/server/server/sample/Main.java @@ -1,34 +1,31 @@ package com.munjaon.server.server.sample; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; public class Main { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService e = Executors.newFixedThreadPool(5); // 리턴 값이 필요 없는 경우 -// for (int i = 0; i < 5; i++) { -// e.execute(new MyRunnable(i * 20)); -// } + for (int i = 0; i < 5; i++) { + e.execute(new MyRunnable(i * 20)); + } // 작업을 기다려야 할 경우 - //e.shutdown(); + e.shutdown(); // 리턴 값이 필요한 경우 - List> l = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - Future f = e.submit(new MyCallable(i * 20)); - l.add(f); - } - - // 작업이 완료 되길 기다려야 할 경우 - int n = 0; - for (int i = 0; i < 5; i++) { - Future f = l.get(i); - n += f.get(); - } +// List> l = new ArrayList<>(); +// for (int i = 0; i < 5; i++) { +// Future f = e.submit(new MyCallable(i * 20)); +// l.add(f); +// } +// +// // 작업이 완료 되길 기다려야 할 경우 +// int n = 0; +// for (int i = 0; i < 5; i++) { +// Future f = l.get(i); +// n += f.get(); +// } } } diff --git a/src/main/java/com/munjaon/server/server/sample/MyRunnable.java b/src/main/java/com/munjaon/server/server/sample/MyRunnable.java index 505e9f3..03da849 100644 --- a/src/main/java/com/munjaon/server/server/sample/MyRunnable.java +++ b/src/main/java/com/munjaon/server/server/sample/MyRunnable.java @@ -7,8 +7,9 @@ public class MyRunnable implements Runnable { } public void run() { + System.out.println("SendReadTask start : " + Thread.currentThread().getName()); for (int i = 0; i < 20; i++) { - System.out.println(s + " : MyRunnable"); + System.out.println(s + " : MyRunnable : " + Thread.currentThread().getName()); System.out.println(i + s); try { Thread.sleep(1000L); diff --git a/src/main/java/com/munjaon/server/server/service/CollectServer.java b/src/main/java/com/munjaon/server/server/service/CollectServer.java new file mode 100644 index 0000000..1a34cd4 --- /dev/null +++ b/src/main/java/com/munjaon/server/server/service/CollectServer.java @@ -0,0 +1,184 @@ +package com.munjaon.server.server.service; + +import com.munjaon.server.queue.enums.QueueTypeWorker; +import com.munjaon.server.server.config.ServerConfig; +import com.munjaon.server.server.dto.ConnectUserDto; +import com.munjaon.server.server.queue.CollectUserQueue; +import com.munjaon.server.server.task.CollectServerTask; +import com.munjaon.server.server.task.StatusCheckTask; +import org.json.simple.JSONObject; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; + +public class CollectServer extends Service { + private final InetSocketAddress listenAddress; + private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); + + private Selector selector; + private final String serviceType; + + private long USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis(); + + public CollectServer(String serviceName, String serviceType, int port) { + super(serviceName); + this.listenAddress = new InetSocketAddress(port); + this.serviceType = serviceType; + } + + @Override + public void checkReady() { + QueueTypeWorker worker = QueueTypeWorker.find(this.serviceType); + if (worker != null && worker.getQueueSize() > 0) { + this.IS_READY_YN = true; + saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS READY ... ..."); + } else { + this.IS_READY_YN = false; + saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS NOT READY ... ..."); + } + } + + @Override + public void initResources() { + try { + saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZING ... ..."); + initCollectChannel(); + saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZED ... ..."); + } catch (IOException e) { + saveSystemLog(e); + throw new RuntimeException(e); + } + } + + private void initCollectChannel() throws IOException { + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZING ... ..."); + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER PORT [" + listenAddress.getPort() + "]"); + selector = Selector.open(); + /* 채널 생성 */ + ServerSocketChannel serverChannel = ServerSocketChannel.open(); + /* non-Blocking 설정 */ + serverChannel.configureBlocking(false); + /* 서버 ip, port 설정 */ + serverChannel.socket().bind(listenAddress); + /* 채널에 accept 대기 설정 */ + serverChannel.register(selector, SelectionKey.OP_ACCEPT); + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZED ... ..."); + } + + private void closeCollectChannel() throws IOException { + selector.close(); + } + + @Override + public void releaseResources() { + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASING ... ..."); + try { + closeCollectChannel(); + } catch (IOException e) { + saveSystemLog(e); + throw new RuntimeException(e); + } + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASED ... ..."); + } + + @Override + public void doService() { + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STARTED ... ..."); + while (isRun()) { + try { + execInterest(); + execUserStatus(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STOPPED ... ..."); + } + + private void execInterest() throws IOException { + if (selector.select(1000) == 0) { + return ; + } + Iterator keys = selector.selectedKeys().iterator(); + while (keys.hasNext()) { + SelectionKey key = keys.next(); + /* 키 셋에서 제거. */ + keys.remove(); + + if (key.isValid()) { + if (key.isAcceptable()) { // 접속일 경우.. + saveSystemLog("CONNECTION IS ACCEPTABLE ... ..."); + accept(selector, key); + } else if (key.isReadable()) { // 수신일 경우.. + ConnectUserDto connectUserDto = (ConnectUserDto) key.attachment(); + if (connectUserDto == null || connectUserDto.isRunningMode()) { + continue; + } + /* 사용자별 Collect Thread 실행 */ + new CollectServerTask(selector, key, getName(), this.serviceType, logger).run(); + } + } else { + expireConnectUser(key); + } + } + } + + private void execUserStatus() throws IOException { + if (System.currentTimeMillis() - USER_STATUS_LAST_CHECK_TIME > ServerConfig.USER_STATUS_CYCLE_TIME) { + new StatusCheckTask(this.serviceType, logger).run(); + USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis(); + } + } + + private void accept(Selector selector, SelectionKey key) { + try { + /* 키 채널을 가져온다. */ + ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); + /* accept을 해서 Socket 채널을 가져온다. */ + SocketChannel channel = serverChannel.accept(); + channel.configureBlocking(false); + /* 소켓 취득 */ + Socket socket = channel.socket(); + InetAddress inetAddress = socket.getInetAddress(); + saveSystemLog("[CLIENT CONNECTION IP : " + inetAddress.getHostAddress() + "]"); + // Socket 채널을 channel에 수신 등록한다 + channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().serviceType(this.serviceType).lastTrafficTime(System.currentTimeMillis()).remoteIP(inetAddress.getHostAddress()).build()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void expireConnectUser(SelectionKey key) { + if (key == null || !key.isValid()) { + return; + } + try { + SocketChannel channel = (SocketChannel) key.channel(); + ConnectUserDto userDto = (ConnectUserDto) key.attachment(); + if (userDto != null && userDto.getUserId() != null) { + saveSystemLog("[CLIENT USER IS DISCONNECT : " + userDto.toString() + "]"); + collectUserQueue.removeUser(this.serviceType, userDto.getUserId()); +// connectUserMap.remove(userDto.getUserId()); + key.attach(null); + } + // 소켓 채널 닫기 + channel.close(); + // 키 닫기 + key.cancel(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public JSONObject monitorService() { + return null; + } +} diff --git a/src/main/java/com/munjaon/server/server/service/CollectServerService.java b/src/main/java/com/munjaon/server/server/service/CollectServerService.java index 2e74913..0f6d7a4 100644 --- a/src/main/java/com/munjaon/server/server/service/CollectServerService.java +++ b/src/main/java/com/munjaon/server/server/service/CollectServerService.java @@ -4,14 +4,16 @@ import com.munjaon.server.queue.enums.QueueTypeWorker; import com.munjaon.server.server.dto.ConnectUserDto; import com.munjaon.server.server.queue.CollectUserQueue; import com.munjaon.server.server.task.CollectReadTask; +import com.munjaon.server.server.task.SendReadTask; +import com.munjaon.server.server.task.StatusCheckTask; import com.munjaon.server.util.LogUtil; import lombok.Getter; import org.json.simple.JSONObject; import java.io.IOException; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; -import java.net.SocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; @@ -21,17 +23,24 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; public class CollectServerService extends Service { private final InetSocketAddress listenAddress; private CollectThreadService threadService; + private StatusThreadService statusThreadService; private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); + private Selector selector; private final String serviceType; private int readMaxCore; + private long USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis(); + private static final long USER_STATUS_CYCLE_TIME = 60000; + public CollectServerService(String serviceName, String serviceType, int port) { super(serviceName); this.readMaxCore = Integer.parseInt(getProp("READ_MAX_CORE").trim()); @@ -44,17 +53,21 @@ public class CollectServerService extends Service { QueueTypeWorker worker = QueueTypeWorker.find(this.serviceType); if (worker != null && worker.getQueueSize() > 0) { this.IS_READY_YN = true; + saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS READY ... ..."); } else { this.IS_READY_YN = false; + saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS NOT READY ... ..."); } - saveSystemLog("CollectServerService ready : " + this.IS_READY_YN); } @Override public void initResources() { try { + saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZING ... ..."); initCollectChannel(); threadService = new CollectThreadService(readMaxCore, this.serviceType, logger); + statusThreadService = new StatusThreadService(this.serviceType, this.logger); + saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZED ... ..."); } catch (IOException e) { saveSystemLog(e); throw new RuntimeException(e); @@ -62,6 +75,8 @@ public class CollectServerService extends Service { } private void initCollectChannel() throws IOException { + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZING ... ..."); + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER PORT [" + listenAddress.getPort() + "]"); selector = Selector.open(); /* 채널 생성 */ ServerSocketChannel serverChannel = ServerSocketChannel.open(); @@ -71,6 +86,7 @@ public class CollectServerService extends Service { serverChannel.socket().bind(listenAddress); /* 채널에 accept 대기 설정 */ serverChannel.register(selector, SelectionKey.OP_ACCEPT); + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZED ... ..."); } private void closeCollectChannel() throws IOException { @@ -79,24 +95,58 @@ public class CollectServerService extends Service { @Override public void releaseResources() { + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASING ... ..."); try { closeCollectChannel(); threadService.close(); + statusThreadService.close(); } catch (IOException e) { saveSystemLog(e); throw new RuntimeException(e); } + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASED ... ..."); } @Override public void doService() { + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STARTED ... ..."); while (isRun()) { try { execInterest(); + execUserStatus(); } catch (Exception e) { throw new RuntimeException(e); } } + saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STOPPED ... ..."); + } + + private void execInterest_bak() throws IOException { + if (selector.select(1000) == 0) { + return ; + } + Iterator keys = selector.selectedKeys().iterator(); + while (keys.hasNext()) { + SelectionKey key = keys.next(); + /* 키 셋에서 제거. */ + keys.remove(); + + if (key.isValid()) { + if (key.isAcceptable()) { // 접속일 경우.. + saveSystemLog("CONNECTION IS ACCEPTABLE ... ..."); + accept(selector, key); + } else if (key.isReadable()) { // 수신일 경우.. + ConnectUserDto connectUserDto = (ConnectUserDto) key.attachment(); + if (connectUserDto == null || connectUserDto.isRunningMode()) { + continue; + } + threadService.execute(new SendReadTask(selector, key, this.serviceType, logger)); +// threadService.submit(selector, key, 2); + } + } else { + expireConnectUser(key); + } + } } private void execInterest() throws IOException { @@ -112,10 +162,9 @@ public class CollectServerService extends Service { if (key.isValid()) { if (key.isAcceptable()) { // 접속일 경우.. - saveSystemLog("isAcceptable"); + saveSystemLog("CONNECTION IS ACCEPTABLE ... ..."); accept(selector, key); } else if (key.isReadable()) { // 수신일 경우.. - saveSystemLog("isReadable"); Future future = threadService.submit(new CollectReadTask(selector, key, this.serviceType, logger)); list.add(future); // threadService.submit(selector, key, 2); @@ -132,14 +181,19 @@ public class CollectServerService extends Service { } catch (ExecutionException e) { } - if (connectUserDto == null) { - saveSystemLog("Future : " + future); - } else { - saveSystemLog("Future : " + connectUserDto.toString()); + if (connectUserDto != null) { + saveSystemLog("[READ USER : " + connectUserDto.toString() + "]"); } } } + private void execUserStatus() throws IOException { + if (System.currentTimeMillis() - USER_STATUS_LAST_CHECK_TIME > USER_STATUS_CYCLE_TIME) { + statusThreadService.execute(new StatusCheckTask(this.serviceType, logger)); + USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis(); + } + } + private void accept(Selector selector, SelectionKey key) { try { /* 키 채널을 가져온다. */ @@ -149,10 +203,10 @@ public class CollectServerService extends Service { channel.configureBlocking(false); /* 소켓 취득 */ Socket socket = channel.socket(); - SocketAddress remoteAddr = socket.getRemoteSocketAddress(); - saveSystemLog("Connected to: " + remoteAddr); + InetAddress inetAddress = socket.getInetAddress(); + saveSystemLog("[CLIENT CONNECTION IP : " + inetAddress.getHostAddress() + "]"); // Socket 채널을 channel에 수신 등록한다 - channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().serviceType(this.serviceType).lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).build()); + channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().serviceType(this.serviceType).lastTrafficTime(System.currentTimeMillis()).remoteIP(inetAddress.getHostAddress()).build()); } catch (Exception e) { throw new RuntimeException(e); } @@ -166,6 +220,7 @@ public class CollectServerService extends Service { SocketChannel channel = (SocketChannel) key.channel(); ConnectUserDto userDto = (ConnectUserDto) key.attachment(); if (userDto != null && userDto.getUserId() != null) { + saveSystemLog("[CLIENT USER IS DISCONNECT : " + userDto.toString() + "]"); collectUserQueue.removeUser(this.serviceType, userDto.getUserId()); // connectUserMap.remove(userDto.getUserId()); key.attach(null); @@ -184,27 +239,77 @@ public class CollectServerService extends Service { return null; } - private static class CollectThreadService { + private static class StatusThreadService { @Getter private String serviceType; @Getter - private final int maxCore; + private final int maxCore = 1; private final ExecutorService executor; - private final Map connectUserMap = new ConcurrentHashMap<>(); private final LogUtil logger; - public CollectThreadService(String serviceType, LogUtil logger) { - this(Runtime.getRuntime().availableProcessors(), serviceType, logger); - } - - public CollectThreadService(int maxCore, String serviceType, LogUtil logger) { - this.maxCore = maxCore; + public StatusThreadService(String serviceType, LogUtil logger) { this.executor = Executors.newFixedThreadPool(maxCore); this.logger = logger; + saveSystemLog("[STATUS_TASK_THREAD_POOL : " + maxCore + "]"); } - public Future submit(CollectReadTask collectReadTask) { - return executor.submit(collectReadTask); + public void execute(StatusCheckTask statusCheckTask) { + executor.execute(statusCheckTask); + } + + private void saveSystemLog(Object obj) { + saveLog(obj, true); + } + + private void saveLog(Object obj) { + saveLog(obj, false); + } + + private void saveLog(Object obj, boolean isConsoleOutput) { + if (isConsoleOutput) { + System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + serviceType + "}} " + obj); + } + + if (logger == null) { + return; + } + + logger.log(obj); + } + + public void close() { + List unfinishedTasks = executor.shutdownNow(); + if (!unfinishedTasks.isEmpty()) { + saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size()); + } + } + } + + private static class CollectThreadService { + @Getter + private String serviceType; + @Getter + private final int maxCore; + private final ExecutorService executor; + private final LogUtil logger; + + public CollectThreadService(String serviceType, LogUtil logger) { + this(Runtime.getRuntime().availableProcessors(), serviceType, logger); + } + + public CollectThreadService(int maxCore, String serviceType, LogUtil logger) { + this.maxCore = maxCore; + this.executor = Executors.newFixedThreadPool(maxCore); + this.logger = logger; + saveSystemLog("[COLLECT_TASK_THREAD_POOL : " + maxCore + "]"); + } + + public Future submit(CollectReadTask collectReadTask) { + return executor.submit(collectReadTask); + } + + public void execute(SendReadTask sendReadTask) { + executor.execute(sendReadTask); } private void saveSystemLog(Object obj) { @@ -229,7 +334,6 @@ public class CollectServerService extends Service { public void close() { List unfinishedTasks = executor.shutdownNow(); - connectUserMap.clear(); if (!unfinishedTasks.isEmpty()) { saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size()); } diff --git a/src/main/java/com/munjaon/server/server/service/QueueServerService.java b/src/main/java/com/munjaon/server/server/service/QueueServerService.java index e708fa3..9b8037d 100644 --- a/src/main/java/com/munjaon/server/server/service/QueueServerService.java +++ b/src/main/java/com/munjaon/server/server/service/QueueServerService.java @@ -3,14 +3,18 @@ package com.munjaon.server.server.service; import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.enums.QueueTypeWorker; import com.munjaon.server.queue.pool.ReadQueue; +import com.munjaon.server.queue.pool.SerialQueuePool; import com.munjaon.server.queue.pool.WriteQueue; import com.munjaon.server.util.CommonUtil; +import com.munjaon.server.util.MessageUtil; import com.munjaon.server.util.ServiceUtil; import org.json.simple.JSONObject; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; public class QueueServerService extends Service { /** 큐모드 설정(WAIT : 파일에 쓰기모드만 / DB : DB에 적재) */ @@ -21,6 +25,7 @@ public class QueueServerService extends Service { private long QUEUE_INIT_CHECK_TIME = 0; /** Commit 누적 카운트 */ private long SUM_COMMIT_COUNT = 0; + SerialQueuePool queueInstance = SerialQueuePool.getInstance(); /* 쓰기큐 */ private WriteQueue writeQueue; private ReadQueue readQueue; @@ -49,7 +54,7 @@ public class QueueServerService extends Service { @Override public void checkReady() { - this.IS_READY_YN = true; + this.IS_READY_YN = queueInstance.isReady(); } @Override @@ -109,6 +114,8 @@ public class QueueServerService extends Service { } // 큐초기화 대상이면 if (isQueueInit) { + /* 큐 백업 */ + writeQueue.backupQueue(); /* 커밋 카운트 초기화 */ SUM_COMMIT_COUNT = 0; writeQueue.truncateQueue(); @@ -158,6 +165,8 @@ public class QueueServerService extends Service { isQueueInit = true; } if (isQueueInit) { + /* 큐 백업 */ + writeQueue.backupQueue(); /* 커밋 카운트 초기화 */ SUM_COMMIT_COUNT = 0; // 큐를 초기화한다. @@ -171,6 +180,34 @@ public class QueueServerService extends Service { } private void messageService() throws Exception { + int DB_PROC_COUNT = 0; + List list = new ArrayList<>(); + for (int loopCnt = 0; loopCnt < ServiceUtil.COMMIT_COUNT; loopCnt++) { + BasicMessageDto messageDto = readQueue.popMessageFromBuffer(); + if (messageDto == null) { + break; + } + /* MSG ID 채번 */ + String msgId = queueInstance.getSerialNumber(); + msgId = MessageUtil.makeMessageKey(msgId); + String msgGroupId = msgId.replace("MSGID", "MGRP"); + messageDto.setId(msgId); + messageDto.setMsgGroupID(msgGroupId); + list.add(messageDto); + DB_PROC_COUNT++; + SUM_COMMIT_COUNT++; + } + + // DB 처리한 카운트에 대한 처리 + if (DB_PROC_COUNT > 0) { + worker.saveMessageForList(list); + Thread.sleep(10); + } else { + Thread.sleep(100); + } + } + + private void messageService_bak() throws Exception { int DB_PROC_COUNT = 0; for (int loopCnt = 0; loopCnt < ServiceUtil.COMMIT_COUNT; loopCnt++) { BasicMessageDto messageDto = readQueue.popMessageFromBuffer(); diff --git a/src/main/java/com/munjaon/server/server/service/ReportQueueServerService.java b/src/main/java/com/munjaon/server/server/service/ReportQueueServerService.java index 4d27f09..c8237c5 100644 --- a/src/main/java/com/munjaon/server/server/service/ReportQueueServerService.java +++ b/src/main/java/com/munjaon/server/server/service/ReportQueueServerService.java @@ -17,10 +17,12 @@ public class ReportQueueServerService extends Service { private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); private QueueThreadService threadService; private int queueMaxCore; + private int maxWriteCount; public ReportQueueServerService(String serviceName) { super(serviceName); this.queueMaxCore = Integer.parseInt(getProp("QUEUE_MAX_CORE").trim()); + this.maxWriteCount = Integer.parseInt(getProp("MAX_WRITE_COUNT").trim()); } @Override @@ -43,7 +45,7 @@ public class ReportQueueServerService extends Service { while (isRun()) { try { doQueueService(); - Thread.sleep(100); + Thread.sleep(10); } catch (Exception e) { throw new RuntimeException(e); } @@ -57,6 +59,7 @@ public class ReportQueueServerService extends Service { } for (ReportUserDto reportUserDto : reportUserList) { + reportUserDto.setMaxWriteCount(this.maxWriteCount); threadService.execute(new ReportQueueTask(reportUserDto, logger)); } } diff --git a/src/main/java/com/munjaon/server/server/service/ReportServer.java b/src/main/java/com/munjaon/server/server/service/ReportServer.java new file mode 100644 index 0000000..cc1ab4b --- /dev/null +++ b/src/main/java/com/munjaon/server/server/service/ReportServer.java @@ -0,0 +1,191 @@ +package com.munjaon.server.server.service; + +import com.munjaon.server.queue.pool.ReportQueue; +import com.munjaon.server.server.dto.ConnectUserDto; +import com.munjaon.server.server.dto.ReportUserDto; +import com.munjaon.server.server.queue.ReportUserQueue; +import org.json.simple.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Future; + +public class ReportServer extends Service { + private final InetSocketAddress listenAddress; + private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); + private Selector selector; + + public ReportServer(String serviceName, int port) { + super(serviceName); + this.listenAddress = new InetSocketAddress(port); + } + + @Override + public void checkReady() { + this.IS_READY_YN = true; + } + + @Override + public void initResources() { + try { + initReportChannel(); + } catch (IOException e) { + saveSystemLog(e); + throw new RuntimeException(e); + } + } + + private void initReportChannel() throws IOException { + selector = Selector.open(); + /* 채널 생성 */ + ServerSocketChannel serverChannel = ServerSocketChannel.open(); + /* non-Blocking 설정 */ + serverChannel.configureBlocking(false); + /* 서버 ip, port 설정 */ + serverChannel.socket().bind(listenAddress); + /* 채널에 accept 대기 설정 */ + serverChannel.register(selector, SelectionKey.OP_ACCEPT); + } + + private void closeReportChannel() throws IOException { + selector.close(); + } + + @Override + public void releaseResources() { + try { + closeReportChannel(); + } catch (IOException e) { + saveSystemLog(e); + throw new RuntimeException(e); + } + } + + @Override + public void doService() { + + while (isRun()) { + try { + execInterest(); + checkInterest(); + } catch (Exception e) { + saveSystemLog(e.toString()); + } + } + } + + private void checkInterest() throws IOException, InterruptedException { + Iterator keys = selector.keys().iterator(); + while (keys.hasNext()) { + SelectionKey key = keys.next(); + if (key.isValid()) { + ReportUserDto reportUserDto = (ReportUserDto) key.attachment(); + if (reportUserDto == null) { + continue; + } + SocketChannel channel = (SocketChannel) key.channel(); // 키 채널을 가져온다. + if (reportUserDto.isAlive() == 1) { // 로그인이 완료되지 않은 경우 + expireConnectUser(key); + } else if (reportUserDto.isAlive() == 2) { + if (reportUserDto == null || reportUserDto.isRunningMode()) { + continue; + } + } else { + ReportQueue reportQueue = reportUserDto.getReportQueue(); + if (reportUserDto.isLogin() && reportQueue != null && reportQueue.isRemainReport()) { + if (reportUserDto.isRunningMode()) { + continue; + } + /* 사용자별 Report Thread 실행 */ + } + } + } else { + expireConnectUser(key); + } + } + } + + private void execInterest() throws IOException { + if (selector.select(1000) == 0) { + return ; + } + Iterator keys = selector.selectedKeys().iterator(); + List> list = new ArrayList<>(); + while (keys.hasNext()) { + SelectionKey key = keys.next(); + /* 키 셋에서 제거. */ + keys.remove(); + + if (key.isValid()) { + if (key.isAcceptable()) { // 접속일 경우.. + saveSystemLog("CONNECTION IS ACCEPTABLE ... ..."); + accept(selector, key); + } else if (key.isReadable()) { // 수신일 경우.. + ReportUserDto reportUserDto = (ReportUserDto) key.attachment(); + if (reportUserDto == null || reportUserDto.isRunningMode()) { + continue; + } + saveSystemLog("isReadable"); + /* 사용자별 Report Thread 실행 */ +// threadService.submit(selector, key, 2); + } + } else { + expireConnectUser(key); + } + } + } + + private void accept(Selector selector, SelectionKey key) { + try { + /* 키 채널을 가져온다. */ + ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); + /* accept을 해서 Socket 채널을 가져온다. */ + SocketChannel channel = serverChannel.accept(); + channel.configureBlocking(false); + /* 소켓 취득 */ + Socket socket = channel.socket(); + SocketAddress remoteAddr = socket.getRemoteSocketAddress(); + saveSystemLog("Connected to: " + remoteAddr); + // Socket 채널을 channel에 수신 등록한다 + channel.register(selector, SelectionKey.OP_READ, ReportUserDto.builder().lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).queuePath(System.getProperty("ROOTPATH") + File.separator + getProp("QUEUE_PATH")).build()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void expireConnectUser(SelectionKey key) { + if (key == null || !key.isValid()) { + return; + } + try { + SocketChannel channel = (SocketChannel) key.channel(); + ConnectUserDto userDto = (ConnectUserDto) key.attachment(); + if (userDto != null && userDto.getUserId() != null) { + reportUserQueue.removeUser(userDto.getUserId()); +// connectUserMap.remove(userDto.getUserId()); + key.attach(null); + } + // 소켓 채널 닫기 + channel.close(); + // 키 닫기 + key.cancel(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public JSONObject monitorService() { + return null; + } +} diff --git a/src/main/java/com/munjaon/server/server/service/ReportServerService.java b/src/main/java/com/munjaon/server/server/service/ReportServerService.java index 54a4fe5..f8d1978 100644 --- a/src/main/java/com/munjaon/server/server/service/ReportServerService.java +++ b/src/main/java/com/munjaon/server/server/service/ReportServerService.java @@ -62,7 +62,7 @@ public class ReportServerService extends Service { public void initResources() { try { initReportChannel(); - threadService = new ReadThreadService(8, logger); + threadService = new ReadThreadService(readMaxCore, logger); } catch (IOException e) { saveSystemLog(e); throw new RuntimeException(e); @@ -142,7 +142,6 @@ public class ReportServerService extends Service { try { ReportDto reportDto = reportQueue.popReportFromQueue(); if (reportDto == null) { - saveSystemLog("reportQueue.popReportFromQueue() : null"); continue; } saveSystemLog("reportQueue.popReportFromQueue() : " + reportDto.toString()); diff --git a/src/main/java/com/munjaon/server/server/task/CollectReadTask.java b/src/main/java/com/munjaon/server/server/task/CollectReadTask.java index 96ba607..29df345 100644 --- a/src/main/java/com/munjaon/server/server/task/CollectReadTask.java +++ b/src/main/java/com/munjaon/server/server/task/CollectReadTask.java @@ -77,6 +77,11 @@ public class CollectReadTask implements Callable { } private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + /* 서비스 중지여부 체크 */ + if (isExpireService()) { + expireConnectUser(); + return; + } switch (this.serviceType) { case "SMS": recvSmsDeliver(channel, headBuffer); @@ -97,6 +102,40 @@ public class CollectReadTask implements Callable { } } + private boolean isExpireService() { + ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId()); + MemberDto memberDto = checkConnectUserDto.getMemberDto(); + saveSystemLog("[isExpireService : " + memberDto.toString() + "]"); + if (memberDto == null) { + return true; + } + if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) { + return true; + } + /* 회원 사용 상태 */ + if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { + return true; + } + /* 서비스 이용 상태 */ + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return true; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return true; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return true; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return true; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return true; + } + + return false; + } + public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) { if (deliverBuffer == null) { return null; @@ -116,6 +155,7 @@ public class CollectReadTask implements Callable { return messageDto; } + private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { try { ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH); @@ -126,7 +166,18 @@ public class CollectReadTask implements Callable { // Packet.printBuffer(deliverBuffer); BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer)); - System.out.println("BasicMessageDto : " + messageDto.toString()); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice())); + } + + saveSystemLog("[SMS] [MESSAGE : " + messageDto.toString() + "]"); QueueTypeWorker worker = QueueTypeWorker.find("SMS"); if (worker != null) { worker.pushQueue(messageDto); @@ -148,6 +199,17 @@ public class CollectReadTask implements Callable { messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer)); messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer)); + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice())); + } + + saveSystemLog("[LMS] [MESSAGE : " + messageDto.toString() + "]"); QueueTypeWorker worker = QueueTypeWorker.find("LMS"); if (worker != null) { worker.pushQueue(messageDto); @@ -173,11 +235,8 @@ public class CollectReadTask implements Callable { if (fileCount != null && fileCount.length() > 0) { recvFileCount = Integer.parseInt(fileCount); messageDto.setUserFileCnt(recvFileCount); - saveSystemLog("recvFileCount : " + recvFileCount); } - saveSystemLog("messageDto : " + messageDto.toString()); - String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile"; imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); FileUtil.mkdirs(imagePath); @@ -198,9 +257,28 @@ public class CollectReadTask implements Callable { } else if (i == 2) { messageDto.setUserFileName03(imagePath + File.separator + fileName); } - saveSystemLog("File : " + fileName + ", Size : " + fileSize); + saveSystemLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]"); } + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode()); + float mmsPrice = 0.0F; + if (recvFileCount == 1) { + mmsPrice = savedMemberDto.getPicturePrice(); + } else if (recvFileCount == 2) { + mmsPrice = savedMemberDto.getPicture2Price(); + } else { + mmsPrice = savedMemberDto.getPicture3Price(); + } + messageDto.setUnitCost(String.valueOf(mmsPrice)); + } + + saveSystemLog("[MMS] [MESSAGE : " + messageDto.toString() + "]"); QueueTypeWorker worker = QueueTypeWorker.find("MMS"); if (worker != null) { worker.pushQueue(messageDto); @@ -224,8 +302,6 @@ public class CollectReadTask implements Callable { messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); - saveSystemLog("messageDto : " + messageDto.toString()); - String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); FileUtil.mkdirs(jsonPath); @@ -242,8 +318,19 @@ public class CollectReadTask implements Callable { JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); - saveSystemLog("File : " + fileName + ", Size : " + fileSize); + saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice())); + } + + saveSystemLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]"); QueueTypeWorker worker = QueueTypeWorker.find("KAT"); if (worker != null) { worker.pushQueue(messageDto); @@ -269,8 +356,6 @@ public class CollectReadTask implements Callable { messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); - saveSystemLog("messageDto : " + messageDto.toString()); - String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); FileUtil.mkdirs(jsonPath); @@ -287,8 +372,19 @@ public class CollectReadTask implements Callable { JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); - saveSystemLog("File : " + fileName + ", Size : " + fileSize); + saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice())); + } + + saveSystemLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]"); QueueTypeWorker worker = QueueTypeWorker.find("KFT"); if (worker != null) { worker.pushQueue(messageDto); @@ -304,6 +400,11 @@ public class CollectReadTask implements Callable { channel.read(bodyBuffer); // SocketChannel channel = (SocketChannel) key.channel(); channel.write(LinkCheck.makeLinkCheckAckBuffer()); + /* 서비스 중지여부 체크 */ + if (isExpireService()) { + expireConnectUser(); + return; + } } private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { @@ -316,29 +417,46 @@ public class CollectReadTask implements Callable { String id = Bind.getBindId(bindBuffer); String pwd = Bind.getBindPwd(bindBuffer); - saveSystemLog("Bind id : " + id); - saveSystemLog("Bind pwd : " + pwd); - if (id == null || pwd == null) { - resultCode = "50"; - } else { - if (collectUserQueue.isExist(this.serviceType, id)) { - resultCode = "60"; + + MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); + MemberDto memberDto = null; + if (svc != null) { + memberDto = svc.get(id); + } + saveSystemLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); + /* Bind Check */ + resultCode = checkBind(memberDto, this.serviceType, id, pwd); + + /* 접속 IP 체크 */ + if ("00".equals(resultCode)) { + boolean isPermit = false; + if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { + saveSystemLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP()); + saveSystemLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); + saveSystemLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); + if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { + isPermit = true; + } + if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { + isPermit = true; + } } else { - MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); - MemberDto memberDto = null; - if (svc != null) { - memberDto = svc.get(id); - } - if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { - resultCode = "20"; - } else { - connectUserDto.setUserId(id); - connectUserDto.setLogin(true); - connectUserDto.setMemberDto(memberDto); - /* 세션통신 시간 업데이트 */ - connectUserDto.updateLastTrafficTime(); - } + isPermit = true; } + if (isPermit) { + resultCode = "00"; + } else { + resultCode = "40"; + } + } + if ("00".equals(resultCode)) { + connectUserDto.setUserId(id); + connectUserDto.setLogin(true); + connectUserDto.setMemberDto(memberDto); + /* 사용자 Pool에 저장 */ + collectUserQueue.putUser(this.serviceType, connectUserDto); + /* 세션통신 시간 업데이트 */ + connectUserDto.updateLastTrafficTime(); } } catch (Exception e) { resultCode = "10"; @@ -346,7 +464,7 @@ public class CollectReadTask implements Callable { } try { - saveSystemLog("Bind ResultCode : " + resultCode); + saveSystemLog("[BIND RESULT : " + resultCode + "]"); channel.write(Bind.makeBindAckBuffer(resultCode)); if ("00".equals(resultCode) == false) { expireConnectUser(); @@ -356,6 +474,60 @@ public class CollectReadTask implements Callable { } } + private String checkBind(MemberDto memberDto, String serviceType, String id, String pwd) { + if (id == null || pwd == null) { + return "50"; + } + if (collectUserQueue.isExist(this.serviceType, id)) { + return "60"; + } + if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { + return "20"; + } + /* 회원 사용 상태 */ + if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { + return "30"; + } + /* 서비스 이용 상태 */ + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return "30"; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return "30"; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return "30"; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return "30"; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return "30"; + } + + return "00"; + } + + private String checkService(MemberDto memberDto, String serviceType) { + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return "30"; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return "30"; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return "30"; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return "30"; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return "30"; + } + + return "00"; + } + private void expireConnectUser() { if (key == null || !key.isValid()) { return; diff --git a/src/main/java/com/munjaon/server/server/task/CollectServerTask.java b/src/main/java/com/munjaon/server/server/task/CollectServerTask.java new file mode 100644 index 0000000..5f459e0 --- /dev/null +++ b/src/main/java/com/munjaon/server/server/task/CollectServerTask.java @@ -0,0 +1,635 @@ +package com.munjaon.server.server.task; + +import com.munjaon.server.cache.dto.MemberDto; +import com.munjaon.server.cache.enums.CacheService; +import com.munjaon.server.cache.service.MemberService; +import com.munjaon.server.queue.dto.BasicMessageDto; +import com.munjaon.server.queue.enums.QueueTypeWorker; +import com.munjaon.server.server.config.ServerConfig; +import com.munjaon.server.server.dto.ConnectUserDto; +import com.munjaon.server.server.packet.*; +import com.munjaon.server.server.queue.CollectUserQueue; +import com.munjaon.server.server.service.PropertyLoader; +import com.munjaon.server.util.*; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class CollectServerTask implements Runnable { + public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); + public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; + + private Selector selector; + private SelectionKey key; + private SocketChannel channel; + private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); + private ConnectUserDto connectUserDto; + private String serviceName; + private String serviceType; + private final LogUtil logger; + + private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부 + private boolean IS_RUN_YN; + private long RUN_FLAG_CHECK_TIME; + + /* 클라이언트 요청 데이터 수신 */ + + /* 세션이 만료되었는지 체크 */ + private boolean isExpiredYn; + + public CollectServerTask(Selector selector, SelectionKey key, String serviceName, String serviceType, LogUtil logger) { + this.selector = selector; + this.key = key; + this.channel = (SocketChannel) key.channel(); + this.connectUserDto = (ConnectUserDto) key.attachment(); + this.connectUserDto.setRunningMode(true); + this.serviceName = serviceName; + this.serviceType = serviceType; + this.logger = logger; + } + + protected String getProp(String name) { + return getProp(this.serviceName, name); + } + + public static String getProp(String svc, String name) { + return PropertyLoader.getProp(svc, name); + } + + private void reloadRunFlag() { + if (System.currentTimeMillis() - RUN_FLAG_CHECK_TIME > ServerConfig.INTERVAL_PROPERTY_RELOAD_TIME) { + this.IS_RUN_YN = getProp("RUN_FLAG") != null && "Y".equals(getProp("RUN_FLAG")); + this.IS_SERVER_RUN = getProp("server", "run") != null && "Y".equals(getProp("server", "run")); + RUN_FLAG_CHECK_TIME = System.currentTimeMillis(); + } + } + + public boolean isRun() { + return IS_SERVER_RUN && IS_RUN_YN; + } + + @Override + public void run() { + saveSystemLog("CollectServerTask is Entered"); + /* 최초 RUN Flag 체크 */ + reloadRunFlag(); + /* BIND 체크 및 처리 */ + while (isRun()) { + /* 만료 여부 체크 */ + if (isExpiredYn) { + break; + } + + int size = -1; + try { + /* 1. Head 읽기 */ + ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); + try { + size = channel.read(headBuffer); + } catch (IOException e) {} + /* 2. Body 읽기 */ + if (size > 0) { + String command = Header.getCommand(headBuffer); + switch (Integer.parseInt(command)) { + case 1: + recvBind(channel, headBuffer); + break; + case 3: + recvDeliver(channel, headBuffer); + break; + case 7: + recvLinkCheck(channel); + break; + default: + expireConnectUser(); + break; + } + } else if (size == 0) { + Thread.sleep(1); + if (System.currentTimeMillis() - connectUserDto.getLastTrafficTime() > ServerConfig.DELIVER_EXEC_CYCLE_TIME) { + this.isExpiredYn = true; + } + } else { + expireConnectUser(); + } + + } catch (Exception e) { + size = -1; + e.printStackTrace(); + } + /* RUN Flag 체크 */ + reloadRunFlag(); + } + /* 중요 : 사용자 Thread 실행모드 Off */ + connectUserDto.setRunningMode(false); + saveSystemLog("CollectServerTask is Finished"); + } + + private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + /* 서비스 중지여부 체크 */ + if (isExpireService()) { + expireConnectUser(); + return; + } + switch (this.serviceType) { + case "SMS": + recvSmsDeliver(channel, headBuffer); + break; + case "LMS": + recvLmsDeliver(channel, headBuffer); + break; + case "MMS": + recvMmsDeliver(channel, headBuffer); + break; + case "KAT": + recvKatDeliver(channel, headBuffer); + break; + case "KFT": + recvKftDeliver(channel, headBuffer); + break; + default:break; + } + } + + private boolean isExpireService() { + ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId()); + MemberDto memberDto = checkConnectUserDto.getMemberDto(); + saveSystemLog("[isExpireService : " + memberDto.toString() + "]"); + if (memberDto == null) { + return true; + } + if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) { + return true; + } + /* 회원 사용 상태 */ + if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { + return true; + } + /* 서비스 이용 상태 */ + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return true; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return true; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return true; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return true; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return true; + } + + return false; + } + + public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) { + if (deliverBuffer == null) { + return null; + } + BasicMessageDto messageDto = new BasicMessageDto(); + messageDto.setRouterSeq("40"); + messageDto.setServiceType("4"); + messageDto.setUserId(connectUserDto.getUserId()); + messageDto.setRemoteIP(connectUserDto.getRemoteIP()); + messageDto.setSendStatus("0"); + messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(deliverBuffer)); + messageDto.setUserSender(CommonMessage.getSenderForDeliver(deliverBuffer)); + messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(deliverBuffer)); + messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(deliverBuffer)); + messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(deliverBuffer)); + messageDto.setUnitCost("10.4"); + + return messageDto; + } + + private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + SmsMessage.DELIVER_SMS_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + +// Packet.printBuffer(deliverBuffer); + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer)); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice())); + } + + saveLog("[SMS] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("SMS"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + connectUserDto.updateLastTrafficTime(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvLmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(LmsMessage.DELIVER_LMS_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + LmsMessage.DELIVER_LMS_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer)); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice())); + } + + saveSystemLog("[LMS] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("LMS"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(LmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + connectUserDto.updateLastTrafficTime(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvMmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(MmsMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(MmsMessage.getMessageForDeliver(deliverBuffer)); + String fileCount = MessageUtil.doNumber(MmsMessage.getFileCountForDeliver(deliverBuffer)); + int recvFileCount = 0; + if (fileCount != null && fileCount.length() > 0) { + recvFileCount = Integer.parseInt(fileCount); + messageDto.setUserFileCnt(recvFileCount); + } + + String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile"; + imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); + FileUtil.mkdirs(imagePath); + + for (int i = 0; i < recvFileCount; i++) { + ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH); + channel.read(fileHeadBuffer); + String fileName = MmsMessage.getFileNameForDeliver(fileHeadBuffer); + String fileSize = MmsMessage.getFileSizeForDeliver(fileHeadBuffer); + ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); + channel.read(fileBuffer); + fileBuffer.flip(); + JobFileFactory.saveFileForByteBuffer(imagePath, fileName, fileBuffer); + if (i == 0) { + messageDto.setUserFileName01(imagePath + File.separator + fileName); + } else if (i == 1) { + messageDto.setUserFileName02(imagePath + File.separator + fileName); + } else if (i == 2) { + messageDto.setUserFileName03(imagePath + File.separator + fileName); + } + saveSystemLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]"); + } + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode()); + float mmsPrice = 0.0F; + if (recvFileCount == 1) { + mmsPrice = savedMemberDto.getPicturePrice(); + } else if (recvFileCount == 2) { + mmsPrice = savedMemberDto.getPicture2Price(); + } else { + mmsPrice = savedMemberDto.getPicture3Price(); + } + messageDto.setUnitCost(String.valueOf(mmsPrice)); + } + + saveSystemLog("[MMS] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("MMS"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(MmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + connectUserDto.updateLastTrafficTime(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvKatDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); + messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); + messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); + + String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; + jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); + FileUtil.mkdirs(jsonPath); + + ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); + channel.read(fileHeadBuffer); + + String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); + String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); + + ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); + channel.read(fileBuffer); + fileBuffer.flip(); + JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); + + messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); + saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice())); + } + + saveSystemLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("KAT"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + connectUserDto.updateLastTrafficTime(); + } else { + saveSystemLog("worker is null"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvKftDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); + messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); + messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); + + String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; + jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); + FileUtil.mkdirs(jsonPath); + + ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); + channel.read(fileHeadBuffer); + + String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); + String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); + + ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); + channel.read(fileBuffer); + fileBuffer.flip(); + JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); + + messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); + saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice())); + } + + saveSystemLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("KFT"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + connectUserDto.updateLastTrafficTime(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvLinkCheck(SocketChannel channel) throws IOException { + ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH); + channel.read(bodyBuffer); +// SocketChannel channel = (SocketChannel) key.channel(); + channel.write(LinkCheck.makeLinkCheckAckBuffer()); + connectUserDto.updateLastTrafficTime(); + /* 서비스 중지여부 체크 */ + if (isExpireService()) { + expireConnectUser(); + return; + } + } + + private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { + String resultCode = "00"; + try { + ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); + ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); + channel.read(bodyBuffer); + Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); + + String id = Bind.getBindId(bindBuffer); + String pwd = Bind.getBindPwd(bindBuffer); + + MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); + MemberDto memberDto = null; + if (svc != null) { + memberDto = svc.get(id); + } + saveSystemLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); + /* Bind Check */ + resultCode = checkBind(memberDto, this.serviceType, id, pwd); + + /* 접속 IP 체크 */ + if ("00".equals(resultCode)) { + boolean isPermit = false; + if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { + saveSystemLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP()); + saveSystemLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); + saveSystemLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); + if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { + isPermit = true; + } + if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { + isPermit = true; + } + } else { + isPermit = true; + } + if (isPermit) { + resultCode = "00"; + } else { + resultCode = "40"; + } + } + if ("00".equals(resultCode)) { + connectUserDto.setUserId(id); + connectUserDto.setLogin(true); + connectUserDto.setMemberDto(memberDto); + /* 사용자 Pool에 저장 */ + collectUserQueue.putUser(this.serviceType, connectUserDto); + /* 세션통신 시간 업데이트 */ + connectUserDto.updateLastTrafficTime(); + } + } catch (Exception e) { + resultCode = "10"; + e.printStackTrace(); + } + + try { + saveSystemLog("[BIND RESULT : " + resultCode + "]"); + channel.write(Bind.makeBindAckBuffer(resultCode)); + if ("00".equals(resultCode) == false) { + expireConnectUser(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String checkBind(MemberDto memberDto, String serviceType, String id, String pwd) { + if (id == null || pwd == null) { + return "50"; + } + if (collectUserQueue.isExist(this.serviceType, id)) { + return "60"; + } + if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { + return "20"; + } + /* 회원 사용 상태 */ + if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { + return "30"; + } + /* 서비스 이용 상태 */ + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return "30"; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return "30"; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return "30"; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return "30"; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return "30"; + } + + return "00"; + } + + private String checkService(MemberDto memberDto, String serviceType) { + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return "30"; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return "30"; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return "30"; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return "30"; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return "30"; + } + + return "00"; + } + + private void expireConnectUser() { + if (key == null || !key.isValid()) { + return; + } + try { + SocketChannel channel = (SocketChannel) key.channel(); + if (connectUserDto != null) { + if (connectUserDto.getUserId() != null) { + collectUserQueue.removeUser(connectUserDto.getServiceType(), connectUserDto.getUserId()); + } + key.attach(null); + } + /* 세션 만료 여부 */ + this.isExpiredYn = true; + // 소켓 채널 닫기 + channel.close(); + // 키 닫기 + key.cancel(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void saveSystemLog(Object obj) { + saveLog(obj, true); + } + + private void saveLog(Object obj) { + saveLog(obj, false); + } + + private void saveLog(Object obj, boolean isConsoleOutput) { + if (isConsoleOutput) { + System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj); + } + + if (logger == null) { + return; + } + + logger.log(obj); + } +} diff --git a/src/main/java/com/munjaon/server/server/task/ReportQueueTask.java b/src/main/java/com/munjaon/server/server/task/ReportQueueTask.java index 37ff10b..bc1704d 100644 --- a/src/main/java/com/munjaon/server/server/task/ReportQueueTask.java +++ b/src/main/java/com/munjaon/server/server/task/ReportQueueTask.java @@ -36,6 +36,16 @@ public class ReportQueueTask implements Runnable { } ReportQueue reportQueue = reportUserDto.getReportQueue(); + /* 리포트큐에 최대 크기까지 쓰고 모두 리포트는 전송했는지 체크 : 테스트후 적용 */ +// if (reportQueue.isWriteLimit(reportUserDto.getMaxWriteCount())) { +// if (reportQueue.isTruncateQueue(reportUserDto.getMaxWriteCount())) { +// try { +// reportQueue.truncateQueue(); +// } catch (Exception e) {} +// } else { +// return; +// } +// } ReportService reportService = (ReportService) CacheService.REPORT_SERVICE.getService(); List list = reportService.getReportListForUser(reportUserDto.getUserId()); if (list == null || list.isEmpty()) { diff --git a/src/main/java/com/munjaon/server/server/task/ReportReadTask.java b/src/main/java/com/munjaon/server/server/task/ReportReadTask.java index 416f823..5cb1179 100644 --- a/src/main/java/com/munjaon/server/server/task/ReportReadTask.java +++ b/src/main/java/com/munjaon/server/server/task/ReportReadTask.java @@ -87,21 +87,112 @@ public class ReportReadTask implements Callable { private void recvReport(SocketChannel channel, ByteBuffer headBuffer) { try { ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH); - saveSystemLog("recv report"); int size = channel.read(bodyBuffer); - if (size > 0) { - ReportQueue reportQueue = reportUserDto.getReportQueue(); - reportUserDto.updateLastTrafficTime(); - if (reportQueue != null) { - reportQueue.addReadCounter(); - } + if (size != Report.REPORT_ACK_BODY_LENGTH) { + return; + } + + saveSystemLog("recv report"); + ReportQueue reportQueue = reportUserDto.getReportQueue(); + reportUserDto.updateLastTrafficTime(); + if (reportQueue != null) { + reportQueue.addReadCounter(); } } catch (Exception e) { e.printStackTrace(); } } + private String checkBind(MemberDto memberDto, String id, String pwd) { + if (id == null || pwd == null) { + return "50"; + } + if (reportUserQueue.isExist(id)) { + return "60"; + } + if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { + return "20"; + } + /* 회원 사용 상태 */ + if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { + return "30"; + } + + return "00"; + } + private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { + String resultCode = "00"; + try { + ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); + ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); + channel.read(bodyBuffer); + Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); + + String id = Bind.getBindId(bindBuffer); + String pwd = Bind.getBindPwd(bindBuffer); + + MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); + MemberDto memberDto = null; + if (svc != null) { + memberDto = svc.get(id); + } + saveSystemLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); + /* Bind Check */ + resultCode = checkBind(memberDto, id, pwd); + + /* 접속 IP 체크 */ + if ("00".equals(resultCode)) { + boolean isPermit = false; + if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { + saveSystemLog("connectUserDto.getRemoteIP() : " + reportUserDto.getRemoteIP()); + saveSystemLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); + saveSystemLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); + if (memberDto.getAllowIpBasic() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { + isPermit = true; + } + if (memberDto.getAllowIpExtend() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { + isPermit = true; + } + } else { + isPermit = true; + } + if (isPermit) { + resultCode = "00"; + } else { + resultCode = "40"; + } + } + + if ("00".equals(resultCode)) { + reportUserDto.setUserId(id); + reportUserDto.setLogin(true); + reportUserDto.setMemberDto(memberDto); + /* 리포트 큐 생성 */ + ReportQueue reportQueue = new ReportQueue(reportUserDto.getQueuePath(), reportUserDto.getUserId()); + reportUserDto.setReportQueue(reportQueue); + /* 사용자 Pool에 저장 */ + reportUserQueue.putUser(reportUserDto); + /* 세션통신 시간 업데이트 */ + reportUserDto.updateLastTrafficTime(); + } + } catch (Exception e) { + resultCode = "10"; + e.printStackTrace(); + } + + try { + saveSystemLog("Bind ResultCode : " + resultCode); + channel.write(Bind.makeBindAckBuffer(resultCode)); + if ("00".equals(resultCode) == false) { + expireConnectUser(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void recvBind_bak(SocketChannel channel, ByteBuffer headBuffer) { String resultCode = "00"; try { ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); diff --git a/src/main/java/com/munjaon/server/server/task/ReportServerTask.java b/src/main/java/com/munjaon/server/server/task/ReportServerTask.java new file mode 100644 index 0000000..a7bc13d --- /dev/null +++ b/src/main/java/com/munjaon/server/server/task/ReportServerTask.java @@ -0,0 +1,219 @@ +package com.munjaon.server.server.task; + +import com.munjaon.server.queue.pool.ReportQueue; +import com.munjaon.server.server.config.ServerConfig; +import com.munjaon.server.server.dto.ReportDto; +import com.munjaon.server.server.dto.ReportUserDto; +import com.munjaon.server.server.packet.Header; +import com.munjaon.server.server.packet.LinkCheck; +import com.munjaon.server.server.packet.Packet; +import com.munjaon.server.server.packet.Report; +import com.munjaon.server.server.queue.ReportUserQueue; +import com.munjaon.server.server.service.PropertyLoader; +import com.munjaon.server.util.LogUtil; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class ReportServerTask implements Runnable { + public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); + public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; + + private Selector selector; + private SelectionKey key; + private SocketChannel channel; + private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); + private ReportUserDto reportUserDto; + private ReportQueue reportQueue; + private String serviceName; + private final LogUtil logger; + + private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부 + private boolean IS_RUN_YN; + private long RUN_FLAG_CHECK_TIME; + + /* 세션이 만료되었는지 체크 */ + private boolean isExpiredYn; + /* Packet을 전송했는지 여부 */ + private boolean isPacketSendYn; + + public ReportServerTask(Selector selector, SelectionKey key, String serviceName, LogUtil logger) { + this.selector = selector; + this.key = key; + this.channel = (SocketChannel) key.channel(); + this.reportUserDto = (ReportUserDto) key.attachment(); + this.reportUserDto.setRunningMode(true); + this.serviceName = serviceName; + this.reportQueue = reportUserDto.getReportQueue(); + this.logger = logger; + } + + protected String getProp(String name) { + return getProp(this.serviceName, name); + } + + public static String getProp(String svc, String name) { + return PropertyLoader.getProp(svc, name); + } + + private void reloadRunFlag() { + if (System.currentTimeMillis() - RUN_FLAG_CHECK_TIME > ServerConfig.INTERVAL_PROPERTY_RELOAD_TIME) { + this.IS_RUN_YN = getProp("RUN_FLAG") != null && "Y".equals(getProp("RUN_FLAG")); + this.IS_SERVER_RUN = getProp("server", "run") != null && "Y".equals(getProp("server", "run")); + RUN_FLAG_CHECK_TIME = System.currentTimeMillis(); + } + } + + public boolean isRun() { + return IS_SERVER_RUN && IS_RUN_YN; + } + + @Override + public void run() { + saveSystemLog("ReportServerTask is Entered"); + /* 최초 RUN Flag 체크 */ + reloadRunFlag(); + /* BIND 체크 및 처리 */ + while (isRun()) { + /* 만료 여부 체크 */ + if (isExpiredYn) { + break; + } + + try { + sendInterest(); + /* RUN Flag 체크 */ + reloadRunFlag(); + } catch (Exception e) { + this.isExpiredYn = true; + e.printStackTrace(); + } + } + /* 중요 : 사용자 Thread 실행모드 Off */ + reportUserDto.setRunningMode(false); + saveSystemLog("ReportServerTask is Finished"); + } + +// private void recvInterest() { +// while (isPacketSendYn) { +// +// } +// int size = -1; +// try { +// /* 1. Head 읽기 */ +// ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); +// try { +// size = channel.read(headBuffer); +// } catch (IOException e) {} +// /* 2. Body 읽기 */ +// if (size > 0) { +// String command = Header.getCommand(headBuffer); +// switch (Integer.parseInt(command)) { +// case 1: +// recvBind(channel, headBuffer); +// break; +// case 3: +// recvDeliver(channel, headBuffer); +// break; +// case 7: +// recvLinkCheck(channel); +// break; +// default: +// expireConnectUser(); +// break; +// } +// } else if (size == 0) { +// Thread.sleep(1); +// if (System.currentTimeMillis() - reportUserDto.getLastTrafficTime() > ServerConfig.REPORT_EXEC_CYCLE_TIME) { +// this.isExpiredYn = true; +// } +// } else { +// expireConnectUser(); +// } +// } catch (Exception e) { +// size = -1; +// e.printStackTrace(); +// } +// } + + private void sendInterest() throws IOException { + if (reportUserDto.isLogin() == false) { + return; + } + if (reportUserDto.isAlive() == 1) { + expireConnectUser(); + } else if (reportUserDto.isAlive() == 2) { + channel.write(LinkCheck.makeLinkCheckBuffer()); + /* Packet을 전송했는지 여부 */ + isPacketSendYn = true; + } else { + if (this.reportQueue != null && this.reportQueue.isRemainReport()) { + try { + ReportDto reportDto = this.reportQueue.popReportFromQueue(); + if (reportDto == null) { + return; + } + saveSystemLog("[REPORT : " + reportDto.toString() + "]"); + ByteBuffer reportBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH); + Packet.setDefaultByte(reportBuffer); + Header.putHeader(reportBuffer, Header.COMMAND_REPORT, Report.REPORT_BODY_LENGTH); + Report.putReport(reportBuffer, reportDto); + channel.write(reportBuffer); + /* Packet을 전송했는지 여부 */ + isPacketSendYn = true; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + private void expireConnectUser() { + if (key == null || !key.isValid()) { + return; + } + try { + SocketChannel channel = (SocketChannel) key.channel(); + if (reportUserDto != null) { + if (reportUserDto.getUserId() != null) { + reportUserQueue.removeUser(reportUserDto.getUserId()); + } + key.attach(null); + } + /* 세션 만료 여부 */ + this.isExpiredYn = true; + // 소켓 채널 닫기 + channel.close(); + // 키 닫기 + key.cancel(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void saveSystemLog(Object obj) { + saveLog(obj, true); + } + + private void saveLog(Object obj) { + saveLog(obj, false); + } + + private void saveLog(Object obj, boolean isConsoleOutput) { + if (isConsoleOutput) { + System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj); + } + + if (logger == null) { + return; + } + + logger.log(obj); + } +} diff --git a/src/main/java/com/munjaon/server/server/task/SendReadTask.java b/src/main/java/com/munjaon/server/server/task/SendReadTask.java new file mode 100644 index 0000000..452e9fb --- /dev/null +++ b/src/main/java/com/munjaon/server/server/task/SendReadTask.java @@ -0,0 +1,564 @@ +package com.munjaon.server.server.task; + +import com.munjaon.server.cache.dto.MemberDto; +import com.munjaon.server.cache.enums.CacheService; +import com.munjaon.server.cache.service.MemberService; +import com.munjaon.server.queue.dto.BasicMessageDto; +import com.munjaon.server.queue.enums.QueueTypeWorker; +import com.munjaon.server.server.dto.ConnectUserDto; +import com.munjaon.server.server.packet.*; +import com.munjaon.server.server.queue.CollectUserQueue; +import com.munjaon.server.util.*; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class SendReadTask implements Runnable { + public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); + public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; + + private Selector selector; + private SelectionKey key; + private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); + private ConnectUserDto connectUserDto; + private String serviceType; + private final LogUtil logger; + + public SendReadTask(Selector selector, SelectionKey key, String serviceType, LogUtil logger) { + this.selector = selector; + this.key = key; + this.connectUserDto = (ConnectUserDto) key.attachment(); + this.serviceType = serviceType; + this.logger = logger; + } + + @Override + public void run() { + System.out.println("SendReadTask start : " + Thread.currentThread().getName()); + int size = -1; + try { + SocketChannel channel = (SocketChannel) key.channel(); + /* 1. Head 읽기 */ + ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); + try { + size = channel.read(headBuffer); + } catch (IOException e) {} + /* 2. Body 읽기 */ + if (size > 0) { +// Packet.printBuffer(headBuffer); + String command = Header.getCommand(headBuffer); + switch (Integer.parseInt(command)) { + case 1 : recvBind(channel, headBuffer); break; + case 3 : recvDeliver(channel, headBuffer); break; + case 7 : recvLinkCheck(channel); break; + default: expireConnectUser(); break; + } + } else { + expireConnectUser(); + } + } catch (Exception e) { + size = -1; + e.printStackTrace(); + } + } + + private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + /* 서비스 중지여부 체크 */ + if (isExpireService()) { + expireConnectUser(); + return; + } + switch (this.serviceType) { + case "SMS": + recvSmsDeliver(channel, headBuffer); + break; + case "LMS": + recvLmsDeliver(channel, headBuffer); + break; + case "MMS": + recvMmsDeliver(channel, headBuffer); + break; + case "KAT": + recvKatDeliver(channel, headBuffer); + break; + case "KFT": + recvKftDeliver(channel, headBuffer); + break; + default:break; + } + } + + private boolean isExpireService() { + ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId()); + MemberDto memberDto = checkConnectUserDto.getMemberDto(); + saveSystemLog("[isExpireService : " + memberDto.toString() + "]"); + if (memberDto == null) { + return true; + } + if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) { + return true; + } + /* 회원 사용 상태 */ + if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { + return true; + } + /* 서비스 이용 상태 */ + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return true; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return true; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return true; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return true; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return true; + } + + return false; + } + + public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) { + if (deliverBuffer == null) { + return null; + } + BasicMessageDto messageDto = new BasicMessageDto(); + messageDto.setRouterSeq("40"); + messageDto.setServiceType("4"); + messageDto.setUserId(connectUserDto.getUserId()); + messageDto.setRemoteIP(connectUserDto.getRemoteIP()); + messageDto.setSendStatus("0"); + messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(deliverBuffer)); + messageDto.setUserSender(CommonMessage.getSenderForDeliver(deliverBuffer)); + messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(deliverBuffer)); + messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(deliverBuffer)); + messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(deliverBuffer)); + messageDto.setUnitCost("10.4"); + + return messageDto; + } + + private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + SmsMessage.DELIVER_SMS_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + +// Packet.printBuffer(deliverBuffer); + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer)); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice())); + } + + saveSystemLog("[SMS] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("SMS"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvLmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(LmsMessage.DELIVER_LMS_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + LmsMessage.DELIVER_LMS_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer)); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice())); + } + + saveSystemLog("[LMS] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("LMS"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(LmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvMmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(MmsMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(MmsMessage.getMessageForDeliver(deliverBuffer)); + String fileCount = MessageUtil.doNumber(MmsMessage.getFileCountForDeliver(deliverBuffer)); + int recvFileCount = 0; + if (fileCount != null && fileCount.length() > 0) { + recvFileCount = Integer.parseInt(fileCount); + messageDto.setUserFileCnt(recvFileCount); + } + + String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile"; + imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); + FileUtil.mkdirs(imagePath); + + for (int i = 0; i < recvFileCount; i++) { + ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH); + channel.read(fileHeadBuffer); + String fileName = MmsMessage.getFileNameForDeliver(fileHeadBuffer); + String fileSize = MmsMessage.getFileSizeForDeliver(fileHeadBuffer); + ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); + channel.read(fileBuffer); + fileBuffer.flip(); + JobFileFactory.saveFileForByteBuffer(imagePath, fileName, fileBuffer); + if (i == 0) { + messageDto.setUserFileName01(imagePath + File.separator + fileName); + } else if (i == 1) { + messageDto.setUserFileName02(imagePath + File.separator + fileName); + } else if (i == 2) { + messageDto.setUserFileName03(imagePath + File.separator + fileName); + } + saveSystemLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]"); + } + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode()); + float mmsPrice = 0.0F; + if (recvFileCount == 1) { + mmsPrice = savedMemberDto.getPicturePrice(); + } else if (recvFileCount == 2) { + mmsPrice = savedMemberDto.getPicture2Price(); + } else { + mmsPrice = savedMemberDto.getPicture3Price(); + } + messageDto.setUnitCost(String.valueOf(mmsPrice)); + } + + saveSystemLog("[MMS] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("MMS"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(MmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvKatDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); + messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); + messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); + + String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; + jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); + FileUtil.mkdirs(jsonPath); + + ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); + channel.read(fileHeadBuffer); + + String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); + String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); + + ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); + channel.read(fileBuffer); + fileBuffer.flip(); + JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); + + messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); + saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice())); + } + + saveSystemLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("KAT"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + } else { + saveSystemLog("worker is null"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvKftDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { + try { + ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + channel.read(bodyBuffer); + ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); + Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); + + BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); + messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); + messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); + messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); + messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); + + String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; + jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); + FileUtil.mkdirs(jsonPath); + + ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); + channel.read(fileHeadBuffer); + + String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); + String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); + + ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); + channel.read(fileBuffer); + fileBuffer.flip(); + JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); + + messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); + saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); + + /* 사용자 단가, 발송망 설정 */ + MemberDto savedMemberDto = null; + if (this.connectUserDto != null) { + savedMemberDto = this.connectUserDto.getMemberDto(); + } + if (savedMemberDto != null) { + messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode()); + messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice())); + } + + saveSystemLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]"); + QueueTypeWorker worker = QueueTypeWorker.find("KFT"); + if (worker != null) { + worker.pushQueue(messageDto); + channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void recvLinkCheck(SocketChannel channel) throws IOException { + ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH); + channel.read(bodyBuffer); +// SocketChannel channel = (SocketChannel) key.channel(); + channel.write(LinkCheck.makeLinkCheckAckBuffer()); + /* 서비스 중지여부 체크 */ + if (isExpireService()) { + expireConnectUser(); + return; + } + } + + private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { + String resultCode = "00"; + try { + ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); + ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); + channel.read(bodyBuffer); + Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); + + String id = Bind.getBindId(bindBuffer); + String pwd = Bind.getBindPwd(bindBuffer); + + MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); + MemberDto memberDto = null; + if (svc != null) { + memberDto = svc.get(id); + } + saveSystemLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); + /* Bind Check */ + resultCode = checkBind(memberDto, this.serviceType, id, pwd); + + /* 접속 IP 체크 */ + if ("00".equals(resultCode)) { + boolean isPermit = false; + if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { + saveSystemLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP()); + saveSystemLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); + saveSystemLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); + if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { + isPermit = true; + } + if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { + isPermit = true; + } + } else { + isPermit = true; + } + if (isPermit) { + resultCode = "00"; + } else { + resultCode = "40"; + } + } + if ("00".equals(resultCode)) { + connectUserDto.setUserId(id); + connectUserDto.setLogin(true); + connectUserDto.setMemberDto(memberDto); + /* 사용자 Pool에 저장 */ + collectUserQueue.putUser(this.serviceType, connectUserDto); + /* 세션통신 시간 업데이트 */ + connectUserDto.updateLastTrafficTime(); + } + } catch (Exception e) { + resultCode = "10"; + e.printStackTrace(); + } + + try { + saveSystemLog("[BIND RESULT : " + resultCode + "]"); + channel.write(Bind.makeBindAckBuffer(resultCode)); + if ("00".equals(resultCode) == false) { + expireConnectUser(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String checkBind(MemberDto memberDto, String serviceType, String id, String pwd) { + if (id == null || pwd == null) { + return "50"; + } + if (collectUserQueue.isExist(this.serviceType, id)) { + return "60"; + } + if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { + return "20"; + } + /* 회원 사용 상태 */ + if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { + return "30"; + } + /* 서비스 이용 상태 */ + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return "30"; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return "30"; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return "30"; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return "30"; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return "30"; + } + + return "00"; + } + + private String checkService(MemberDto memberDto, String serviceType) { + if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { + return "30"; + } + if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { + return "30"; + } + if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { + return "30"; + } + if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { + return "30"; + } + if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { + return "30"; + } + + return "00"; + } + + private void expireConnectUser() { + if (key == null || !key.isValid()) { + return; + } + try { + SocketChannel channel = (SocketChannel) key.channel(); + if (connectUserDto != null) { + if (connectUserDto.getUserId() != null) { + collectUserQueue.removeUser(connectUserDto.getServiceType(), connectUserDto.getUserId()); + } + key.attach(null); + } + // 소켓 채널 닫기 + channel.close(); + // 키 닫기 + key.cancel(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void saveSystemLog(Object obj) { + saveLog(obj, true); + } + + private void saveLog(Object obj) { + saveLog(obj, false); + } + + private void saveLog(Object obj, boolean isConsoleOutput) { + if (isConsoleOutput) { + System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj); + } + + if (logger == null) { + return; + } + + logger.log(obj); + } +} diff --git a/src/main/java/com/munjaon/server/server/task/StatusCheckTask.java b/src/main/java/com/munjaon/server/server/task/StatusCheckTask.java new file mode 100644 index 0000000..d16eaea --- /dev/null +++ b/src/main/java/com/munjaon/server/server/task/StatusCheckTask.java @@ -0,0 +1,76 @@ +package com.munjaon.server.server.task; + +import com.munjaon.server.cache.dto.MemberDto; +import com.munjaon.server.cache.enums.CacheService; +import com.munjaon.server.cache.service.MemberService; +import com.munjaon.server.server.dto.ConnectUserDto; +import com.munjaon.server.server.queue.CollectUserQueue; +import com.munjaon.server.util.LogUtil; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +public class StatusCheckTask implements Runnable { + public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); + public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; + + private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); + private String serviceType; + private final LogUtil logger; + + public StatusCheckTask(String serviceType, LogUtil logger) { + this.serviceType = serviceType; + this.logger = logger; + } + + @Override + public void run() { + saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is starting ... ...]"); + List userList = collectUserQueue.getUsers(this.serviceType); + if (userList == null && userList.isEmpty()) { + saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is empty ... ...]"); + saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is ended ... ...]"); + return; + } + + MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); + for (ConnectUserDto user : userList) { + MemberDto savedMemberDto = user.getMemberDto(); + saveSystemLog("[" + this.serviceType + "][USER PREVIOUS STATUS : " + savedMemberDto.toString() + "]"); + if (savedMemberDto == null) { + continue; + } + MemberDto newMemberDto = svc.get(savedMemberDto.getMberId()); + saveSystemLog("[" + this.serviceType + "][USER NEW STATUS : " + newMemberDto.toString() + "]"); + if (newMemberDto == null) { + savedMemberDto.setMberSttus("N"); + } else { + user.setMemberDto(newMemberDto); + } + saveSystemLog("[" + this.serviceType + "][USER AFTER STATUS : " + savedMemberDto.toString() + "]"); + } + saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is ended ... ...]"); + } + + private void saveSystemLog(Object obj) { + saveLog(obj, true); + } + + private void saveLog(Object obj) { + saveLog(obj, false); + } + + private void saveLog(Object obj, boolean isConsoleOutput) { + if (isConsoleOutput) { + System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{StatusCheckTask}} " + obj); + } + + if (logger == null) { + return; + } + + logger.log(obj); + } +} diff --git a/src/main/java/com/munjaon/server/util/MessageUtil.java b/src/main/java/com/munjaon/server/util/MessageUtil.java index eba9bfd..1f71edb 100644 --- a/src/main/java/com/munjaon/server/util/MessageUtil.java +++ b/src/main/java/com/munjaon/server/util/MessageUtil.java @@ -501,4 +501,16 @@ public final class MessageUtil { return reportDto; } + + public static String makeMessageKey(String msgId) { + if (msgId == null || msgId.trim().isEmpty() || msgId.trim().length() > 14) { + return "MSGID_" + SerialNoUtil.getSerialNo(); + } + String lpad = ""; + for (int i = 0, size = 14 - msgId.trim().length(); i < size; i++) { + lpad += "0"; + } + + return "MSGID_" + lpad + msgId.trim(); + } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ea3d1c8..94bd1c7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,6 +4,10 @@ spring: profiles: default: local +logging: + level: + root: info + mybatis: configuration: map-underscore-to-camel-case: true diff --git a/src/main/resources/dev/application-dev.yml b/src/main/resources/dev/application-dev.yml index 783e38f..f4fc8ad 100644 --- a/src/main/resources/dev/application-dev.yml +++ b/src/main/resources/dev/application-dev.yml @@ -2,7 +2,9 @@ spring: datasource: server: driver-class-name: org.mariadb.jdbc.Driver - jdbc-url: jdbc:mariadb://119.193.215.98:3306/mjon_agent_back + url: jdbc:mariadb://192.168.0.125:3306/mjon_agent_back + jdbc-url: jdbc:mariadb://192.168.0.125:3306/mjon_agent_back +# jdbc-url: jdbc:mariadb://119.193.215.98:3306/mjon_agent_back username: mjonUr_agent password: mjagent123$ diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 704d5bc..7e1f61a 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -10,7 +10,7 @@ ${LOG_PATTERN} - + diff --git a/src/main/resources/prod/application-prod.yml b/src/main/resources/prod/application-prod.yml index 38c854c..3516d8d 100644 --- a/src/main/resources/prod/application-prod.yml +++ b/src/main/resources/prod/application-prod.yml @@ -2,6 +2,7 @@ spring: datasource: server: driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://119.193.215.98:3306/mjon_agent jdbc-url: jdbc:mariadb://119.193.215.98:3306/mjon_agent username: mjonUr_agent password: mjagent123$ diff --git a/src/main/resources/sqlmap/kat_sql.xml b/src/main/resources/sqlmap/kat_sql.xml index bdc1fec..5fff119 100644 --- a/src/main/resources/sqlmap/kat_sql.xml +++ b/src/main/resources/sqlmap/kat_sql.xml @@ -21,6 +21,22 @@ , BIZ_KAKAO_RESEND_DATA , BIZ_KAKAO_RESEND_TYPE , BIZ_KAKAO_JSON_FILE - ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '8', 'N', null, null, #{kakaoJsonFile}) + ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '8', 'N', null, null, #{kakaoJsonFile}) + + + + INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, MSG_NOTICETALK_SENDER_KEY, MSG_NOTICETALK_TMP_KEY, REQ_DATE, CALL_TO, CALL_FROM, SMS_TXT, BIZ_KAKAO_TITLE, MSG_TYPE, BIZ_KAKAO_RESEND_YN, BIZ_KAKAO_RESEND_DATA, BIZ_KAKAO_RESEND_TYPE, BIZ_KAKAO_JSON_FILE) + VALUES + + (#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, #{item.kakaoSenderKey}, #{item.kakaoTemplateCode}, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, '8', 'N', null, null, #{item.kakaoJsonFile}) + + + + + INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT) + VALUES + + (#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '8', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'Y', '' ) + \ No newline at end of file diff --git a/src/main/resources/sqlmap/kft_sql.xml b/src/main/resources/sqlmap/kft_sql.xml index c044ed5..caa0661 100644 --- a/src/main/resources/sqlmap/kft_sql.xml +++ b/src/main/resources/sqlmap/kft_sql.xml @@ -20,6 +20,22 @@ , BIZ_KAKAO_RESEND_DATA , BIZ_KAKAO_RESEND_TYPE , BIZ_KAKAO_JSON_FILE - ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '9', 'N', null, null, #{kakaoJsonFile}) + ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '9', 'N', null, null, #{kakaoJsonFile}) + + + + INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, MSG_NOTICETALK_SENDER_KEY, MSG_NOTICETALK_TMP_KEY, REQ_DATE, CALL_TO, CALL_FROM, SMS_TXT, BIZ_KAKAO_TITLE, MSG_TYPE, BIZ_KAKAO_RESEND_YN, BIZ_KAKAO_RESEND_DATA, BIZ_KAKAO_RESEND_TYPE, BIZ_KAKAO_JSON_FILE) + VALUES + + (#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, #{item.kakaoSenderKey}, #{item.kakaoTemplateCode}, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, '8', 'N', null, null, #{item.kakaoJsonFile}) + + + + + INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT) + VALUES + + (#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '9', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'Y', '' ) + \ No newline at end of file diff --git a/src/main/resources/sqlmap/lms_sql.xml b/src/main/resources/sqlmap/lms_sql.xml index 4de94a2..939d98a 100644 --- a/src/main/resources/sqlmap/lms_sql.xml +++ b/src/main/resources/sqlmap/lms_sql.xml @@ -16,6 +16,22 @@ , SMS_TXT , MSG_TYPE , CONT_SEQ, FILE_CNT - ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, '0' ) + ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, '0' ) + + + + INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, REQ_DATE, CALL_TO, CALL_FROM, SUBJECT, SMS_TXT, MSG_TYPE, CONT_SEQ, FILE_CNT) + VALUES + + (#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userSubject}, #{item.userMessage}, '6', null, '0' ) + + + + + INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT) + VALUES + + (#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '6', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'N', '' ) + \ No newline at end of file diff --git a/src/main/resources/sqlmap/mms_sql.xml b/src/main/resources/sqlmap/mms_sql.xml index 63ea0b9..fb6de91 100644 --- a/src/main/resources/sqlmap/mms_sql.xml +++ b/src/main/resources/sqlmap/mms_sql.xml @@ -21,6 +21,22 @@ , FILE_PATH2 , FILE_PATH3 , NEO_TYPE - ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, #{userFileCnt}, #{userFileName01}, #{userFileName02}, #{userFileName03}, null) + ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, #{userFileCnt}, #{userFileName01}, #{userFileName02}, #{userFileName03}, null) + + + + INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, REQ_DATE, CALL_TO, CALL_FROM, SUBJECT, SMS_TXT, MSG_TYPE, CONT_SEQ, FILE_CNT, FILE_PATH1, FILE_PATH2, FILE_PATH3, NEO_TYPE) + VALUES + + (#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userSubject}, #{item.userMessage}, '6', null, #{item.userFileCnt}, #{item.userFileName01}, #{item.userFileName02}, #{item.userFileName03}, null) + + + + + INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT) + VALUES + + (#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '6', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, #{item.userFileCnt}, '0.0', NULL, NULL, 'N', '' ) + \ No newline at end of file diff --git a/src/main/resources/sqlmap/sms_sql.xml b/src/main/resources/sqlmap/sms_sql.xml index 0c1050e..3a88a4b 100644 --- a/src/main/resources/sqlmap/sms_sql.xml +++ b/src/main/resources/sqlmap/sms_sql.xml @@ -15,6 +15,22 @@ , SUBJECT , SMS_TXT , MSG_TYPE - )VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, NOW(), #{userReceiver}, #{userSender}, NULL, #{userMessage}, '4' ) + )VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, NOW(), #{userReceiver}, #{userSender}, NULL, #{userMessage}, '4' ) + + + + INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, REQ_DATE, CALL_TO, CALL_FROM, SUBJECT, SMS_TXT, MSG_TYPE) + VALUES + + (#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, NOW(), #{item.userReceiver}, #{item.userSender}, NULL, #{item.userMessage}, '4' ) + + + + + INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT) + VALUES + + (#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, NULL, NOW(), '1', NULL, '4', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'N', '' ) + \ No newline at end of file