|
@@ -68,9 +68,8 @@ public class KakaoEventHandler {
|
|
|
private WallpadMsgSender wallpadMsgSender;
|
|
|
|
|
|
@Async("eventExecutor")
|
|
|
- public CompletableFuture<Map<String, Object>> getDeviceStatus(DonghoInfo donghoInfo, Map<String, Object> params) throws InterruptedException{
|
|
|
+ public CompletableFuture<Map<String, Object>> sendEventAsync(DonghoInfo donghoInfo, Map<String, Object> params) throws InterruptedException{
|
|
|
Map<String, Object> retMap = new HashMap<String, Object>();
|
|
|
-
|
|
|
try {
|
|
|
// 인증토큰 검증
|
|
|
String tokenStartTime = donghoInfo.getKakaoTokenCreateTime();
|
|
@@ -78,19 +77,218 @@ public class KakaoEventHandler {
|
|
|
String currentTime = CommonUtil.getStrTypeCurTime();
|
|
|
|
|
|
int result = CommonUtil.compareStringTypeTime(currentTime, tokenExpiresTime);
|
|
|
-
|
|
|
+
|
|
|
+ boolean connFlag = true;
|
|
|
// 현재 시간이 토큰 만료시간보다 크다면 토큰이 만료 됐다는 뜻.
|
|
|
// 카카오 이벤트 서버에서 토큰을 갱신 받은 뒤 이벤트를 전송해야 한다.
|
|
|
- if(result < 1) {
|
|
|
-// sendKakaoTokenRefresh(dong, ho, params);
|
|
|
+ if(result < 1)
|
|
|
+ connFlag = sendKakaoTokenRefresh(donghoInfo);
|
|
|
+
|
|
|
+ if(!connFlag) {
|
|
|
+ retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
|
|
|
+ retMap.put("message", "ID-["+donghoInfo.getId() + "]-Fail to Token Refresh");
|
|
|
+ return CompletableFuture.completedFuture(retMap);
|
|
|
}
|
|
|
|
|
|
- retMap.put("result", "SUCCESS");
|
|
|
+ logger.info("["+donghoInfo.getKakaoAccessToken()+"] - 유효한 토큰");
|
|
|
+
|
|
|
+ // 이벤트 전송.
|
|
|
+ Map<String, Object> sendResult = sendStatusResult(donghoInfo, params);
|
|
|
+
|
|
|
+ int code = (int) sendResult.get("result");
|
|
|
+
|
|
|
+ switch(code) {
|
|
|
+ case KAKAO_RESULT.FAIL_INTERNAL:
|
|
|
+ break;
|
|
|
+ case KAKAO_RESULT.FAIL_INVALID_TOKEN: // 유효하지 않은 토큰, 연동 해제한 계정 토큰
|
|
|
+ logger.info("["+donghoInfo.getKakaoAccessToken()+"] - 유효하지 않은 토큰..삭제요청");
|
|
|
+ DonghoInfoRepository repo = (DonghoInfoRepository)BeanUtils.getBean("donghoInfoRepository");
|
|
|
+ donghoInfo.setDeleteFlag("Y");
|
|
|
+ repo.save(donghoInfo);
|
|
|
+
|
|
|
+ retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
|
|
|
+ retMap.put("message", "ID-["+donghoInfo.getId() + "]-FAIL_INVALID_TOKEN");
|
|
|
+ break;
|
|
|
+ case KAKAO_RESULT.FAIL_EXPIREDTOKEN: // 만료된 토큰, 토큰 재발급 뒤 재시도.
|
|
|
+ // 재시도 할때는 따로 결과를 받지 않을려고.. 성공할때까지 계속 시도하는것도 비효율적.
|
|
|
+ logger.info("["+donghoInfo.getKakaoAccessToken()+"]-인증토큰 만료 토큰 갱신 요청");
|
|
|
+ connFlag = sendKakaoTokenRefresh(donghoInfo);
|
|
|
+
|
|
|
+ if(!connFlag) {
|
|
|
+ retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
|
|
|
+ retMap.put("message", "ID-["+donghoInfo.getId() + "]-Fail to Token Refresh Retry");
|
|
|
+ return CompletableFuture.completedFuture(retMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("["+donghoInfo.getKakaoAccessToken()+"]-이벤트 재전송 시도");
|
|
|
+ sendResult = sendStatusResult(donghoInfo, params);
|
|
|
+
|
|
|
+ code = (int) sendResult.get("result");
|
|
|
+
|
|
|
+ retMap.put("result", code);
|
|
|
+
|
|
|
+ if(code != KAKAO_RESULT.SUCCESS) {
|
|
|
+ retMap.put("message", "ID-["+donghoInfo.getId() + "]-이벤트 재전송 실패 - [" + sendResult.get("message") + "]");
|
|
|
+ }else {
|
|
|
+ retMap.put("message", "ID-["+donghoInfo.getId() + "]-이벤트 재전송 성공");
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ case KAKAO_RESULT.SUCCESS:
|
|
|
+ retMap.put("result", KAKAO_RESULT.SUCCESS);
|
|
|
+ retMap.put("message", "ID-["+donghoInfo.getId() + "]-이벤트 전송 성공!");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}catch(Exception e) {
|
|
|
- retMap.put("result", "FAIL");
|
|
|
- retMap.put("error", e.getMessage());
|
|
|
+ retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
|
|
|
+
|
|
|
+ retMap.put("message", "ID-["+donghoInfo.getId() + "]-" + e.getMessage());
|
|
|
}
|
|
|
|
|
|
return CompletableFuture.completedFuture(retMap);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 상태 변경 이벤트 발생시 이벤트 결과를 카카오 이벤트 서버에 전송한다.
|
|
|
+ * 전송시 토큰이 만료 되면 [sendKakaoTokenRefresh] method를 호출하여 토큰을 갱신한뒤 다시 재시도 한다.
|
|
|
+ * @param dong
|
|
|
+ * @param ho
|
|
|
+ * @param params
|
|
|
+ * @param reqType
|
|
|
+ */
|
|
|
+ public Map<String, Object> sendStatusResult(DonghoInfo donghoInfo, Map<String, Object> params) {
|
|
|
+ Map<String, Object> retMap = new HashMap<String, Object>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ if(params == null) {
|
|
|
+ retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
|
|
|
+ retMap.put("message", "params is null");
|
|
|
+ logger.error("[sendStatusResult] - params is null");
|
|
|
+ return retMap;
|
|
|
+ }
|
|
|
+ logger.info("[sendStatusResult] - START - " + donghoInfo.toString());
|
|
|
+
|
|
|
+ String authorization = SERVERINFO.KAKAO_EVENT_CLIENT_ID+":"+SERVERINFO.KAKAO_EVENT_CLIENT_SECRET;
|
|
|
+ String encoding = Base64.getEncoder().encodeToString(authorization.getBytes());
|
|
|
+
|
|
|
+ CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
|
|
|
+ HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
|
|
|
+
|
|
|
+ requestFactory.setHttpClient(httpClient);
|
|
|
+ requestFactory.setConnectTimeout(3000);
|
|
|
+
|
|
|
+ RestTemplate restTemplate = new RestTemplate(requestFactory);
|
|
|
+
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+
|
|
|
+ headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
+ headers.set("Authorization", "Basic " + encoding);
|
|
|
+ // 제어기기 별로 상태 이벤트 구분하여 처리하도록 해야 한다
|
|
|
+ HttpEntity<Object> entity = new HttpEntity<Object>(params, headers);
|
|
|
+
|
|
|
+ String url = SERVERINFO.SendDevEventURL + ":" + SERVERINFO.SendDevEventPort + "/events";
|
|
|
+
|
|
|
+ logger.info("SendStatusResult URL : " + url);
|
|
|
+ logger.info("SendStatusResult header : " + headers.toString());
|
|
|
+ logger.info("SendStatusResult return value : " + params.toString());
|
|
|
+
|
|
|
+ String answer = restTemplate.postForObject(url, entity, String.class);
|
|
|
+
|
|
|
+ logger.info("SendStatusResult answer :" + answer);
|
|
|
+
|
|
|
+ // 결과에 error가 있으면 error에 맞게 대응해줘야 한다.
|
|
|
+ Map<String, Object> resultMap = CommonUtil.jsonToMap(answer);
|
|
|
+
|
|
|
+ if(resultMap.containsKey(KEY_INFO.HTTP_KEY_ERROR)) {
|
|
|
+ //error 결과가 -201 이면 인증토큰이 만료 됐다는 뜻
|
|
|
+ Map<String, Object> errMap = (Map<String, Object>)resultMap.get(KEY_INFO.HTTP_KEY_ERROR);
|
|
|
+ int errorCode = Integer.parseInt((String)errMap.get(KEY_INFO.ERROR_KEY_CODE));
|
|
|
+ String message = (String)errMap.get(KEY_INFO.ERROR_KEY_MESSAGE);
|
|
|
+
|
|
|
+ logger.info("[KAKAO - ERROR] - [ CODE ] - " + errorCode + " || [message] - " + message );
|
|
|
+
|
|
|
+ retMap.put("result", errorCode);
|
|
|
+ retMap.put("message", message);
|
|
|
+ }else {
|
|
|
+ logger.info("EVENT SEND SUCCESS -- " + params.toString());
|
|
|
+
|
|
|
+ retMap.put("result", KAKAO_RESULT.SUCCESS);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.info("SendStatusResult Exception e :" + e.toString());
|
|
|
+ retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
|
|
|
+ retMap.put("message", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ return retMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 이벤트 전송시 토큰이 만료되면 해당 메서드가 호출된다.
|
|
|
+ * 이벤트 토큰 만료시 카카오 이벤트 토큰 서버에 토큰 갱신 요청을 보낸다.
|
|
|
+ * 토큰이 갱신 되면 이벤트 전송을 시도한다.
|
|
|
+ * @param dong
|
|
|
+ * @param ho
|
|
|
+ * @param params
|
|
|
+ */
|
|
|
+ public boolean sendKakaoTokenRefresh(DonghoInfo donghoInfo){
|
|
|
+ DonghoInfoRepository repo = (DonghoInfoRepository)BeanUtils.getBean("donghoInfoRepository");
|
|
|
+
|
|
|
+ String refreshToken = donghoInfo.getKakaoRefreshToken();
|
|
|
+
|
|
|
+ String authorization = SERVERINFO.KAKAO_EVENT_CLIENT_ID+":"+SERVERINFO.KAKAO_EVENT_CLIENT_SECRET;
|
|
|
+ String encoding = Base64.getEncoder().encodeToString(authorization.getBytes());
|
|
|
+
|
|
|
+
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
+ headers.add("Authorization", "Basic " + encoding);
|
|
|
+
|
|
|
+ MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
|
|
|
+ parameters.add("grant_type", "refresh_token");
|
|
|
+ parameters.add("refresh_token", refreshToken);
|
|
|
+
|
|
|
+ HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(parameters, headers);
|
|
|
+
|
|
|
+ String url = SERVERINFO.SendDevEventURL + ":" + SERVERINFO.SendDevEventPort + "/events/token";
|
|
|
+
|
|
|
+ logger.info("[TOKEN REFRESH REQUEST] URL : " + url);
|
|
|
+ logger.info("[TOKEN REFRESH REQUEST] header : " + headers.toString());
|
|
|
+ logger.info("[TOKEN REFRESH REQUEST] return value : " + entity.toString());
|
|
|
+ URI uri = URI.create(url);
|
|
|
+
|
|
|
+ CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
|
|
|
+ HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
|
|
|
+
|
|
|
+ requestFactory.setHttpClient(httpClient);
|
|
|
+ requestFactory.setConnectTimeout(3000);
|
|
|
+
|
|
|
+ RestTemplate restTemplate = new RestTemplate(requestFactory);
|
|
|
+
|
|
|
+ String answer = restTemplate.postForObject(url, entity, String.class);
|
|
|
+ logger.debug("[TOKEN REFRESH REQUEST] = " + answer);
|
|
|
+
|
|
|
+ Map<String, Object> retMap = CommonUtil.jsonToMap(answer);
|
|
|
+
|
|
|
+ if(retMap.containsKey(KEY_INFO.HTTP_KEY_ACCESS_TOKEN) && retMap.containsKey(KEY_INFO.HTTP_KEY_REFRESH_TOKEN) && retMap.containsKey(KEY_INFO.HTTP_KEY_EXPIRES_IN)) {
|
|
|
+ donghoInfo.setKakaoAccessToken((String)retMap.get(KEY_INFO.HTTP_KEY_ACCESS_TOKEN));
|
|
|
+ donghoInfo.setKakaoRefreshToken((String)retMap.get(KEY_INFO.HTTP_KEY_REFRESH_TOKEN));
|
|
|
+ donghoInfo.setKakaoExpiresTime(Integer.toString((int)retMap.get(KEY_INFO.HTTP_KEY_EXPIRES_IN)));
|
|
|
+
|
|
|
+ donghoInfo.setKakaoTokenCreateTime(CommonUtil.getStrTypeCurTime());
|
|
|
+ donghoInfo.setKakaoTokenExpireTime(CommonUtil.getStrTypeCurTimeAfterSec(Integer.parseInt(donghoInfo.getKakaoExpiresTime())));
|
|
|
+
|
|
|
+ repo.save(donghoInfo);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }else {
|
|
|
+ logger.error("****************************************************");
|
|
|
+ logger.error("토클 리프레시 실패");
|
|
|
+ logger.error("****************************************************");
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|