junekeunsong 4 years ago
parent
commit
4ecfd6d02c

+ 27 - 6
src/main/java/com/lemon/lifecenter/scheduler/common/HomeController.java

@@ -1,14 +1,17 @@
 package com.lemon.lifecenter.scheduler.common;
 
 import java.io.IOException;
+import java.util.HashMap;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.lemon.lifecenter.scheduler.controller.PushController;
 import com.lemon.lifecenter.scheduler.test.TestService;
 
 @RestController
@@ -22,6 +25,9 @@ public class HomeController {
     @Autowired
     private TestService service;
     
+    @Autowired
+    private PushController pushController;
+    
     @RequestMapping(value = "/test", method = RequestMethod.GET)
     public String index() {
 //        String result = service.testSelect();
@@ -30,24 +36,39 @@ public class HomeController {
         String title = "오늘의";
         String content = " 점심은??";
         
-        pushUtils.sendFcm("dC7nrWbLRquoaOoWdMAq2x:APA91bFqjD4LIHgoJU6s0ptR0MDqHqw8WxdjxRLsL8lpo5Do-RV8_NZ_MYXDM3xD0ex_Z8zaijvDKXhGvFPIUaZ4Dv8ilZqxcJmC5WXTlYNgetvFihQoQ-w25c4VbheYCXjJG5SXFCY4",
-                title, content);
+        HashMap<String, String> response = new HashMap<>();
         
-        pushUtils.sendFcm("d_N0ErUTTk2QiRCur8-AcA:APA91bGLm2v9F2e4Sl-NIXXtPt6MzXze9NrdV6OltzyBo-DUGI_r9DGicQM6-yQ05T8M4KVN4XqpIkNx6nvbWZ7MKYNeGzs-9r44mjBW2nqApyIVRcFMTHSUhD58xSaumejuiW6K2Diq",
+        response = pushUtils.sendFcm("dC7nrWbLRquoaOoWdMAq2x:APA91bFqjD4LIHgoJU6s0ptR0MDqHqw8WxdjxRLsL8lpo5Do-RV8_NZ_MYXDM3xD0ex_Z8zaijvDKXhGvFPIUaZ4Dv8ilZqxcJmC5WXTlYNgetvFihQoQ-w25c4VbheYCXjJG5SXFCY4",
                 title, content);
         
-        pushUtils.sendFcm("fGKpg4m8SUSiaclDxhDUlS:APA91bFDbbSVtyA3mFFEE7q7DTBYMJkv9E_qBxeCM0lztuE1VyO4RbA1dSc8NC9QLbvV2TGf79eDFpZy2kh-wCkjlYYssIiX0DtIRkqvNgbtfJdosuF0Y8tjlsJua4r4-cAY_xldXsrU",
-                title, content);
+        logger.error("response! -- > " + response);
         
-        pushUtils.sendFcm("fA-RwuMFQJO3E76CuyTqyS:APA91bFaPwatHGIPiRs9MWVPGXb7szXZHUrjPWuRafXjOPLO1BSR5CZgwNuFcXb1x7fFbTnjaF_o7FSPka3ucJ3RJJN0Ujr_rQ2PBMFuGuNtpoy6oWLxltty4nw4_x1zJ-cYi7WsV3t8",
+        response = pushUtils.sendFcm("d_N0ErUTTk2QiRCur8-AcA:APA91bGLm2v9F2e4Sl-NIXXtPt6MzXze9NrdV6OltzyBo-DUGI_r9DGicQM6-yQ05T8M4KVN4XqpIkNx6nvbWZ7MKYNeGzs-9r44mjBW2nqApyIVRcFMTHSUhD58xSaumejuiW6K2Diq",
                 title, content);
         
+        logger.error("response!!!! -- > " + response);
+        
+//        pushUtils.sendFcm("fGKpg4m8SUSiaclDxhDUlS:APA91bFDbbSVtyA3mFFEE7q7DTBYMJkv9E_qBxeCM0lztuE1VyO4RbA1dSc8NC9QLbvV2TGf79eDFpZy2kh-wCkjlYYssIiX0DtIRkqvNgbtfJdosuF0Y8tjlsJua4r4-cAY_xldXsrU",
+//                title, content);
+//        
+//        pushUtils.sendFcm("fA-RwuMFQJO3E76CuyTqyS:APA91bFaPwatHGIPiRs9MWVPGXb7szXZHUrjPWuRafXjOPLO1BSR5CZgwNuFcXb1x7fFbTnjaF_o7FSPka3ucJ3RJJN0Ujr_rQ2PBMFuGuNtpoy6oWLxltty4nw4_x1zJ-cYi7WsV3t8",
+//                title, content);
+        
         pushUtils.sendFcm("cuLTEbJThUvWlaBtvOHqfJ:APA91bEuOtQN6mnw9fqcS5wA6VLSEDulyg54nczI5KNN_0BaQWO-Fn5O92lxycfSdPrw_9wC2mGcH2nkIsWhayv3RXDnXQDAGN5r3uKJ-wrVtM2HC7j7OHGbiuTexwADBAo4ehHJHkZh",
                 title, content);
         
         return "helloWorld";
     }
     
+    /**
+     * fixedDelay 1초 단위
+     * 하루에 한번 결과 테이블이 있는지 확인 후 없으면 생성한다
+     */
+    @Scheduled(fixedDelay=86400)
+    public void createTable() {
+        pushController.createResultTable();
+    }
+    
 //    @Scheduled(fixedDelay=1000)
 //    public void task() {
 //        logger.error("time -- > " + new Date());

+ 18 - 0
src/main/java/com/lemon/lifecenter/scheduler/common/LogbackFilter.java

@@ -0,0 +1,18 @@
+package com.lemon.lifecenter.scheduler.common;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.filter.Filter;
+import ch.qos.logback.core.spi.FilterReply;
+
+public class LogbackFilter  extends Filter<ILoggingEvent> {
+    
+    @Override 
+    public FilterReply decide(ILoggingEvent e) {
+        if (e.getLoggerName().contains("sqlonly") || e.getLoggerName().contains("resultsettable")) {
+            return FilterReply.DENY;
+        } else {
+            return FilterReply.ACCEPT;
+        }
+        
+    }
+}

+ 57 - 28
src/main/java/com/lemon/lifecenter/scheduler/common/PushUtils.java

@@ -2,6 +2,10 @@ package com.lemon.lifecenter.scheduler.common;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.HashMap;
 
 import org.slf4j.Logger;
@@ -10,6 +14,7 @@ import org.springframework.core.io.ClassPathResource;
 import org.springframework.stereotype.Component;
 
 import com.google.auth.oauth2.GoogleCredentials;
+import com.google.firebase.ErrorCode;
 import com.google.firebase.FirebaseApp;
 import com.google.firebase.FirebaseOptions;
 import com.google.firebase.messaging.AndroidConfig;
@@ -29,8 +34,9 @@ public class PushUtils {
     
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
     
-    public void sendFcm(String deviceKey, String title, String content) {
+    public HashMap<String, String> sendFcm(String deviceKey, String title, String content) {
         
+        HashMap<String, String> result = new HashMap<String, String>();
         try {
             ClassPathResource cpr = new ClassPathResource("firebase/firebase_service_key.json");
             FirebaseOptions options = new FirebaseOptions.Builder()
@@ -59,41 +65,64 @@ public class PushUtils {
             String response = FirebaseMessaging.getInstance().send(message);
             logger.error("response -- > " + response);
             
+            result.put("success", "success");
+            return result;
         } catch (FileNotFoundException e) {
-            logger.error("fileNotFound -- > " + e);
-            errorMsg("FileNotFound");
+//            logger.error("fileNotFound -- > " + e);
+            result.put("FileNotFound", "FileNotFound");
         } catch (IOException e) {
-            logger.error("IOException -- > " + e);
-            errorMsg("IOException");
+//            logger.error("IOException -- > " + e);
+            result.put("IOException", "IOException");
         } catch (FirebaseMessagingException e) {
-            logger.error("FirebaseMessagingException -- > " + e);
-            errorMsg(e.getErrorCode().toString().trim());
+//            logger.error("FirebaseMessagingException -- > " + e);
+//            logger.error("FirebaseMessagingException -- > " + e.getErrorCode());
+//            logger.error("FirebaseMessagingException -- > " + e.getMessage());
+//            result = errorMsg(e.getErrorCode().toString().trim());
+            result.put(e.getErrorCode().toString().trim(), e.getMessage());
         }
+        
+        return result;
     }
     
-    private void errorMsg(String e) {
-        String msg = "";
-        if (fcmErrorCode().get(e) != null) {
-            msg = fcmErrorCode().get(e);
-        } else {
-            msg = fcmErrorCode().get("FATAL");
-        }
+//    private String errorMsg(String e) {
+//        String msg = "";
+//        if (fcmErrorCode().get(e) != null) {
+//            msg = fcmErrorCode().get(e);
+//        } else {
+//            msg = fcmErrorCode().get("FATAL");
+//        }
+//        
+//        return msg;
+//    }
+//    
+//    private HashMap<String, String> fcmErrorCode() {
+//         HashMap<String, String> code = new HashMap<String, String>();
+//         code.put("UNSPECIFIED_ERROR", "이 오류에 대한 추가 정보가 없습니다.");
+//         code.put("INVALID_ARGUMENT", "(HTTP 오류 코드 = 400) 요청 매개 변수가 유효하지 않습니다. google.rpc.BadRequest 유형의 확장자가 리턴되어 유효하지 않은 필드를 지정합니다.");
+//         code.put("UNREGISTERED", " (HTTP 오류 코드 = 404) FCM에서 앱 인스턴스가 등록 해제되었습니다. 이것은 일반적으로 사용 된 토큰이 더 이상 유효하지 않으며 새로운 토큰을 사용해야 함을 의미합니다.");
+//         code.put("SENDER_ID_MISMATCH", "(HTTP 오류 코드 = 403) 인증 된 발신자 ID가 등록 토큰의 발신자 ID와 다릅니다.");
+//         code.put("QUOTA_EXCEEDED", "(HTTP 오류 코드 = 429) 메시지 대상에 대한 전송 제한이 초과되었습니다. 초과 한 할당량을 지정하기 위해 google.rpc.QuotaFailure 유형의 확장이 반환됩니다..");
+//         code.put("UNAVAILABLE", "  (HTTP 오류 코드 = 503) 서버가 과부하되었습니다.");
+//         code.put("INTERNAL", "(HTTP 오류 코드 = 500) 알 수없는 내부 오류가 발생했습니다.");
+//         code.put("THIRD_PARTY_AUTH_ERROR", "(HTTP 오류 코드 = 401) APN 인증서 또는 웹 푸시 인증 키가 잘못되었거나 없습니다.");
+//         code.put("FATAL", "알수없는 오류");
+//         code.put("FileNotFound", "FileNotFound");
+//         code.put("IOException", "IOException");
+//         return code;
+//    }
+    
+    public String getNowYm() {
+        DateFormat dateFormat = new SimpleDateFormat("yyyyMM");
+        Date date = new Date();
+        return dateFormat.format(date);
     }
     
-    private HashMap<String, String> fcmErrorCode() {
-         HashMap<String, String> code = new HashMap<String, String>();
-         code.put("UNSPECIFIED_ERROR", "이 오류에 대한 추가 정보가 없습니다.");
-         code.put("INVALID_ARGUMENT", "(HTTP 오류 코드 = 400) 요청 매개 변수가 유효하지 않습니다. google.rpc.BadRequest 유형의 확장자가 리턴되어 유효하지 않은 필드를 지정합니다.");
-         code.put("UNREGISTERED", " (HTTP 오류 코드 = 404) FCM에서 앱 인스턴스가 등록 해제되었습니다. 이것은 일반적으로 사용 된 토큰이 더 이상 유효하지 않으며 새로운 토큰을 사용해야 함을 의미합니다.");
-         code.put("SENDER_ID_MISMATCH", "(HTTP 오류 코드 = 403) 인증 된 발신자 ID가 등록 토큰의 발신자 ID와 다릅니다.");
-         code.put("QUOTA_EXCEEDED", "(HTTP 오류 코드 = 429) 메시지 대상에 대한 전송 제한이 초과되었습니다. 초과 한 할당량을 지정하기 위해 google.rpc.QuotaFailure 유형의 확장이 반환됩니다..");
-         code.put("UNAVAILABLE", "  (HTTP 오류 코드 = 503) 서버가 과부하되었습니다.");
-         code.put("INTERNAL", "(HTTP 오류 코드 = 500) 알 수없는 내부 오류가 발생했습니다.");
-         code.put("THIRD_PARTY_AUTH_ERROR", "(HTTP 오류 코드 = 401) APN 인증서 또는 웹 푸시 인증 키가 잘못되었거나 없습니다.");
-         code.put("FATAL", "알수없는 오류");
-         code.put("FileNotFound", "FileNotFound");
-         code.put("IOException", "IOException");
-         return code;
+    public String getNextYm() {
+        DateFormat dateFormat = new SimpleDateFormat("yyyyMM");
+        Calendar cal = Calendar.getInstance();
+        cal.add (cal.MONTH, + 1); //다음달
+        
+        return dateFormat.format(cal.getTime());
     }
     
     public void apnsSend() {

+ 104 - 2
src/main/java/com/lemon/lifecenter/scheduler/controller/PushController.java

@@ -1,18 +1,27 @@
 package com.lemon.lifecenter.scheduler.controller;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.lemon.lifecenter.scheduler.common.PushUtils;
 import com.lemon.lifecenter.scheduler.dto.DeviceInfoDTO;
+import com.lemon.lifecenter.scheduler.dto.PushResultDTO;
+import com.lemon.lifecenter.scheduler.dto.ScheduleDTO;
 import com.lemon.lifecenter.scheduler.service.PushService;
 
 @RestController
@@ -23,9 +32,102 @@ public class PushController {
     @Autowired
     private PushService service;
     
+    @Autowired
+    private PushUtils pushUtils;
+    
     @RequestMapping(value = "/selectSendPushList", method = RequestMethod.POST)
+    @Transactional(propagation=Propagation.REQUIRED)
     public void selectSendPushList() {
+        int count = service.selectSendPushCount();
+        if (count == 0) {
+        } else {
+            ArrayList<ScheduleDTO> list = (ArrayList<ScheduleDTO>) service.selectSendPushList();
+            for (int i = 0; i < list.size(); i++) {
+                int pushIdx = list.get(i).getPushIdx();
+                String sendType = list.get(i).getSendType();
+                String sendState = list.get(i).getSendState();
+                String targetType = list.get(i).getTargetType();
+                String centerCode = list.get(i).getCenterCode();
+                String pushTitle = list.get(i).getPushTitle();
+                String pushContent = list.get(i).getPushContent();
+                String sendDate = list.get(i).getSendDate();
+                String sendTime = list.get(i).getSendTime();
+                String startDate = "";
+                
+                // sendType : D(즉시), R(발송중), E(매일 발송)
+                // sendState : W(대기), I(발송중), C(완료)
+                //A(전체), N(건강정보 미엽락자), M(본인관리환자), P(환자개별선택)
+                if (sendType.equals("D") && sendState.equals("W") && targetType.equals("P")) {
+                    startDate = sendDate+ " " + sendTime;
+                    list.get(i).setStartDate(startDate);
+                    int idx = service.insertPushLog(list.get(i));
+                    if (idx == 0) {
+                    } else {
+                        service.updatePushSchedule(list.get(i));
+                        List<DeviceInfoDTO> pushTargetList = service.selectTargetPatient(pushIdx);
+                        for (int j = 0; j <pushTargetList.size(); j++) {
+                            String token = pushTargetList.get(j).getDeviceToken();
+                            int patientIdx = pushTargetList.get(j).getPatientIdx();
+                            
+                            PushResultDTO pushResultDto = new PushResultDTO();
+                            pushResultDto.setYm(pushUtils.getNowYm());
+                            pushResultDto.setPushIdx(pushIdx);
+                            pushResultDto.setPatientIdx(patientIdx);
+                            pushResultDto.setDeviceToken(token);
+                            pushResultDto.setState("W"); // 결과 대기
+                            service.insertPushResult(pushResultDto);
+                            
+                            HashMap<String, String> response = new HashMap<String, String>();
+                            if (!token.equals("")) {
+                                response = pushUtils.sendFcm(token, pushTitle, pushContent);
+                            } else {
+                                response.put("NOT_FOUND", "Requested entity was not found.");
+                            }
+                            
+                            for (String key : response.keySet()) {
+                                if (key.equals("success")) {
+                                    pushResultDto.setSuccessYn("Y");
+                                } else {
+                                    pushResultDto.setSuccessYn("N");
+                                    pushResultDto.setFailCode(key);
+                                    pushResultDto.setNote(response.get(key));
+                                }
+                            }
+                            
+                            pushResultDto.setState("C"); // 발송 완료
+                            service.updatePushResult(pushResultDto);
+                        }
+                        
+                        service.updatePushLog(list.get(i));
+                    }
+                }
+            }
+            
+        }
+
+    }
+    
+    @RequestMapping(value = "/createResultTable", method = RequestMethod.POST)
+    public void createResultTable() {
+        String ym = pushUtils.getNowYm();
+        
+        int tableCount = 0;
+        tableCount = service.resultTableCount(ym);
+        
+        if (tableCount == 0) {
+            service.createResultTable(ym);
+        }
+
+        Calendar cal = Calendar.getInstance();
+        cal.add (cal.MONTH, + 1); //다음달
+        
+        ym = pushUtils.getNextYm();
+        
+        tableCount = service.resultTableCount(ym);
         
+        if (tableCount == 0) {
+            service.createResultTable(ym);
+        }
     }
 
 }

+ 76 - 0
src/main/java/com/lemon/lifecenter/scheduler/dto/PushResultDTO.java

@@ -0,0 +1,76 @@
+package com.lemon.lifecenter.scheduler.dto;
+
+public class PushResultDTO {
+    private String ym          = "";
+    private int pushIdx        = 0;
+    private int patientIdx     = 0;
+    private String deviceToken = "";
+    private String state       = "";
+    private String successYn   = "";
+    private String failCode    = "";
+    private String note        = "";
+    private String createDate  = "";
+    private String updateDate  = "";
+    
+    public String getYm() {
+        return ym;
+    }
+    public void setYm(String ym) {
+        this.ym = ym;
+    }
+    public int getPushIdx() {
+        return pushIdx;
+    }
+    public void setPushIdx(int pushIdx) {
+        this.pushIdx = pushIdx;
+    }
+    
+    public int getPatientIdx() {
+        return patientIdx;
+    }
+    public void setPatientIdx(int patientIdx) {
+        this.patientIdx = patientIdx;
+    }
+    public String getDeviceToken() {
+        return deviceToken;
+    }
+    public void setDeviceToken(String deviceToken) {
+        this.deviceToken = deviceToken;
+    }
+    public String getState() {
+        return state;
+    }
+    public void setState(String state) {
+        this.state = state;
+    }
+    public String getSuccessYn() {
+        return successYn;
+    }
+    public void setSuccessYn(String successYn) {
+        this.successYn = successYn;
+    }
+    public String getFailCode() {
+        return failCode;
+    }
+    public void setFailCode(String failCode) {
+        this.failCode = failCode;
+    }
+    public String getNote() {
+        return note;
+    }
+    public void setNote(String note) {
+        this.note = note;
+    }
+    public String getCreateDate() {
+        return createDate;
+    }
+    public void setCreateDate(String createDate) {
+        this.createDate = createDate;
+    }
+    public String getUpdateDate() {
+        return updateDate;
+    }
+    public void setUpdateDate(String updateDate) {
+        this.updateDate = updateDate;
+    }
+}

+ 20 - 0
src/main/java/com/lemon/lifecenter/scheduler/dto/PushTargetTempDTO.java

@@ -0,0 +1,20 @@
+package com.lemon.lifecenter.scheduler.dto;
+
+public class PushTargetTempDTO {
+    private int pushIdx = 0;
+    private int patientIdx = 0;
+    
+    public int getPushIdx() {
+        return pushIdx;
+    }
+    public void setPushIdx(int pushIdx) {
+        this.pushIdx = pushIdx;
+    }
+    public int getPatientIdx() {
+        return patientIdx;
+    }
+    public void setPatientIdx(int patientIdx) {
+        this.patientIdx = patientIdx;
+    }
+    
+}

+ 98 - 0
src/main/java/com/lemon/lifecenter/scheduler/dto/ScheduleDTO.java

@@ -0,0 +1,98 @@
+package com.lemon.lifecenter.scheduler.dto;
+
+public class ScheduleDTO {
+    private int idx            = 0;
+    private int pushIdx        = 0;
+    private String sendType    = "";
+    private String sendState   = "";
+    private String targetType  = "";
+    private String centerCode  = "";
+    private String senderIp    = "";
+    private String sender      = "";
+    private String pushTitle   = "";
+    private String pushContent = "";
+    private String sendDate    = "";
+    private String sendTime    = "";
+    private String startDate   = "";
+
+    
+    public int getIdx() {
+        return idx;
+    }
+    public void setIdx(int idx) {
+        this.idx = idx;
+    }
+    public int getPushIdx() {
+        return pushIdx;
+    }
+    public void setPushIdx(int pushIdx) {
+        this.pushIdx = pushIdx;
+    }
+    public String getSendType() {
+        return sendType;
+    }
+    public void setSendType(String sendType) {
+        this.sendType = sendType;
+    }
+    public String getSendState() {
+        return sendState;
+    }
+    public void setSendState(String sendState) {
+        this.sendState = sendState;
+    }
+    public String getTargetType() {
+        return targetType;
+    }
+    public void setTargetType(String targetType) {
+        this.targetType = targetType;
+    }
+    public String getCenterCode() {
+        return centerCode;
+    }
+    public void setCenterCode(String centerCode) {
+        this.centerCode = centerCode;
+    }
+    public String getSenderIp() {
+        return senderIp;
+    }
+    public void setSenderIp(String senderIp) {
+        this.senderIp = senderIp;
+    }
+    public String getSender() {
+        return sender;
+    }
+    public void setSender(String sender) {
+        this.sender = sender;
+    }
+    public String getPushTitle() {
+        return pushTitle;
+    }
+    public void setPushTitle(String pushTitle) {
+        this.pushTitle = pushTitle;
+    }
+    public String getPushContent() {
+        return pushContent;
+    }
+    public void setPushContent(String pushContent) {
+        this.pushContent = pushContent;
+    }
+    public String getSendDate() {
+        return sendDate;
+    }
+    public void setSendDate(String sendDate) {
+        this.sendDate = sendDate;
+    }
+    public String getSendTime() {
+        return sendTime;
+    }
+    public void setSendTime(String sendTime) {
+        this.sendTime = sendTime;
+    }
+    public String getStartDate() {
+        return startDate;
+    }
+    public void setStartDate(String startDate) {
+        this.startDate = startDate;
+    }
+    
+}

+ 15 - 4
src/main/java/com/lemon/lifecenter/scheduler/mapper/PushMapper.java

@@ -1,15 +1,26 @@
 package com.lemon.lifecenter.scheduler.mapper;
 
+import java.util.List;
+
 import org.apache.ibatis.annotations.Mapper;
 import org.springframework.stereotype.Repository;
 
 import com.lemon.lifecenter.scheduler.dto.DeviceInfoDTO;
+import com.lemon.lifecenter.scheduler.dto.PushResultDTO;
+import com.lemon.lifecenter.scheduler.dto.PushTargetTempDTO;
+import com.lemon.lifecenter.scheduler.dto.ScheduleDTO;
 
 @Repository
 @Mapper
 public interface PushMapper {
-    public int selectDeviceInfoCount(DeviceInfoDTO dto);
-    public void insertDeviceInfo(DeviceInfoDTO dto);
-    public int updatedeviceInfo(DeviceInfoDTO dto);
-    public int deleteDeviceInfo(int patientIdx);
+    public int resultTableCount(String ym);
+    public int createResultTable(String ym);
+    public int selectSendPushCount();
+    public List<ScheduleDTO> selectSendPushList();
+    public int updatePushSchedule(ScheduleDTO dto);
+    public int updatePushLog(ScheduleDTO dto);
+    public int insertPushLog(ScheduleDTO dto);
+    public List<DeviceInfoDTO> selectTargetPatient(int pushIdx);
+    public int insertPushResult(PushResultDTO dto);
+    public int updatePushResult(PushResultDTO dto);
 }

+ 37 - 8
src/main/java/com/lemon/lifecenter/scheduler/service/PushService.java

@@ -1,9 +1,14 @@
 package com.lemon.lifecenter.scheduler.service;
 
+import java.util.List;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import com.lemon.lifecenter.scheduler.dto.DeviceInfoDTO;
+import com.lemon.lifecenter.scheduler.dto.PushResultDTO;
+import com.lemon.lifecenter.scheduler.dto.PushTargetTempDTO;
+import com.lemon.lifecenter.scheduler.dto.ScheduleDTO;
 import com.lemon.lifecenter.scheduler.mapper.PushMapper;
 
 @Service
@@ -11,19 +16,43 @@ public class PushService {
     @Autowired
     private PushMapper mapper;
     
-    public int selectDeviceInfoCount(DeviceInfoDTO dto) {
-        return mapper.selectDeviceInfoCount(dto);
+    public int resultTableCount(String ym) {
+        return mapper.resultTableCount(ym);
+    }
+    
+    public int createResultTable(String ym) {
+        return mapper.createResultTable(ym);
     }
     
-    public void insertDeviceInfo(DeviceInfoDTO dto) {
-        mapper.insertDeviceInfo(dto);
+    public int selectSendPushCount() {
+        return mapper.selectSendPushCount();
     }
     
-    public int updatedeviceInfo(DeviceInfoDTO dto) {
-        return mapper.updatedeviceInfo(dto);
+    public List<ScheduleDTO> selectSendPushList() {
+        return mapper.selectSendPushList();
     }
     
-    public int deleteDeviceInfo(int patientIdx) {
-        return mapper.deleteDeviceInfo(patientIdx);
+    public int updatePushSchedule(ScheduleDTO dto) {
+        return mapper.updatePushSchedule(dto);
+    }
+    public int updatePushLog(ScheduleDTO dto) {
+        return mapper.updatePushLog(dto);
     }
+    
+    public int insertPushLog(ScheduleDTO dto) {
+        return mapper.insertPushLog(dto);
+    }
+    
+    public List<DeviceInfoDTO> selectTargetPatient(int pushIdx) {
+        return mapper.selectTargetPatient(pushIdx);
+    }
+    
+    public int insertPushResult(PushResultDTO dto) {
+        return mapper.insertPushResult(dto);
+    }
+    
+    public int updatePushResult(PushResultDTO dto) {
+        return mapper.updatePushResult(dto);
+    }
+    
 }

+ 3 - 3
src/main/resources/application.properties

@@ -1,6 +1,6 @@
 spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
-spring.datasource.url=jdbc:log4jdbc:cubrid:61.97.184.187:30000:LIFE_CENTER:::?charset=UTF-8
-#spring.datasource.url=jdbc:log4jdbc:cubrid:localhost:30000:LIFE_CENTER:::?charset=UTF-8
+#spring.datasource.url=jdbc:log4jdbc:cubrid:61.97.184.187:30000:LIFE_CENTER:::?charset=UTF-8
+spring.datasource.url=jdbc:log4jdbc:cubrid:localhost:30000:LIFE_CENTER:::?charset=UTF-8
 
 spring.datasource.username=dba
 spring.datasource.password=#zo240s!
@@ -11,5 +11,5 @@ mybatis.mapper-locations=mybatis/mapper/**/*.xml
 
 #logging.level.com.lemon.lifecenter.mapper=DEBUG
 
-logging.level.root=debug
+logging.level.root=info
 spring.profiles.active=local

+ 11 - 27
src/main/resources/logback-spring.xml

@@ -29,11 +29,8 @@
     </appender>
     <!-- File Appender -->
     <appender name="FILE_SAVE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>DEBUG</level>
-            <onMatch>ACCEPT</onMatch>
-            <onMismatch>DENY</onMismatch>
-        </filter>
+        <!-- 커스텀 로그 필터 설정 -->
+        <filter class="com.lemon.lifecenter.scheduler.common.LifeCenterLogbackFilter"/>
         <!-- 파일경로 설정 -->
         <file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
         <!-- 출력패턴 설정-->
@@ -46,10 +43,10 @@
             <fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
             <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                 <!-- 파일당 최고 용량 kb, mb, gb -->
-                <maxFileSize>10MB</maxFileSize>
+                <maxFileSize>50MB</maxFileSize>
             </timeBasedFileNamingAndTriggeringPolicy>
             <!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거-->
-             <maxHistory>30</maxHistory>
+             <maxHistory>15</maxHistory>
             <!--<MinIndex>1</MinIndex> <MaxIndex>10</MaxIndex>-->
         </rollingPolicy>
     </appender>
@@ -70,16 +67,16 @@
             <fileNamePattern>${LOG_PATH}/${ERR_LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
             <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
             <!-- 파일당 최고 용량 kb, mb, gb -->
-            <maxFileSize>10MB</maxFileSize>
+            <maxFileSize>50MB</maxFileSize>
             </timeBasedFileNamingAndTriggeringPolicy>
             <!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거-->
-            <maxHistory>60</maxHistory>
+            <maxHistory>15</maxHistory>
          </rollingPolicy>
     </appender>
     <!-- jdbc query log -->
     <appender name="jdbc.log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-           <level>DEBUG</level>
+           <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
@@ -93,10 +90,10 @@
            <fileNamePattern>${LOG_PATH}/${SQL_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <!-- 파일당 최고 용량 kb, mb, gb -->
-           <maxFileSize>10MB</maxFileSize>
+           <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거 -->
-           <maxHistory>60</maxHistory>
+           <maxHistory>15</maxHistory>
         </rollingPolicy>
     </appender>
     <!-- root레벨 설정 -->
@@ -106,28 +103,15 @@
         <appender-ref ref="Error" />
     </root>
 
-   <!-- mapper log -->
-   <!-- <logger name="com.lemon.lifecenter.TestImpl">
-       <appender-ref ref="jdbc.log" />
-   </logger> -->
-   <!-- <logger name="com.dbs.consentServer.mapper.HospitalMapper">
-       <appender-ref ref="jdbc.log" />
-   </logger>
-   <logger name="com.dbs.consentServer.mapper.HospitalMapper">
-       <appender-ref ref="jdbc.log" />
-   </logger> -->
    <!-- 특정패키지 로깅레벨 설정 -->
     <logger name="org.apache.ibatis" level="DEBUG" additivity="true">
-        <appender-ref ref="CONSOLE" />
-        <appender-ref ref="FILE_SAVE" />
-        <appender-ref ref="Error" />
     </logger>
     <!-- log4jdbc 옵션 설정 -->
     <logger name="jdbc" level="OFF"/>
     <!-- 커넥션 open close 이벤트를 로그로 남긴다. -->
     <logger name="jdbc.connection" level="OFF"/>
     <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. -->
-    <logger name="jdbc.sqlonly" level="DEBUG">
+    <logger name="jdbc.sqlonly" level="INFO">
          <appender-ref ref="jdbc.log" />
     </logger>
    <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. -->
@@ -140,7 +124,7 @@
     <logger name="jdbc.resultset" level="ERROR" additivity="true" />
       
     <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. -->
-    <logger name="jdbc.resultsettable" level="DEBUG" additivity="true" />
+    <logger name="jdbc.resultsettable" level="INFO" additivity="true" />
     <logger name="com.zaxxer.hikari.HikariConfig" level="OFF" additivity="false" />
     <logger name="com.zaxxer.hikari" level="OFF" />
    

+ 117 - 22
src/main/resources/mybatis/mapper/push/push.xml

@@ -3,43 +3,138 @@
 
 <mapper namespace="com.lemon.lifecenter.scheduler.mapper.PushMapper">
 
-    <select id="selectDeviceInfoCount" parameterType="DeviceInfoDTO" resultType="int">
+    <select id="resultTableCount" parameterType="String" resultType="int">
+        <![CDATA[
+            SELECT COUNT(*) FROM db_attribute WHERE class_name = 'push_result_${ym}';
+        ]]>
+    </select>
+
+    <update id="createResultTable" parameterType="String">
+        <![CDATA[
+            CREATE TABLE `push_result_${ym}` (
+                `idx` INTEGER AUTO_INCREMENT(1,1) NOT NULL COMMENT 'IDX',
+                `push_idx` INTEGER NOT NULL,
+                `patient_idx` INTEGER NOT NULL,
+                `device_key` CHARACTER VARYING (255) COLLATE utf8_ko_cs COMMENT '발송 당시 device_key',
+                `state` CHARACTER(1) COLLATE utf8_ko_cs COMMENT '발송결과 ( W:결과 대기, C:발송완료 )',
+                `success_yn` CHARACTER(1) COLLATE utf8_ko_cs COMMENT 'Y:성공, N:실패',
+                `fail_code` CHARACTER VARYING (255) COLLATE utf8_ko_cs COMMENT '실패 코드',
+                `note` CHARACTER VARYING (100) COLLATE utf8_ko_cs COMMENT '비고',
+                `create_date` DATETIME COMMENT '발송 시작 시간',
+                `update_date` DATETIME COMMENT '발송 완료 시간',
+                CONSTRAINT `pk` PRIMARY KEY(`idx`)
+            )
+            REUSE_OID,
+            COLLATE utf8_ko_cs
+            COMMENT = '푸시 발송 결과'
+        ]]>
+    </update>
+    
+    <select id="selectSendPushCount" resultType="int">
         <![CDATA[
             SELECT COUNT(*) AS CNT
-              FROM PUSH_DEVICE_INFO
+              FROM PUSH_SCHEDULE
+             WHERE SEND_STATE = 'W'
+               AND SEND_TYPE != 'E'
+        ]]>
+    </select>
+
+    <select id="selectSendPushList" resultType="ScheduleDTO">
+        <![CDATA[
+            SELECT PUSH_IDX     AS pushIdx,
+                   SEND_TYPE    AS sendType,
+                   SEND_STATE   AS sendState,
+                   TARGET_TYPE  AS targetType,
+                   CENTER_CODE  AS centerCode,
+                   SENDER_IP    AS senderIp,
+                   SENDER       AS sender,
+                   PUSH_TITLE   AS pushTitle,
+                   PUSH_CONTENT AS pushContent,
+                   SEND_DATE    AS sendDate,
+                   SEND_TIME    AS sendTime
+              FROM PUSH_SCHEDULE
              WHERE 1 = 1
-               AND PATIENT_IDX = #{patientIdx}
+               AND SEND_STATE = 'W'
+               AND SEND_TYPE != 'E'
         ]]>
     </select>
-    <insert id="insertDeviceInfo" parameterType="DeviceInfoDTO">
-        <selectKey keyProperty="queryCount" resultType="int" order="AFTER">
+    
+    <update id="updatePushSchedule" parameterType="ScheduleDTO">
+        <![CDATA[
+            UPDATE PUSH_SCHEDULE
+               SET SEND_STATE = 'I'
+             WHERE PUSH_IDX = #{pushIdx}
+        ]]>
+    </update>
+    
+    <insert id="insertPushLog" parameterType="ScheduleDTO">
+        <selectKey keyProperty="idx" resultType="int" order="AFTER">
             <![CDATA[
-                SELECT COUNT(*) queryCount FROM PUSH_DEVICE_INFO WHERE PATIENT_IDX = #{patientIdx}
+                SELECT CURRENT_VAL AS idx FROM db_serial WHERE NAME = 'push_log_ai_idx';
             ]]>
         </selectKey>
         <![CDATA[
-            INSERT INTO PUSH_DEVICE_INFO
-                        (PATIENT_IDX,   DEVICE_TYPE,   DEVICE_KEY,     MAC_ADDRESS,   CREATE_DATE)
-                 VALUES (#{patientIdx}, #{deviceType}, #{deviceToken}, #{macAddress}, NOW())
+            INSERT INTO PUSH_LOG
+                        (push_idx,    send_type,   send_state,    target_type,     center_code,
+                         sender_ip,   sender,      push_title,    push_content,    create_date,
+                         start_date)
+                 VALUES (#{pushIdx},  #{sendType}, #{sendState},  #{targetType},   #{centerCode},
+                         #{senderIp}, #{sender},   #{pushTitle}, #{pushContent}, NOW(),
+                         #{startDate})
         ]]>
     </insert>
-    <update id="updatedeviceInfo" parameterType="DeviceInfoDTO">
+    
+    <select id="selectTargetPatient" parameterType="int" resultType="DeviceInfoDTO">
+        <![CDATA[
+            SELECT PTT.PATIENT_IDX AS patientIdx,
+                   PDI.DEVICE_TYPE AS deviceType,
+                   PDI.DEVICE_KEY  AS deviceToken
+              FROM PUSH_TARGET_TEMP PTT
+              LEFT JOIN PUSH_DEVICE_INFO PDI
+                ON PTT.PATIENT_IDX = PDI.PATIENT_IDX
+             WHERE 1 = 1
+        ]]>
+    </select>
+    
+    <update id="updatePushLog" parameterType="ScheduleDTO">
         <![CDATA[
-            UPDATE PUSH_DEVICE_INFO
-               SET UPDATE_DATE  = NOW(),
-                   DEVICE_TYPE  = #{deviceType},
-                   DEVICE_KEY   = #{deviceToken},
-                   MAC_ADDRESS  = #{macAddress}
-             WHERE PATIENT_IDX  = #{patientIdx}
+            UPDATE PUSH_LOG
+               SET END_DATE = NOW(),
+                   SEND_STATE = 'C'
+             WHERE PUSH_IDX = #{pushIdx}
         ]]>
+        <if test='sendType != null and sendType != ""'>
+            <if test='sendType != "E"'>
+                <![CDATA[
+                    DELETE FROM PUSH_SCHEDULE WHERE PUSH_IDX = #{pushIdx}
+                    DELETE FROM PUSH_TARGET_TEMP WHERE PUSH_IDX = #{pushIdx}
+                ]]>
+            </if>
+        </if>
     </update>
     
-    <delete id="deleteDeviceInfo" parameterType="int">
+    <insert id="insertPushResult" parameterType="PushResultDTO">
+        <![CDATA[
+            INSERT INTO PUSH_RESULT_${ym}
+                        (PUSH_IDX,   PATIENT_IDX,   DEVICE_KEY,   STATE,    CREATE_DATE)
+                 VALUES (#{pushIdx}, #{patientIdx}, #{deviceToken}, #{state}, NOW())
+        ]]>
+    </insert>
+    
+    <update id="updatePushResult" parameterType="PushResultDTO">
+        <![CDATA[
+            UPDATE PUSH_RESULT_${ym}
+               SET SUCCESS_YN = #{successYn},
+                   STATE = #{state}
+        ]]>
+        <if test='failCode != null and failCode != ""'>
+            <![CDATA[
+                , FAIL_CODE = #{failCode}
+                , NOTE = #{note}
+            ]]>
+        </if>
         <![CDATA[
-            UPDATE PUSH_DEVICE_INFO
-               SET UPDATE_DATE = NOW(),
-                   DEVICE_KEY = ''
-             WHERE PATIENT_IDX = #{patientIdx}
+            WHERE PUSH_IDX = #{pushIdx}
         ]]>
-    </delete>
+    </update>
 </mapper>