package com.ktds.act.admin.hndlrmngt.service;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ktds.act.admin.common.config.hndlr.HndlrBlackList;
import com.ktds.act.admin.common.handler.AdminRuntimeException;
import com.ktds.act.admin.common.handler.model.TestDto;
import com.ktds.act.admin.common.response.Pagination;
import com.ktds.act.admin.common.response.Response;
import com.ktds.act.admin.common.response.StatusEnum;
import com.ktds.act.admin.common.util.UserAuthUtil;
import com.ktds.act.admin.domain.dto.AdmHndlrDto;
import com.ktds.act.admin.domain.dto.AdmTmpltDto;
import com.ktds.act.admin.domain.dto.AdmUtilDto;
import com.ktds.act.admin.domain.entity.AdmApiDply;
import com.ktds.act.admin.domain.entity.AdmHndlr;
import com.ktds.act.admin.domain.enums.DplyType;
import com.ktds.act.admin.domain.repository.AdmApiDplyTrRepository;
import com.ktds.act.admin.domain.repository.AdmHndlrDplyTrRepository;
import com.ktds.act.admin.domain.repository.AdmHndlrRepository;
import com.ktds.act.admin.domain.repository.AdmTmpltRepository;
import com.ktds.act.admin.domain.repository.AdmUtilRepository;
import com.ktds.act.admin.hndlrmngt.db.model.ApiIdAndSysIdDto;
import com.ktds.act.admin.hndlrmngt.db.model.ApiListDto;
import com.ktds.act.admin.hndlrmngt.db.model.DuplicatedCheckDto;
import com.ktds.act.admin.hndlrmngt.db.model.HndlrMngtQueryParameter;
import com.ktds.act.admin.hndlrmngt.db.model.Transaction;
import com.ktds.act.admin.hndlrmngt.db.model.UrlDto;
import com.ktds.act.apigw.common.header.Header;
import com.ktds.act.apigw.common.util.CompilerUtils;
import com.ktds.act.apigw.filter.handler.RouteHandler;
import com.ktds.act.apigw.filter.model.ComnonDto;
import com.ktds.act.apigw.filter.model.RequestDto;
import com.ktds.act.apigw.filter.model.ResponseDto;
import com.ktds.act.apigw.filter.model.StoreDto;
import com.ktds.act.apigw.filter.model.TransactionDto;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Service
@RequiredArgsConstructor
@Slf4j
public class HndlrMngtService {
@Value("${nexus.url}")
private String domainUrl;
@Value("${nexus.basic}")
private String basicKey;
private final AdmApiDplyTrRepository admApiDplyTrRepository;
private final AdmHndlrRepository admHndlrRepository;
private final AdmHndlrDplyTrRepository admHndlrDplyRepository;
private final AdmTmpltRepository admTmpltRepository;
private final AdmUtilRepository admUtilRepository;
private final ApplicationContext applicationContext;
private final UserAuthUtil userAuthUtil;
// 핸들러 임시저장 및 등록
public Response<Object> createHndlr(AdmHndlrDto admHndlrDto, HttpServletRequest request) {
String cstmClassAdr = "";
if (!admHndlrDto.getCstmClassSrc().isEmpty() || admHndlrDto.getCstmClassSrc() != "") {
String[] reg = admHndlrDto.getCstmClassSrc().split(";");
String[] adr = reg[0].split("package ");
cstmClassAdr = adr[1] + "." + admHndlrDto.getCstmClassNm();
}
admHndlrDto.setCstmClassAdr(cstmClassAdr);
admHndlrDto.setTbReqDply("N");
admHndlrDto.setProdReqDply("N");
AdmHndlr entity = admHndlrRepository.findByHndlrId(admHndlrDto.getHndlrId()).orElseGet(AdmHndlr::new);
if (entity.getId() == null) {
if (admHndlrRepository.existsByHndlrId(entity.getHndlrId())) {
throw new AdminRuntimeException(StatusEnum.DUPLICATED_HNDLR_ID);
}
entity = AdmHndlr.to(admHndlrDto);
} else {
entity = admHndlrRepository.findById(entity.getId()).get();
}
// db에 값이 있을 때만 update
if (entity.getId() != null) {
BeanUtils.copyProperties(admHndlrDto, entity, "id", "hndlrId", "cretId", "cretDt");
}
entity.setProdDplyUrl("");
entity.setTbDplyUrl("");
var result = admHndlrRepository.save(entity);
return new Response<>().responseOk(result);
}
// 핸들러 전체조회 및 검색
public Response<List<AdmHndlrDto>> getHndlrList(Pageable pageable,
HndlrMngtQueryParameter hndlrMngtQueryParameter, HttpServletRequest request) {
if (hndlrMngtQueryParameter.getHndlrId() != null || hndlrMngtQueryParameter.getTrtSect() != null
|| hndlrMngtQueryParameter.getTbReqDply() != null || hndlrMngtQueryParameter.getProdReqDply() != null) {
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() == null
&& hndlrMngtQueryParameter.getTbReqDply() == null && hndlrMngtQueryParameter.getProdReqDply() == null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(),
pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() == null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() == null && hndlrMngtQueryParameter.getProdReqDply() == null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByTrtSectIgnoreCaseContainingOrderByUpdDtDesc(
hndlrMngtQueryParameter.getTrtSect(),
pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() == null && hndlrMngtQueryParameter.getTrtSect() == null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() == null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByTbReqDplyOrderByUpdDtDesc(hndlrMngtQueryParameter.getTbReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() == null && hndlrMngtQueryParameter.getTrtSect() == null
&& hndlrMngtQueryParameter.getTbReqDply() == null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByProdReqDplyOrderByUpdDtDesc(hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() == null && hndlrMngtQueryParameter.getProdReqDply() == null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingAndTrtSectOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(),
hndlrMngtQueryParameter.getTrtSect(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() == null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() == null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingAndTbReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(),
hndlrMngtQueryParameter.getTbReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() == null
&& hndlrMngtQueryParameter.getTbReqDply() == null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingAndProdReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(),
hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() == null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() == null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByTrtSectIgnoreCaseContainingAndTbReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getTrtSect(),
hndlrMngtQueryParameter.getTbReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() == null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() == null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByTrtSectIgnoreCaseContainingAndProdReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getTrtSect(),
hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() == null && hndlrMngtQueryParameter.getTrtSect() == null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByTbReqDplyIgnoreCaseContainingAndProdReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getTbReqDply(),
hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
//3개조건
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() == null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingAndTrtSectAndTbReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(), hndlrMngtQueryParameter.getTrtSect(),
hndlrMngtQueryParameter.getTbReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() == null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingAndTrtSectAndProdReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(), hndlrMngtQueryParameter.getTrtSect(),
hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() == null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingAndTbReqDplyAndProdReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(), hndlrMngtQueryParameter.getTbReqDply(),
hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() == null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByTrtSectIgnoreCaseContainingAndTbReqDplyAndProdReqDplyOrderByUpdDtDesc(
hndlrMngtQueryParameter.getTrtSect(), hndlrMngtQueryParameter.getTbReqDply(),
hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if (hndlrMngtQueryParameter.getHndlrId() != null && hndlrMngtQueryParameter.getTrtSect() != null
&& hndlrMngtQueryParameter.getTbReqDply() != null && hndlrMngtQueryParameter.getProdReqDply() != null) {
var pageAdmHndlr = (Page) admHndlrRepository
.findByHndlrIdIgnoreCaseContainingAndTbReqDplyAndProdReqDplyAndTrtSectOrderByUpdDtDesc(
hndlrMngtQueryParameter.getHndlrId(), hndlrMngtQueryParameter.getTrtSect(), hndlrMngtQueryParameter.getTbReqDply(),
hndlrMngtQueryParameter.getProdReqDply(), pageable);
return new Response<List<AdmHndlrDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
}
var result = (Page) admHndlrRepository.findByOrderByUpdDtDescHndlrIdAsc(pageable);
return new Response<List<AdmHndlrDto>>().responseOk(result.getContent(),
new Pagination().complete(result, pageable));
}
// 핸들러 상세조회
public Response<AdmHndlrDto> getHndlrById(String hndlrId, HttpServletRequest request) {
return admHndlrRepository.findByHndlrId(hndlrId).map(entity -> {
var responseDto = AdmHndlrDto.of(entity);
return new Response<AdmHndlrDto>().responseOk(responseDto);
}).orElseThrow(() -> new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND));
}
// 핸들러 수정
@Transactional
public Response<Object> updateHndlr(AdmHndlrDto admHndlrDto, HttpServletRequest request) {
return admHndlrRepository.findByHndlrId(admHndlrDto.getHndlrId()).map(entity -> {
String hndlrId = entity.getHndlrId();
String trtSect = entity.getTrtSect();
String cstmClassAdr = "";
if (!admHndlrDto.getCstmClassSrc().isEmpty() || admHndlrDto.getCstmClassSrc() != "") {
String[] reg = admHndlrDto.getCstmClassSrc().split(";");
String[] adr = reg[0].split("package ");
cstmClassAdr = adr[1] + "." + admHndlrDto.getCstmClassNm();
}
admHndlrDto.setCstmClassAdr(cstmClassAdr);
admHndlrDto.setTbReqDply("N");
admHndlrDto.setProdReqDply("N");
BeanUtils.copyProperties(admHndlrDto, entity, "id", "hndlrId", "cretId", "cretDt", "url", "encodedUrl");
admHndlrRepository.save(entity);
return new Response<>().responseOk(StatusEnum.SUCCESS);
}).orElseThrow(() -> new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND));
}
// 핸들러 삭제
@Transactional
public Response<Object> deleteHndlr(String hndlrId, HttpServletRequest request) {
return admHndlrRepository.findByHndlrId(hndlrId).map(entity -> {
String objectId = entity.getId();
String trtSect = entity.getTrtSect();
Boolean apiBool = false;
if (trtSect.equals("REQ")) {
apiBool = admApiDplyTrRepository.existsByReqHndlrAndDplyTypeNotIn(hndlrId, DplyType.DEL);
if (apiBool == true) {
throw new AdminRuntimeException(StatusEnum.USED_HNDLR);
}
} else if (trtSect.equals("RES")) {
apiBool = admApiDplyTrRepository.existsByResHndlrAndDplyTypeNotIn(hndlrId, DplyType.DEL);
if (apiBool == true) {
throw new AdminRuntimeException(StatusEnum.USED_HNDLR);
}
} else if (trtSect.equals("ERR")) {
apiBool = admApiDplyTrRepository.existsByErrHndlrAndDplyTypeNotIn(hndlrId, DplyType.DEL);
if (apiBool == true) {
throw new AdminRuntimeException(StatusEnum.USED_HNDLR);
}
}
admHndlrRepository.deleteById(objectId);
return new Response<>().responseOk(StatusEnum.SUCCESS);
}).orElseThrow(() -> new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND));
}
// 핸들러 ID 중복체크
public Response<DuplicatedCheckDto> hndlrCheckById(String hndlrId) {
boolean isExisted = false;
isExisted = admHndlrRepository.existsByHndlrId(hndlrId);
var responseDto = new DuplicatedCheckDto().setIsPkDuplicated(isExisted);
return new Response<DuplicatedCheckDto>().responseOk(responseDto);
}
// 핸들러 리스트 조회
// public Response<Map<String, List<AdmHndlrListDto>>> getHndlrIdList(String trtSect, HttpServletRequest request) {
// var autId = userAuthUtil.getAutId(request);
// if (userAuthUtil.isAdmr(request)) {
// var hndlrList = this.admHndlrRepository.findByTrtSectOrderByOrderAsc(trtSect).stream()
// .filter(s -> s.getSttus().equals("CMPLT")).map(entity -> {
// var hndlrDto = AdmHndlrDto.of(entity);
// var admHndlrListDto = AdmHndlrListDto.builder()
// .admHndlrDto(hndlrDto)
// .type(hndlrDto.getType())
// .build();
// return admHndlrListDto;
// }).collect(Collectors.groupingBy(AdmHndlrListDto::getType,
// Collectors.mapping(AdmHndlrListDto::getAdmHndlrDto, Collectors.toList())));
// return new Response().responseOk(hndlrList);
// } else { // 관리자 아닐때
// var hndlrList = this.admHndlrRepository.findByAutIdAndTrtSectOrderByOrderAsc(autId, trtSect).stream()
// .filter(s -> s.getSttus().equals("CMPLT")).map(entity -> {
// var hndlrDto = AdmHndlrDto.of(entity);
// var admHndlrListDto = AdmHndlrListDto.builder()
// .admHndlrDto(hndlrDto)
// .type(hndlrDto.getType())
// .build();
// return admHndlrListDto;
// }).collect(Collectors.groupingBy(AdmHndlrListDto::getType,
// Collectors.mapping(AdmHndlrListDto::getAdmHndlrDto, Collectors.toList())));
// return new Response().responseOk(hndlrList);
// }
// }
// 템플릿 소스 오류체크 컴파일
public Response<Object> errorCheck(AdmHndlrDto admHndlrDto) {
try {
registerTemplateCode(admHndlrDto);
} catch (AdminRuntimeException e) {
log.error("invalid source");
return new Response<>().serverError(StatusEnum.INVALID_SOURCE);
} catch (Exception e) {
DuplicatedCheckBean(admHndlrDto);
log.error("errorCheck error : {}", e.getMessage());
return new Response<>().serverError(9000, e.getMessage());
}
DuplicatedCheckBean(admHndlrDto);
return new Response<>().responseOk();
}
private void registerTemplateCode(AdmHndlrDto admHndlrDto) throws ClassNotFoundException, IOException {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext
.getBeanFactory();
String compileSource = admHndlrDto.getCstmClassSrc();
HndlrBlackList.getSourceBlackList().stream().forEach(e -> {
if (admHndlrDto.getCstmClassSrc().contains(e)) {
throw new AdminRuntimeException(StatusEnum.INVALID_SOURCE);
}
});
String cstmClassAdr = "";
if (!admHndlrDto.getCstmClassSrc().isEmpty() || admHndlrDto.getCstmClassSrc() != "") {
String[] reg = admHndlrDto.getCstmClassSrc().split(";");
String[] adr = reg[0].split("package ");
cstmClassAdr = adr[1] + "." + admHndlrDto.getCstmClassNm();
}
admHndlrDto.setCstmClassAdr(cstmClassAdr);
System.out.println(cstmClassAdr);
// compileSource = compileSource.replaceFirst("com.ktds.act.apigw.filter.handler.custom;",
// "com.ktds.act.admin.common.handler;");
Class<?> cls = CompilerUtils.compileSource(cstmClassAdr, compileSource);
defaultListableBeanFactory.registerBeanDefinition(admHndlrDto.getHndlrId(),
BeanDefinitionBuilder.genericBeanDefinition(cls).getRawBeanDefinition());
}
private void registerTemplateCode(TestDto testDto) throws ClassNotFoundException, IOException {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext
.getBeanFactory();
String compileSource = testDto.getCstmClassSrc();
HndlrBlackList.getSourceBlackList().stream().forEach(e -> {
if (testDto.getCstmClassSrc().contains(e)) {
throw new AdminRuntimeException(StatusEnum.INVALID_SOURCE);
}
});
compileSource = compileSource.replaceFirst("com.ktds.act.apigw.filter.handler.custom;",
"com.ktds.act.admin.common.handler;");
Class<?> cls = CompilerUtils.compileSource("com.ktds.act.admin.common.handler." + testDto.getCstmClassNm(),
compileSource);
defaultListableBeanFactory.registerBeanDefinition(testDto.getHndlrId(),
BeanDefinitionBuilder.genericBeanDefinition(cls).getRawBeanDefinition());
}
// 템플릿 소스 테스트
public Response<Object> templateTest(TestDto testDto, HttpServletRequest request)
throws UnsupportedEncodingException {
TransactionDto transactionDto = TransactionDto.builder()
.comn(ComnonDto.builder()
.build())
.req(RequestDto.builder()
.header(new HttpHeaders())
.build())
.res(ResponseDto.builder()
.header(new HttpHeaders())
.build())
.store(StoreDto.builder()
.build())
.build();
try {
registerTemplateCode(testDto);
} catch (AdminRuntimeException e) {
log.error("invalid source");
return new Response<>().serverError(StatusEnum.INVALID_SOURCE);
} catch (Exception e) {
DuplicatedCheckBean(testDto);
log.error("templateTest register bean error : {}", e.getMessage());
return new Response<>().serverError(StatusEnum.CODE_COMPILE_ERROR);
}
// 헤더 설정
setRequestHeader(testDto, transactionDto);
// req, res, err 핸들러 바디 설정
setTransaction(testDto, request, transactionDto);
boolean timeOut = false;
Transaction transaction = new Transaction();
try {
RouteHandler routeHandler = (RouteHandler) applicationContext.getBean(testDto.getHndlrId());
Loop loop = new Loop(transactionDto, routeHandler);
long start = System.currentTimeMillis();
long end;
loop.start();
while(true){
end = System.currentTimeMillis();
if(end-start>=10000){
timeOut = true;
break;
}
if(loop.isAlive() == false){
break;
}
}
if(timeOut){
loop.stop();
return new Response<>().serverError(StatusEnum.TIME_OUT);
}
boolean testResult = loop.getTestResult();
if (!testResult) {
return new Response<>().serverError(StatusEnum.CODE_TEST_FAIL);
}
setTestResult(transaction, testDto, transactionDto);
} catch (Exception e) {
DuplicatedCheckBean(testDto);
log.error("templateTest error : {}", e.getMessage());
return new Response<>().serverError(9001, e.getMessage());
}
DuplicatedCheckBean(testDto);
return new Response<>().responseOk(transaction);
}
// 중복된 빈 제거
private void DuplicatedCheckBean(TestDto testDto) {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext
.getBeanFactory();
if (defaultListableBeanFactory.containsBeanDefinition(testDto.getHndlrId())) {
defaultListableBeanFactory.removeBeanDefinition(testDto.getHndlrId());
}
}
// 중복된 빈 제거
private void DuplicatedCheckBean(AdmHndlrDto admHndlrDto) {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext
.getBeanFactory();
if (defaultListableBeanFactory.containsBeanDefinition(admHndlrDto.getHndlrId())) {
defaultListableBeanFactory.removeBeanDefinition(admHndlrDto.getHndlrId());
}
}
private MultiValueMap<String, String> ListToMultiValueMap(TestDto testDto) {
MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
if (testDto.getQueryParam() != null && !testDto.getQueryParam().isEmpty()) {
for (Map<String, String> data : testDto.getQueryParam()) {
for (String key : data.keySet()) {
multiValueMap.set(key, data.get(key));
}
}
}
return multiValueMap;
}
private Map<String, String> MultiValueMapToList(TestDto testDto, TransactionDto transactionDto) {
Map<String, String> header = new HashMap<>();
if (testDto.getTrtSect().equals("REQ")) {
header = transactionDto.getReq().getHeader().toSingleValueMap();
} else {
header = transactionDto.getRes().getHeader().toSingleValueMap();
}
return header;
}
private void setRequestHeader(TestDto testDto, TransactionDto transactionDto) {
HttpHeaders header = new HttpHeaders();
if (testDto.getHeader() != null && !testDto.getHeader().isEmpty()) {
for (Map<String, String> data : testDto.getHeader()) {
for (String key : data.keySet()) {
header.add(key, (String) data.get(key));
if (testDto.getTrtSect().equals("REQ")) {
transactionDto.setReqHeader(header);
} else {
transactionDto.setResHeader(header);
}
}
}
}
}
// 템플릿 리스트 조회
public Response<List<AdmTmpltDto>> getTmpltList(String trtSect) {
var responseDto = (List) this.admTmpltRepository.findAllByTrtSect(trtSect).stream().map(entity -> {
return AdmTmpltDto.of(entity);
}).collect(Collectors.toList());
return new Response().responseOk(responseDto);
}
// 템플릿 클래스 중복 조회
public Response<DuplicatedCheckDto> checkClassNm(String classNm) {
var isDuplicated = admHndlrRepository.existsByCstmClassNm(classNm);
var responseDto = new DuplicatedCheckDto().setIsPkDuplicated(isDuplicated);
return new Response<DuplicatedCheckDto>().responseOk(responseDto);
}
// 유틸 리스트 조회
public Response<List<AdmUtilDto>> getUtilList() {
var responseDto = (List) this.admUtilRepository.findAll().stream().map(entity -> {
return AdmUtilDto.of(entity);
}).collect(Collectors.toList());
return new Response().responseOk(responseDto);
}
private String getHeaderF(HttpHeaders header, String key) {
if (header.containsKey(key)) {
return header.getFirst(key);
}
return "";
}
private void setTransaction(TestDto testDto, HttpServletRequest request, TransactionDto transactionDto)
throws UnsupportedEncodingException {
// testDto -> transactionDto
String txId = getHeaderF(transactionDto.getReq().getHeader(), Header.TX_ID);
String clientIp = getHeaderF(transactionDto.getReq().getHeader(), Header.CLIENT_IP);
String reqMthd = request.getMethod();
String uriIn = request.getRequestURI();
byte[] reqBodyByte = testDto.getBody().getBytes("euc-kr");
var multiValueMap = ListToMultiValueMap(testDto);
MultiValueMapToList(testDto, transactionDto);
if (testDto.getTrtSect().equals("REQ")) {
transactionDto.setComn(ComnonDto.builder().txId(txId).build());
transactionDto.setReq(RequestDto.builder()
.stTm(System.currentTimeMillis())
.svcIp(clientIp)
.meth(reqMthd)
.in(uriIn)
.out("/out")
.header(transactionDto.getReq().getHeader())
.body(reqBodyByte)
.queryParams(multiValueMap)
.svcId("backendSvcId")
.build());
transactionDto.setStore(StoreDto.builder().build());
} else {
transactionDto.setComn(ComnonDto.builder()
.txId(txId)
.build());
transactionDto.setRes(ResponseDto.builder()
.stTm(System.currentTimeMillis())
.header(transactionDto.getRes().getHeader())
.body(reqBodyByte)
.build());
transactionDto.setStore(StoreDto.builder()
.build());
}
}
private void setTestResult(Transaction transaction, TestDto testDto, TransactionDto transactionDto) {
if (testDto.getTrtSect().equals("REQ")) {
transaction.setBody(new String(transactionDto.getReq().getBody()));
} else {
transaction.setBody(new String(transactionDto.getRes().getBody()));
}
var header = MultiValueMapToList(testDto, transactionDto);
transaction.setHeader(header);
transaction.setTransactionDto(transactionDto);
}
// 핸들러를 사용하는 API 조회
public Response<ApiListDto> getApiListByHndlrId(String trtSect, String hndlrId) {
ApiListDto resList = new ApiListDto();
var isExistedHndlr = admHndlrRepository.existsByHndlrId(hndlrId);
if (!isExistedHndlr) {
throw new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND);
}
List<ApiIdAndSysIdDto> apiList = new ArrayList<>();
List<AdmApiDply> admApiList = new ArrayList<>();
if ("REQ".equals(trtSect)) {
admApiList = admApiDplyTrRepository.findByReqHndlr(hndlrId).get();
} else if ("RES".equals(trtSect)) {
admApiList = admApiDplyTrRepository.findByResHndlr(hndlrId).get();
} else if ("ERR".equals(trtSect)) {
admApiList = admApiDplyTrRepository.findByErrHndlr(hndlrId).get();
}
admApiList.stream().forEach(e -> {
ApiIdAndSysIdDto apiIdAndSysIdDto = new ApiIdAndSysIdDto();
apiIdAndSysIdDto.setApiId(e.getApiId())
.setSysId(e.getSysId());
apiList.add(apiIdAndSysIdDto);
});
resList.setApiList(apiList);
return new Response<ApiListDto>().responseOk(resList);
}
//핸들러 관리 업로드 API
public Response<UrlDto> reqHndlrDply(AdmHndlrDto admHndlrDto, HttpServletRequest request) throws MalformedURLException, IOException, NoSuchAlgorithmException{
ObjectMapper mapper = new ObjectMapper();
if(domainUrl.substring(0,5).equals("https")){
System.out.println("상용 환경입니다");
//TB 또는 상용 환경
if(admHndlrDto.getTbProd().equals("tb")){
admHndlrDto.setTbReqDply("Y");
admHndlrDto.setProdReqDply("N");
String json = mapper.writeValueAsString(admHndlrDto);
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));;
String upUrl = domainUrl + admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) +".json";
// System.out.println("upUrl:" + upUrl);
// System.out.println();
//인코딩 작업
String rawUrl = admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) +".json";
String encodedUrl = Base64.getEncoder().encodeToString(rawUrl.getBytes());
// System.out.println("rawUrl:" + rawUrl);
// System.out.println(encodedUrl);
//조회후 업데이트
AdmHndlr entity = new AdmHndlr();
Optional<AdmHndlr> optEntity = admHndlrRepository.findByHndlrId(admHndlrDto.getHndlrId());
if(optEntity.isPresent()){
entity = optEntity.get();
entity.setTbReqDply("Y"); //TB만 Y해줌
entity.setProdReqDply(optEntity.get().getProdReqDply()); //Prod는 있는 그대로 해줌
entity.setTbDplyUrl(encodedUrl);
entity.setProdDplyUrl(optEntity.get().getProdDplyUrl());
admHndlrRepository.save(entity);
}else{
throw new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND);
}
HttpsURLConnection con = null;
con = (HttpsURLConnection) new URL(upUrl).openConnection();
con.setConnectTimeout(3000);
con.setRequestMethod("PUT");
con.setDoInput(true);
con.setDoOutput(true);
con.addRequestProperty("Authorization", "Basic "+basicKey);
OutputStream out_stream = con.getOutputStream();
out_stream.write(json.getBytes("UTF-8"));
out_stream.flush();
out_stream.close();
UrlDto urlDto = new UrlDto();
urlDto.setTbDplyUrl(encodedUrl).setProdDplyUrl(optEntity.get().getProdDplyUrl());
System.out.println(con.getResponseCode());
return new Response<UrlDto>().responseOk(urlDto);
}else if(admHndlrDto.getTbProd().equals("prd")){
System.out.println("TB환경입니다");
admHndlrDto.setTbReqDply("N");
admHndlrDto.setProdReqDply("Y");
String json = mapper.writeValueAsString(admHndlrDto);
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));;
String upUrl = domainUrl + admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) +".json";
// System.out.println("upUrl:" + upUrl);
// System.out.println();
//인코딩 작업
String rawUrl = admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) +".json";
String encodedUrl = Base64.getEncoder().encodeToString(rawUrl.getBytes());
// System.out.println("rawUrl:" + rawUrl);
// System.out.println(encodedUrl);
//조회후 업데이트
AdmHndlr entity = new AdmHndlr();
Optional<AdmHndlr> optEntity = admHndlrRepository.findByHndlrId(admHndlrDto.getHndlrId());
if(optEntity.isPresent()){
entity = optEntity.get();
entity.setTbReqDply(optEntity.get().getTbReqDply()); //TB만 Y해줌
entity.setProdReqDply("Y"); //Prod는 있는 그대로 해줌
entity.setTbDplyUrl(optEntity.get().getTbDplyUrl());
entity.setProdDplyUrl(encodedUrl);
admHndlrRepository.save(entity);
}else{
throw new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND);
}
HttpsURLConnection con = null;
con = (HttpsURLConnection) new URL(upUrl).openConnection();
con.setConnectTimeout(3000);
con.setRequestMethod("PUT");
con.setDoInput(true);
con.setDoOutput(true);
con.addRequestProperty("Authorization", "Basic "+basicKey);
OutputStream out_stream = con.getOutputStream();
out_stream.write(json.getBytes("UTF-8"));
out_stream.flush();
out_stream.close();
UrlDto urlDto = new UrlDto();
urlDto.setTbDplyUrl(optEntity.get().getTbDplyUrl()).setProdDplyUrl(encodedUrl);
System.out.println(con.getResponseCode());
return new Response<UrlDto>().responseOk(urlDto);
}else{
throw new AdminRuntimeException(StatusEnum.BASEURL_BAD_REQUEST);
}
}else{
//dev 환경
//TB 또는 상용 환경
if(admHndlrDto.getTbProd().equals("tb")){
System.out.println("Dev - TB 환경입니다");
admHndlrDto.setTbReqDply("Y");
admHndlrDto.setProdReqDply("N");
String json = mapper.writeValueAsString(admHndlrDto);
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));;
String upUrl = domainUrl + admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) + ".json";
// System.out.println("upUrl:" + upUrl);
// System.out.println();
//인코딩 작업
String rawUrl = admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) +".json";
String encodedUrl = Base64.getEncoder().encodeToString(rawUrl.getBytes());
// System.out.println("rawUrl:" + rawUrl);
// System.out.println(encodedUrl);
//조회후 업데이트
AdmHndlr entity = new AdmHndlr();
Optional<AdmHndlr> optEntity = admHndlrRepository.findByHndlrId(admHndlrDto.getHndlrId());
if(optEntity.isPresent()){
entity = optEntity.get();
entity.setTbReqDply("Y"); //TB만 Y해줌
entity.setProdReqDply(optEntity.get().getProdReqDply()); //Prod는 있는 그대로 해줌
entity.setTbDplyUrl(encodedUrl);
entity.setProdDplyUrl(optEntity.get().getProdDplyUrl());
admHndlrRepository.save(entity);
}else{
throw new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND);
}
HttpURLConnection con = null;
con = (HttpURLConnection) new URL(upUrl).openConnection();
con.setConnectTimeout(3000);
con.setRequestMethod("PUT");
con.setDoInput(true);
con.setDoOutput(true);
con.addRequestProperty("Authorization", "Basic "+basicKey);
OutputStream out_stream = con.getOutputStream();
out_stream.write(json.getBytes("UTF-8"));
out_stream.flush();
out_stream.close();
UrlDto urlDto = new UrlDto();
urlDto.setTbDplyUrl(encodedUrl).setProdDplyUrl(optEntity.get().getProdDplyUrl());
System.out.println(con.getResponseCode());
return new Response<UrlDto>().responseOk(urlDto);
}else if(admHndlrDto.getTbProd().equals("prd")){
System.out.println("Dev - PROD 환경입니다");
admHndlrDto.setTbReqDply("N");
admHndlrDto.setProdReqDply("Y");
String json = mapper.writeValueAsString(admHndlrDto);
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
String upUrl = domainUrl + admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) +".json";
// System.out.println("upUrl:" + upUrl);
// System.out.println();
//인코딩 작업
String rawUrl = admHndlrDto.getTbProd() + "/" + admHndlrDto.getHndlrId() + "/" + admHndlrDto.getHndlrId() + "_" + now + "_" +checkSum(json) +".json";
String encodedUrl = Base64.getEncoder().encodeToString(rawUrl.getBytes());
// System.out.println("rawUrl:" + rawUrl);
// System.out.println(encodedUrl);
//조회후 업데이트
AdmHndlr entity = new AdmHndlr();
Optional<AdmHndlr> optEntity = admHndlrRepository.findByHndlrId(admHndlrDto.getHndlrId());
if(optEntity.isPresent()){
entity = optEntity.get();
entity.setTbReqDply(optEntity.get().getTbReqDply()); //TB만 Y해줌
entity.setProdReqDply("Y"); //Prod는 있는 그대로 해줌
entity.setTbDplyUrl(optEntity.get().getTbDplyUrl());
entity.setProdDplyUrl(encodedUrl);
admHndlrRepository.save(entity);
}else{
throw new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND);
}
HttpURLConnection con = null;
con = (HttpURLConnection) new URL(upUrl).openConnection();
con.setConnectTimeout(3000);
con.setRequestMethod("PUT");
con.setDoInput(true);
con.setDoOutput(true);
con.addRequestProperty("Authorization", "Basic "+basicKey);
OutputStream out_stream = con.getOutputStream();
out_stream.write(json.getBytes("UTF-8"));
out_stream.flush();
out_stream.close();
UrlDto urlDto = new UrlDto();
urlDto.setTbDplyUrl(optEntity.get().getTbDplyUrl()).setProdDplyUrl(encodedUrl);
System.out.println(con.getResponseCode());
return new Response<UrlDto>().responseOk(urlDto);
}else{
throw new AdminRuntimeException(StatusEnum.BASEURL_BAD_REQUEST);
}
}
}
public String checkSum(String data) throws NoSuchAlgorithmException, IOException{
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));;
MessageDigest md5 = MessageDigest.getInstance("MD5");
DigestInputStream dis = new DigestInputStream(new ByteArrayInputStream(data.getBytes("UTF-8")), md5);
while(dis.read() != -1) ;
dis.close();
String resultData;
Formatter formatter = new Formatter();
for(byte b : md5.digest()) {
formatter.format("%02X", b);
}
resultData = formatter.toString();
formatter.close();
return resultData;
}
}
class Loop extends Thread {
private TransactionDto transactionDto;
private RouteHandler routeHandler;
private boolean testResult;
public Loop(TransactionDto transactionDto, RouteHandler routeHandler){
this.transactionDto = transactionDto;
this.routeHandler = routeHandler;
}
@Override
public void run() {
testResult = routeHandler.process(transactionDto);
}
public void stopThread() {
super.interrupt();
}
public boolean getTestResult(){
return this.testResult;
}
}
핸들러 배포
package com.ktds.act.admin.hndlrdplymngt.service;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.Formatter;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ktds.act.admin.common.config.hndlr.HndlrBlackList;
import com.ktds.act.admin.common.handler.AdminRuntimeException;
import com.ktds.act.admin.common.response.Pagination;
import com.ktds.act.admin.common.response.Response;
import com.ktds.act.admin.common.response.StatusEnum;
import com.ktds.act.admin.common.util.UserAuthUtil;
import com.ktds.act.admin.domain.dto.AdmHndlrDplyDto;
import com.ktds.act.admin.domain.entity.AdmApiDply;
import com.ktds.act.admin.domain.entity.AdmHndlrDply;
import com.ktds.act.admin.domain.enums.DplyType;
import com.ktds.act.admin.domain.repository.AdmApiDplyTrRepository;
import com.ktds.act.admin.domain.repository.AdmHndlrDplyTrRepository;
import com.ktds.act.admin.hndlrdplymngt.db.HndlrDplyQueryParameter;
import com.ktds.act.admin.hndlrdplymngt.db.SrcDto;
import com.ktds.act.admin.hndlrmngt.db.model.ApiIdAndSysIdDto;
import com.ktds.act.admin.hndlrmngt.db.model.ApiListDto;
import com.ktds.act.admin.hndlrmngt.db.model.DuplicatedCheckDto;
import com.ktds.act.apigw.common.util.CompilerUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Service
@RequiredArgsConstructor
@Slf4j
public class HndlrDplyMngtService {
@Value("${nexus.url}")
private String domainUrl;
@Value("${nexus.basic}")
private String basicKey;
private final AdmHndlrDplyTrRepository admHndlrDplyTrRepository;
private final AdmApiDplyTrRepository admApiDplyTrRepository;
private final ApplicationContext applicationContext;
private final UserAuthUtil userAuthUtil;
// 핸들러 임시저장 및 등록
public Response<Object> hndlrMngt(AdmHndlrDplyDto admHndlrDplyDto, HttpServletRequest request) {
AdmHndlrDply result = new AdmHndlrDply();
if (admHndlrDplyTrRepository.existsByHndlrId(admHndlrDplyDto.getHndlrId()) == true) {
//수정하는 부분
return admHndlrDplyTrRepository.findByHndlrId(admHndlrDplyDto.getHndlrId()).map(entity -> {
String hndlrId = entity.getHndlrId();
String trtSect = entity.getTrtSect();
String cstmClassAdr = "";
if (!admHndlrDplyDto.getCstmClassSrc().isEmpty() || admHndlrDplyDto.getCstmClassSrc() != "") {
String[] reg = admHndlrDplyDto.getCstmClassSrc().split(";");
String[] adr = reg[0].split("package ");
cstmClassAdr = adr[1] + "." + admHndlrDplyDto.getCstmClassNm();
}
admHndlrDplyDto.setCstmClassAdr(cstmClassAdr);
admHndlrDplyDto.setDplyType(DplyType.DPLY);
BeanUtils.copyProperties(admHndlrDplyDto, entity, "id", "hndlrId", "cretId", "cretDt");
admHndlrDplyTrRepository.save(entity);
return new Response<>().responseOk(StatusEnum.SUCCESS);
}).orElseThrow(() -> new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND));
}else{
//등록하는 부분
String cstmClassAdr = "";
if (!admHndlrDplyDto.getCstmClassSrc().isEmpty() || admHndlrDplyDto.getCstmClassSrc() != "") {
String[] reg = admHndlrDplyDto.getCstmClassSrc().split(";");
String[] adr = reg[0].split("package ");
cstmClassAdr = adr[1] + "." + admHndlrDplyDto.getCstmClassNm();
}
admHndlrDplyDto.setCstmClassAdr(cstmClassAdr);
admHndlrDplyDto.setDplyType(DplyType.DPLY);
AdmHndlrDply entity = admHndlrDplyTrRepository.findByHndlrId(admHndlrDplyDto.getHndlrId()).orElseGet(AdmHndlrDply::new);
if (entity.getId() == null) {
if (admHndlrDplyTrRepository.existsByHndlrId(entity.getHndlrId())) {
throw new AdminRuntimeException(StatusEnum.DUPLICATED_HNDLR_ID);
}
entity = AdmHndlrDply.to(admHndlrDplyDto);
} else {
entity = admHndlrDplyTrRepository.findById(entity.getId()).get();
}
// db에 값이 있을 때만 update
if (entity.getId() != null) {
BeanUtils.copyProperties(admHndlrDplyDto, entity, "id", "hndlrId", "cretId", "cretDt");
}
result = admHndlrDplyTrRepository.save(entity);
}
return new Response<>().responseOk(result);
}
// 핸들러 전체조회 및 검색
public Response<List<AdmHndlrDplyDto>> getHndlrList(Pageable pageable,
HndlrDplyQueryParameter hndlrDplyQueryParameter, HttpServletRequest request) {
if (hndlrDplyQueryParameter.getHndlrId() != null || hndlrDplyQueryParameter.getTrtSect() != null){
if(hndlrDplyQueryParameter.getHndlrId() != null && hndlrDplyQueryParameter.getTrtSect() != null){
var pageAdmHndlr = (Page) admHndlrDplyTrRepository
.findByHndlrIdIgnoreCaseContainingAndTrtSectIgnoreCaseContainingAndDplyType(hndlrDplyQueryParameter.getHndlrId(), hndlrDplyQueryParameter.getTrtSect(),"DPLY",pageable);
return new Response<List<AdmHndlrDplyDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if(hndlrDplyQueryParameter.getHndlrId() != null){
var pageAdmHndlr = (Page) admHndlrDplyTrRepository
.findByHndlrIdIgnoreCaseContainingAndDplyType(hndlrDplyQueryParameter.getHndlrId(), "DPLY",pageable);
return new Response<List<AdmHndlrDplyDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
if(hndlrDplyQueryParameter.getTrtSect() != null){
var pageAdmHndlr = (Page) admHndlrDplyTrRepository
.findByTrtSectIgnoreCaseContainingAndDplyType(hndlrDplyQueryParameter.getTrtSect(), "DPLY",pageable);
return new Response<List<AdmHndlrDplyDto>>().responseOk(pageAdmHndlr.getContent(),
new Pagination().complete(pageAdmHndlr, pageable));
}
}
var result = (Page) admHndlrDplyTrRepository.findByDplyTypeOrderByDplyDtDescHndlrIdAsc("DPLY", pageable);
return new Response<List<AdmHndlrDplyDto>>().responseOk(result.getContent(),
new Pagination().complete(result, pageable));
}
// 핸들러 상세조회
public Response<AdmHndlrDplyDto> getHndlrById(String hndlrId, HttpServletRequest request) {
return admHndlrDplyTrRepository.findByHndlrIdAndDplyType(hndlrId, "DPLY").map(entity -> {
var responseDto = AdmHndlrDplyDto.of(entity);
return new Response<AdmHndlrDplyDto>().responseOk(responseDto);
}).orElseThrow(() -> new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND));
}
// 핸들러 ID 중복체크
public Response<DuplicatedCheckDto> hndlrCheckById(String hndlrId, HttpServletRequest request) {
boolean isExisted = false;
isExisted = admHndlrDplyTrRepository.existsByHndlrId(hndlrId);
var responseDto = new DuplicatedCheckDto().setIsPkDuplicated(isExisted);
return new Response<DuplicatedCheckDto>().responseOk(responseDto);
}
// 템플릿 소스 오류체크 컴파일
public Response<Object> errorCheck(AdmHndlrDplyDto admHndlrDplyDto) {
try {
registerTemplateCode(admHndlrDplyDto);
} catch (AdminRuntimeException e) {
log.error("invalid source");
return new Response<>().serverError(StatusEnum.INVALID_SOURCE);
} catch (Exception e) {
DuplicatedCheckBean(admHndlrDplyDto);
log.error("errorCheck error : {}", e.getMessage());
return new Response<>().serverError(9000, e.getMessage());
}
DuplicatedCheckBean(admHndlrDplyDto);
return new Response<>().responseOk();
}
private void registerTemplateCode(AdmHndlrDplyDto admHndlrDplyDto) throws ClassNotFoundException, IOException {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext
.getBeanFactory();
String compileSource = admHndlrDplyDto.getCstmClassSrc();
HndlrBlackList.getSourceBlackList().stream().forEach(e -> {
if (admHndlrDplyDto.getCstmClassSrc().contains(e)) {
throw new AdminRuntimeException(StatusEnum.INVALID_SOURCE);
}
});
String cstmClassAdr = "";
if (!admHndlrDplyDto.getCstmClassSrc().isEmpty() || admHndlrDplyDto.getCstmClassSrc() != "") {
String[] reg = admHndlrDplyDto.getCstmClassSrc().split(";");
String[] adr = reg[0].split("package ");
cstmClassAdr = adr[1] + "." + admHndlrDplyDto.getCstmClassNm();
}
admHndlrDplyDto.setCstmClassAdr(cstmClassAdr);
System.out.println(cstmClassAdr);
// compileSource = compileSource.replaceFirst("com.ktds.act.apigw.filter.handler.custom;",
// "com.ktds.act.admin.common.handler;");
Class<?> cls = CompilerUtils.compileSource(cstmClassAdr, compileSource);
defaultListableBeanFactory.registerBeanDefinition(admHndlrDplyDto.getHndlrId(),
BeanDefinitionBuilder.genericBeanDefinition(cls).getRawBeanDefinition());
}
// 중복된 빈 제거
private void DuplicatedCheckBean(AdmHndlrDplyDto admHndlrDplyDto) {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext
.getBeanFactory();
if (defaultListableBeanFactory.containsBeanDefinition(admHndlrDplyDto.getHndlrId())) {
defaultListableBeanFactory.removeBeanDefinition(admHndlrDplyDto.getHndlrId());
}
}
// 템플릿 클래스 중복 조회
public Response<DuplicatedCheckDto> checkClassNm(String classNm) {
var isDuplicated = admHndlrDplyTrRepository.existsByCstmClassNm(classNm);
var responseDto = new DuplicatedCheckDto().setIsPkDuplicated(isDuplicated);
return new Response<DuplicatedCheckDto>().responseOk(responseDto);
}
// 핸들러를 사용하는 API 조회
public Response<ApiListDto> getApiListByHndlrId(String trtSect, String hndlrId) {
ApiListDto resList = new ApiListDto();
var isExistedHndlr = admHndlrDplyTrRepository.existsByHndlrId(hndlrId);
if (!isExistedHndlr) {
throw new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND);
}
List<ApiIdAndSysIdDto> apiList = new ArrayList<>();
List<AdmApiDply> admApiList = new ArrayList<>();
if ("REQ".equals(trtSect)) {
admApiList = admApiDplyTrRepository.findByReqHndlr(hndlrId).get();
} else if ("RES".equals(trtSect)) {
admApiList = admApiDplyTrRepository.findByResHndlr(hndlrId).get();
} else if ("ERR".equals(trtSect)) {
admApiList = admApiDplyTrRepository.findByErrHndlr(hndlrId).get();
}
admApiList.stream().forEach(e -> {
ApiIdAndSysIdDto apiIdAndSysIdDto = new ApiIdAndSysIdDto();
apiIdAndSysIdDto.setApiId(e.getApiId())
.setSysId(e.getSysId());
apiList.add(apiIdAndSysIdDto);
});
resList.setApiList(apiList);
return new Response<ApiListDto>().responseOk(resList);
}
// 핸들러 삭제
@Transactional
public Response<Object> hndlrDplyDel(AdmHndlrDplyDto admHndlrDplyDto, HttpServletRequest request) {
var hndlrId = admHndlrDplyDto.getHndlrId();
return admHndlrDplyTrRepository.findByHndlrId(hndlrId).map(entity -> {
String objectId = entity.getId();
String trtSect = entity.getTrtSect();
Boolean apiBool = false;
if (trtSect.equals("REQ")) {
apiBool = admApiDplyTrRepository.existsByReqHndlrAndDplyTypeNotIn(hndlrId, DplyType.DEL);
if (apiBool == true) {
throw new AdminRuntimeException(StatusEnum.USED_HNDLR);
}
} else if (trtSect.equals("RES")) {
apiBool = admApiDplyTrRepository.existsByResHndlrAndDplyTypeNotIn(hndlrId, DplyType.DEL);
if (apiBool == true) {
throw new AdminRuntimeException(StatusEnum.USED_HNDLR);
}
} else if (trtSect.equals("ERR")) {
apiBool = admApiDplyTrRepository.existsByErrHndlrAndDplyTypeNotIn(hndlrId, DplyType.DEL);
if (apiBool == true) {
throw new AdminRuntimeException(StatusEnum.USED_HNDLR);
}
}
// hndlrDply 상태 변경
admHndlrDplyTrRepository.findByHndlrId(hndlrId).stream().forEach(hndlrDplyEntity ->{
if(DplyType.DPLY.equals(hndlrDplyEntity.getDplyType())){
hndlrDplyEntity.setDplyType(DplyType.DEL);
}
admHndlrDplyTrRepository.save(hndlrDplyEntity);
});
return new Response<>().responseOk(StatusEnum.SUCCESS);
}).orElseThrow(() -> new AdminRuntimeException(StatusEnum.DATA_NOT_FOUND));
}
//핸들러 nexus url 조회
public Response<AdmHndlrDplyDto> getUrlHndlr(String encodedUrl, HttpServletRequest request) throws MalformedURLException, IOException, ParseException, NoSuchAlgorithmException{
if(domainUrl.substring(0,5).equals("https")){
//상용 TB 환경
JSONParser jsonParser = new JSONParser();
AdmHndlrDplyDto admHndlrDplyDto = new AdmHndlrDplyDto();
//encodedUrl 해석부분(복호화)
String decodedUrl = decodingUrl(encodedUrl);
String url = decodedUrl;
HttpsURLConnection con = null;
con = (HttpsURLConnection) new URL(url).openConnection();
con.setConnectTimeout(3000);
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.addRequestProperty("Authorization", "Basic "+basicKey);
InputStream input_stream = con.getInputStream();
byte[] contentsByte = input_stream.readAllBytes();
String jsonString = new String(contentsByte);
System.out.println(jsonString);
//checkSum 확인
if(!checkOfCheckSum(jsonString, decodedUrl)){
throw new AdminRuntimeException(StatusEnum.BAD_CHECKSUM);
}
Object obj = jsonParser.parse(jsonString);
JSONObject jsonObj = (JSONObject) obj;
admHndlrDplyDto.setCstmClassSrc(jsonObj.get("cstmClassSrc").toString())
.setCstmClassAdr(jsonObj.get("cstmClassAdr").toString())
.setCstmClassNm(jsonObj.get("cstmClassNm").toString())
.setBodyRfrn(true)
.setHndlrId(jsonObj.get("hndlrId").toString())
.setType(jsonObj.get("type").toString())
.setTrtSect(jsonObj.get("trtSect").toString())
.setDesc(jsonObj.get("desc").toString());;
if(decodedUrl.contains("/tb/")){
admHndlrDplyDto.setTbDplyUrl(encodedUrl);
admHndlrDplyDto.setProdDplyUrl("");
}else{
admHndlrDplyDto.setTbDplyUrl("");
admHndlrDplyDto.setProdDplyUrl(encodedUrl);
}
input_stream.close();
//errorCheck 로직
errorCheck(admHndlrDplyDto);
System.out.println(con.getResponseCode());
return new Response<AdmHndlrDplyDto>().responseOk(admHndlrDplyDto);
}else{
//Dev 환경
JSONParser jsonParser = new JSONParser();
AdmHndlrDplyDto admHndlrDplyDto = new AdmHndlrDplyDto();
//encodedUrl 해석부분(복호화)
String decodedUrl = decodingUrl(encodedUrl);
String url = decodedUrl;
HttpURLConnection con = null;
con = (HttpURLConnection) new URL(url).openConnection();
con.setConnectTimeout(3000);
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.addRequestProperty("Authorization", "Basic "+basicKey);
InputStream input_stream = con.getInputStream();
byte[] contentsByte = input_stream.readAllBytes();
String jsonString = new String(contentsByte);
System.out.println(jsonString);
//checkSum 확인
if(!checkOfCheckSum(jsonString, decodedUrl)){
throw new AdminRuntimeException(StatusEnum.BAD_CHECKSUM);
}
Object obj = jsonParser.parse(jsonString);
JSONObject jsonObj = (JSONObject) obj;
admHndlrDplyDto.setCstmClassSrc(jsonObj.get("cstmClassSrc").toString())
.setCstmClassAdr(jsonObj.get("cstmClassAdr").toString())
.setCstmClassNm(jsonObj.get("cstmClassNm").toString())
.setBodyRfrn(true)
.setHndlrId(jsonObj.get("hndlrId").toString())
.setType(jsonObj.get("type").toString())
.setTrtSect(jsonObj.get("trtSect").toString())
.setDesc(jsonObj.get("desc").toString());
if(decodedUrl.contains("/tb/")){
admHndlrDplyDto.setTbDplyUrl(encodedUrl);
admHndlrDplyDto.setProdDplyUrl("");
}else{
admHndlrDplyDto.setTbDplyUrl("");
admHndlrDplyDto.setProdDplyUrl(encodedUrl);
}
input_stream.close();
//errorCheck 로직
errorCheck(admHndlrDplyDto);
System.out.println(con.getResponseCode());
System.out.println(con.getResponseMessage());
return new Response<AdmHndlrDplyDto>().responseOk(admHndlrDplyDto);
}
}
//get 오래된 소스 가져오기
public Response<SrcDto> getCstmClassSrcOld(String hndlrId, HttpServletRequest request){
SrcDto srcDto = new SrcDto();
boolean dplyYn = true;
Optional<AdmHndlrDply> optEntity = admHndlrDplyTrRepository.findByHndlrIdAndDplyType(hndlrId, "DPLY");
if(optEntity.isPresent()){
dplyYn = true;
srcDto.setDplyYn(dplyYn);
srcDto.setCstmClassSrcOld(optEntity.get().getCstmClassSrc());
}else{
dplyYn = false;
srcDto.setDplyYn(dplyYn);
srcDto.setCstmClassSrcOld("");
}
return new Response<SrcDto>().responseOk(srcDto);
}
//Encoding된거 해독하기
public String decodingUrl(String encodedUrl){
//byte[] decodedUrl = Base64.getDecoder().decode(encodedUrl.getBytes());
byte[] decodedUrlBytes = Base64.getDecoder().decode(encodedUrl);
String decodedUrl = new String(decodedUrlBytes);
String resutUrl = domainUrl + decodedUrl;
return resutUrl;
}
public String checkSum(String data) throws NoSuchAlgorithmException, IOException{
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));;
MessageDigest md5 = MessageDigest.getInstance("MD5");
DigestInputStream dis = new DigestInputStream(new ByteArrayInputStream(data.getBytes("UTF-8")), md5);
while(dis.read() != -1) ;
dis.close();
String resultData;
Formatter formatter = new Formatter();
for(byte b : md5.digest()) {
formatter.format("%02X", b);
}
resultData = formatter.toString();
formatter.close();
return resultData;
}
public boolean checkOfCheckSum(String data, String decodedUrl) throws NoSuchAlgorithmException, IOException{
String recieveCheck = checkSum(data);
boolean result = false;
if(decodedUrl.contains(recieveCheck)){
result = true;
}
return result;
}
}